使用 android studio 在应用程序中流式传输实时摄像头画面
Streaming live camera feed in app using android studio
我正在创建一个应用程序,我想在其中传输我的 foscam
直播。我对编码还很陌生,其中一些代码让我头疼。我找到了一些帮助,但现在遇到了障碍。该应用程序运行但仅显示黑屏。我相信我的清单和 XML 代码都是正确的。问题出在我的代码上。希望有人能帮帮我
package com.rednak.camerastream;
import android.app.Activity;
import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Base64;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends Activity
implements MediaPlayer.OnPreparedListener,
SurfaceHolder.Callback {
final static String USERNAME = "guest";
final static String PASSWORD = "Guest";
final static String RTSP_URL = "rtsp://http://rednak71.ddns.net:8090/live1.sdp";
private MediaPlayer _mediaPlayer;
private SurfaceHolder _surfaceHolder;
@
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up a full-screen black window.
requestWindowFeature(Window.FEATURE_NO_TITLE);
Window window = getWindow();
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.setBackgroundDrawableResource(android.R.color.black);
setContentView(R.layout.activity_main);
// Configure the view that renders live video.
SurfaceView surfaceView =
(SurfaceView) findViewById(R.id.surfaceView);
_surfaceHolder = surfaceView.getHolder();
_surfaceHolder.addCallback(this);
_surfaceHolder.setFixedSize(320, 240);
}
// More to come…
/*
SurfaceHolder.Callback
*/
@
Override
public void surfaceChanged(
SurfaceHolder sh, int f, int w, int h) {}
@
Override
public void surfaceCreated(SurfaceHolder sh) {
_mediaPlayer = new MediaPlayer();
_mediaPlayer.setDisplay(_surfaceHolder);
Context context = getApplicationContext();
Map headers = getRtspHeaders();
Uri source = Uri.parse(RTSP_URL);
try {
// Specify the IP camera’s URL and auth headers.
_mediaPlayer.setDataSource(context, source, headers);
// Begin the process of setting up a video stream.
_mediaPlayer.setOnPreparedListener(this);
_mediaPlayer.prepareAsync();
} catch (Exception e) {}
}
@
Override
public void surfaceDestroyed(SurfaceHolder sh) {
_mediaPlayer.release();
}
private Map getRtspHeaders() {
Map headers = new HashMap();
String basicAuthValue = getBasicAuthValue(USERNAME, PASSWORD);
headers.put("Authorization", basicAuthValue);
return headers;
}
private String getBasicAuthValue(String usr, String pwd) {
String credentials = usr + ":" + pwd;
int flags = Base64.URL_SAFE | Base64.NO_WRAP;
byte[] bytes = credentials.getBytes();
return "Basic" + Base64.encodeToString(bytes, flags);
}
/*
MediaPlayer.OnPreparedListener
*/
@
Override
public void onPrepared(MediaPlayer mp) {
_mediaPlayer.start();
}
}
确保 Android 的 MediaPlayer 确实可以打开和解码您的流。现在,如果 MediaPlayer 无法处理您的流,您将捕获任何异常并默默地忽略它:
try {
// Specify the IP camera’s URL and auth headers.
_mediaPlayer.setDataSource(context, source, headers);
// Begin the process of setting up a video stream.
_mediaPlayer.setOnPreparedListener(this);
_mediaPlayer.prepareAsync();
} catch (Exception e) {}
至少你应该记录错误:
} catch (Exception e) {
Log.e("MyApp", "Could not open data source", e);
}
尽管 MediaPlayer 服务很可能会在日志中加入其自身的错误。所以你应该做的是查看 logcat 是否有来自 "VideoDecoder" 或类似的消息。
要在 Android Studio 中查看 logcat,请打开默认位于底部的 "Android Monitor" 选项卡。如果您想查看未过滤的 logcat,请确保在 Android 监视器视图的右上角显示 "No Filters" 而不是 "Show only selected application".
我有一些链接到 Foscam 视频流的新代码,但只在它开始时抓取帧然后不流式传输。我更近了,但仍然需要帮助。我走对了吗?
package com.rednak.camstream;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.VideoView;
public class MainCamActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_cam);
VideoView vidView = (VideoView)findViewById(R.id.CamVideoView);
String vidAddress = "http://rednak71.ddns.net:8090/CGIProxy.fcgi? cmd=snapPicture2&usr=guest&pwd=guest&t=";
Uri vidUri = Uri.parse(vidAddress);
vidView.setVideoURI(vidUri);
vidView.start();
}
}
我正在创建一个应用程序,我想在其中传输我的 foscam
直播。我对编码还很陌生,其中一些代码让我头疼。我找到了一些帮助,但现在遇到了障碍。该应用程序运行但仅显示黑屏。我相信我的清单和 XML 代码都是正确的。问题出在我的代码上。希望有人能帮帮我
package com.rednak.camerastream;
import android.app.Activity;
import android.content.Context;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Base64;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends Activity
implements MediaPlayer.OnPreparedListener,
SurfaceHolder.Callback {
final static String USERNAME = "guest";
final static String PASSWORD = "Guest";
final static String RTSP_URL = "rtsp://http://rednak71.ddns.net:8090/live1.sdp";
private MediaPlayer _mediaPlayer;
private SurfaceHolder _surfaceHolder;
@
Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set up a full-screen black window.
requestWindowFeature(Window.FEATURE_NO_TITLE);
Window window = getWindow();
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.setBackgroundDrawableResource(android.R.color.black);
setContentView(R.layout.activity_main);
// Configure the view that renders live video.
SurfaceView surfaceView =
(SurfaceView) findViewById(R.id.surfaceView);
_surfaceHolder = surfaceView.getHolder();
_surfaceHolder.addCallback(this);
_surfaceHolder.setFixedSize(320, 240);
}
// More to come…
/*
SurfaceHolder.Callback
*/
@
Override
public void surfaceChanged(
SurfaceHolder sh, int f, int w, int h) {}
@
Override
public void surfaceCreated(SurfaceHolder sh) {
_mediaPlayer = new MediaPlayer();
_mediaPlayer.setDisplay(_surfaceHolder);
Context context = getApplicationContext();
Map headers = getRtspHeaders();
Uri source = Uri.parse(RTSP_URL);
try {
// Specify the IP camera’s URL and auth headers.
_mediaPlayer.setDataSource(context, source, headers);
// Begin the process of setting up a video stream.
_mediaPlayer.setOnPreparedListener(this);
_mediaPlayer.prepareAsync();
} catch (Exception e) {}
}
@
Override
public void surfaceDestroyed(SurfaceHolder sh) {
_mediaPlayer.release();
}
private Map getRtspHeaders() {
Map headers = new HashMap();
String basicAuthValue = getBasicAuthValue(USERNAME, PASSWORD);
headers.put("Authorization", basicAuthValue);
return headers;
}
private String getBasicAuthValue(String usr, String pwd) {
String credentials = usr + ":" + pwd;
int flags = Base64.URL_SAFE | Base64.NO_WRAP;
byte[] bytes = credentials.getBytes();
return "Basic" + Base64.encodeToString(bytes, flags);
}
/*
MediaPlayer.OnPreparedListener
*/
@
Override
public void onPrepared(MediaPlayer mp) {
_mediaPlayer.start();
}
}
确保 Android 的 MediaPlayer 确实可以打开和解码您的流。现在,如果 MediaPlayer 无法处理您的流,您将捕获任何异常并默默地忽略它:
try {
// Specify the IP camera’s URL and auth headers.
_mediaPlayer.setDataSource(context, source, headers);
// Begin the process of setting up a video stream.
_mediaPlayer.setOnPreparedListener(this);
_mediaPlayer.prepareAsync();
} catch (Exception e) {}
至少你应该记录错误:
} catch (Exception e) {
Log.e("MyApp", "Could not open data source", e);
}
尽管 MediaPlayer 服务很可能会在日志中加入其自身的错误。所以你应该做的是查看 logcat 是否有来自 "VideoDecoder" 或类似的消息。
要在 Android Studio 中查看 logcat,请打开默认位于底部的 "Android Monitor" 选项卡。如果您想查看未过滤的 logcat,请确保在 Android 监视器视图的右上角显示 "No Filters" 而不是 "Show only selected application".
我有一些链接到 Foscam 视频流的新代码,但只在它开始时抓取帧然后不流式传输。我更近了,但仍然需要帮助。我走对了吗?
package com.rednak.camstream;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.VideoView;
public class MainCamActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_cam);
VideoView vidView = (VideoView)findViewById(R.id.CamVideoView);
String vidAddress = "http://rednak71.ddns.net:8090/CGIProxy.fcgi? cmd=snapPicture2&usr=guest&pwd=guest&t=";
Uri vidUri = Uri.parse(vidAddress);
vidView.setVideoURI(vidUri);
vidView.start();
}
}