做了个实时视频采集的东西,代码仿照这个写的,代码基本上一样。调了半天,发现了一个相当奇怪的问题:
一开始发现Run了之后回调函数没有跑,就是那个每次Preview新建帧时应该被回调的onPreviewFrame()。不知道具体是怎么回事,什么错也不报,总之是这个函数里的代码木有执行。
结果想用Debug模式看一下是哪出的问题,一点一点单步运行,然后发现居然正常了,回调执行了,PC端画面也有了!
然后反复试,发现直接Run as androidXXX的话有极低的概率成功(目前就成功过一次),
如果用Debug跑,需要在surfaceCreated()里加个断点,然后单步运行几下,就基本上能成。
求问这是怎么回事啊?PS:用的MOTO ME865的机器,刚查了下有人说MOTO的机器不调用onPreviewFrame(),可我这debug以后确实成了(而且不是100%成功率)AndroidCameraVideo实时视频监控
一开始发现Run了之后回调函数没有跑,就是那个每次Preview新建帧时应该被回调的onPreviewFrame()。不知道具体是怎么回事,什么错也不报,总之是这个函数里的代码木有执行。
结果想用Debug模式看一下是哪出的问题,一点一点单步运行,然后发现居然正常了,回调执行了,PC端画面也有了!
然后反复试,发现直接Run as androidXXX的话有极低的概率成功(目前就成功过一次),
如果用Debug跑,需要在surfaceCreated()里加个断点,然后单步运行几下,就基本上能成。
求问这是怎么回事啊?PS:用的MOTO ME865的机器,刚查了下有人说MOTO的机器不调用onPreviewFrame(),可我这debug以后确实成了(而且不是100%成功率)AndroidCameraVideo实时视频监控
解决方案 »
- 如何发送HTTP PUT方式的请求
- Google Maps Android API v2官网样例com.example.mapdemo找不到R.java
- android 图片不能拉伸,apk图标
- 自定义的GroupView中动态添加button怎么显示不出来
- 急:十一还在写程序,求MapView上响应双击事件,长按事件
- 使用SurfaceView的同时对传感器对象实例化时出现诡异的现象
- 如何实现软件升级功能啊
- 应用程序运行就退出
- 求教 !!!震动器Vibrator系统状态的问题
- gallery滑动图片多次重叠
- Java程序移植到Android上容易吗?
- Android广播监听短信,在eclipse的虚拟机上测试没问题,安装到手机就监听不到.
来接收每一帧数据然后 存储 这一帧的数据?在onPreviewFrame 中 我原来只进行 Toast操作 是OK的 可以达到一致输出楼主贴一下你的代码看看
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private String TAG = "tag_CameraActivity";
private Camera mCamera = null;
private CameraPreview mPreview = null;
private MediaRecorder mMediaRecorder = null;
private boolean isRecording = false; @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View ContentView;
ContentView = inflater.inflate(R.layout.monitorview, null);
return ContentView;
} /**
* This is where we perform additional setup for the fragment that's either
* not related to the fragment's layout or must be done after the layout is
* drawn.
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Button captureButton = (Button) getActivity().findViewById(
R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isRecording) {
// 停止录像并释放camera
mMediaRecorder.stop(); // 停止录像
releaseMediaRecorder();// 释放MediaRecorder对象
mCamera.lock(); // 将控制权从MediaRecorder 交回camera // 通知用户录像已停止
setCaptureButtonText("Capture");
isRecording = false;
} else {
// 初始化视频camera
if (prepareVideoRecorder()) {
// Camera已可用并解锁,MediaRecorder已就绪,
// 现在可以开始录像
mMediaRecorder.start(); // 通知用户录像已开始
Log.v(TAG,
"capture button click, preparevideorecorder() success");
setCaptureButtonText("Stop");
isRecording = true;
} else {
// 准备未能完成,释放camera
releaseMediaRecorder();
// 通知用户
Log.v(TAG,
"capture button click, preparevideorecorder() failed");
}
}
}
});
// 创建Camera实例
mCamera = getCameraInstance();
setCameraDisplayOrientation(getActivity(),
Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);// 设置预览方向
// 创建Preview view并将其设为activity中的内容
mPreview = new CameraPreview(getActivity(), mCamera);
FrameLayout preview = (FrameLayout) getActivity().findViewById(
R.id.camera_preview);
preview.addView(mPreview);
} /*
* release hardware camera
*
* @see android.app.Activity#onDestroy()
*/
@Override
public void onDestroy() {
super.onDestroy();
releaseCamera();
} private boolean checkCameraHardware() {
if (getActivity().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// 摄像头存在
Log.v(TAG, "Camera check success.");
return true;
} else {
// 摄像头不存在
Log.v(TAG, "Camera check failed.");
return false;
}
} /** A safe way to get an instance of the Camera object. */
private Camera getCameraInstance() {
if (!checkCameraHardware())
return null;
Camera c = null;
try {
// c = Camera.open(); // attempt to get a Camera instance
c = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
} catch (Exception e) {
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
} public static void setCameraDisplayOrientation(Activity activity,
int cameraId, Camera camera) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
} int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
} private boolean prepareVideoRecorder() { if (mCamera == null) {
mCamera = getCameraInstance();
setCameraDisplayOrientation(getActivity(),
Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);
}
mMediaRecorder = new MediaRecorder(); // Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera); // Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
// mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO)
.toString());
Log.v(TAG, "path = " + getOutputMediaFile(MEDIA_TYPE_VIDEO).toString()); // Step 5: Set the preview output
if (mPreview == null) {
mPreview = new CameraPreview(getActivity(), mCamera);
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
}
// Step 6: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG,
"IllegalStateException preparing MediaRecorder: "
+ e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
} /** Create a File for saving an image or video */
private static File getOutputMediaFile(int type) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this. File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"TestCamera");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
} // Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.SIMPLIFIED_CHINESE).format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
} else {
return null;
} return mediaFile;
} private void setCaptureButtonText(String text) {
Button button = (Button) getActivity()
.findViewById(R.id.button_capture);
button.setText(text);
} private void releaseMediaRecorder() {
if (mMediaRecorder != null) {
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
}
} private void releaseCamera() {
if (mCamera != null) {
mCamera.release(); // release the camera for other applications
mCamera = null;
}
}
}
SurfaceHolder.Callback {
public SurfaceHolder mHolder;
private String mIpname = "192.168.137.1";
private Camera mCamera; // hardware? graphics?
private String TAG = "tag_CameraPreview";
private static final int mPort=6001; public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera; // Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
// mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
} @Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the
// preview.
try {
mCamera.setPreviewDisplay(holder); mCamera.setPreviewCallback(new StreamIt(mIpname)); // 设置回调的类 mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
} @Override
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
} @Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it. if (mHolder.getSurface() == null) {
// preview surface does not exist
return;
} // stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
} // set preview size and make any resize, rotate or
// reformatting changes here // start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview(); } catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
} /*
* Test solution 1 solution 1: use callback method of Camera.PreviewCallback
* , to send every preview frame to the pc server
*/ class StreamIt implements Camera.PreviewCallback {
private String ipname; public StreamIt(String ipname) {
this.ipname = ipname;
Log.v(TAG, "StreamIt hs been newed");
} @Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.v(TAG, "onPreviewFrame has been called");
Size size = camera.getParameters().getPreviewSize();
try {
// 调用image.compressToJpeg()将YUV格式图像数据data转为jpg格式
YuvImage image = new YuvImage(data, ImageFormat.NV21,
size.width, size.height, null);
if (image != null) {
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
image.compressToJpeg(
new Rect(0, 0, size.width, size.height), 80,
outstream);
outstream.flush();
// 启用线程将图像数据发送出去
Thread th = new MyThread(outstream, ipname);
th.start();
}
} catch (Exception ex) {
Log.e("Sys", "Error:" + ex.getMessage());
Log.v(TAG, "catch exception in on PreviewFrame");
}
}
} class MyThread extends Thread {
private byte byteBuffer[] = new byte[1024];
private OutputStream outsocket;
private ByteArrayOutputStream myoutputstream;
private String ipname; public MyThread(ByteArrayOutputStream myoutputstream, String ipname) {
this.myoutputstream = myoutputstream;
this.ipname = ipname;
Log.v(TAG, "MyThread has been newed");
try {
myoutputstream.close();
} catch (IOException e) {
e.printStackTrace();
}
} public void run() {
try {
// 将图像数据通过Socket发送出去
Log.v(TAG, "new thread to send socket,in run()");
Log.v(TAG, "ipname = " + ipname+ "Port = "+mPort);
Socket tempSocket = new Socket(ipname, mPort);
outsocket = tempSocket.getOutputStream();
ByteArrayInputStream inputstream = new ByteArrayInputStream(
myoutputstream.toByteArray());
int amount;
while ((amount = inputstream.read(byteBuffer)) != -1) {
outsocket.write(byteBuffer, 0, amount);
}
myoutputstream.flush();
myoutputstream.close();
tempSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
}