Android 如何从onPreviewFrame()接收的字节数组制作视频
我能够从onPreviewFrame()获取字节数组形式的视频帧数据。我需要用这个字节数组制作一个视频。 下面是我的代码片段:Android 如何从onPreviewFrame()接收的字节数组制作视频,android,android-camera,android-mediarecorder,Android,Android Camera,Android Mediarecorder,我能够从onPreviewFrame()获取字节数组形式的视频帧数据。我需要用这个字节数组制作一个视频。 下面是我的代码片段: @Override public void onPreviewFrame(byte[] data, Camera camera) { try { File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
try {
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
}
}
FileOutputStream out = new FileOutputStream(mediaStorageDir.getAbsolutePath() + "video.mp4");
out.write(data);
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
生成的文件“video.mp4”不可播放
我们将非常感谢您为解决此问题提供的任何帮助或指导
注意
我的应用程序将支持Android 4+版本。以下是用于拍照和视频的代码
// Add listener to video capture button
VideoCapture = (Button)findViewById(R.id.buttonVideo);
VideoCapture.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
captureButton.setVisibility(View.GONE);
if(isRecording){
VideoCapture.setBackgroundResource(R.drawable.ic_action_videoplay);
// stop recording and release camera
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
isRecording = false;
}
else{
releaseCamera();
// initialize video camera
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
mMediaRecorder.start();
// inform the user that recording has started
isRecording = true;
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
VideoCapture.setBackgroundResource(R.drawable.ic_launcher_videopause);
isRecording = true;
}
}
});
private PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: ");
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
/* set image preview in imageview */
previewImage = (ImageView)findViewById(R.id.imageViewPrieview);
previewImage.setImageURI(Uri.fromFile(pictureFile));
/* release camera & removeallview from preview */
relaese();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
/** Create a file Uri for saving an image or video */
private Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private 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), "MyCameraApp");
// 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").format(new Date());
if (type == MEDIA_TYPE_IMAGE){
// mediaFile = new File(mediaStorageDir.getPath() + File.separator +
// "IMG_"+ timeStamp + ".jpg");
mediaFile = new File("/sdcard/"+ "IMG_"+ timeStamp + ".jpg");
Log.i("Image","Image is captured");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
这些代码是为录像机准备的
private boolean prepareVideoRecorder(){
mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
// step 1: Unlock camera & Set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// step 2: set Audio & Video Source
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// step 3: set camcorder profile , it required Api Level 8
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// step 4: set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
// step 5: set preview output
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// step 6: prepare Configured Media recorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d("TAG","IllegalStateException preparing MediaRecorder" + e.getMessage());
return false;
}catch (IOException e) {
Log.d("TAG","IO Exception preparing MediaRecorde" + e.getMessage());
return false;
}
return true;
}
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
}
我想这对你有帮助。因为它对我有用
Android API目前不提供暂停方法
这有点技术性,但是征求意见的
从API级别1开始使用的没有暂停功能,从MediaRecorder状态图可以看出:
录制时,API允许我们使用reset()
或stop()
公共方法:
reset()
->将MediaRecorder重新启动到空闲状态
stop()
->停止录制
现在检查代码,我为视频捕获添加按钮点击事件Hi DreamCoder,谢谢回复。我需要根据从onPreviewFrame()接收到的帧数据(字节数组)制作视频,因为我需要在录制MediaRecorder支持的视频时实现暂停/恢复功能。这并不像您想象的那么简单。您正在创建文件名后缀为“.mp4”的一些字节的文件。了解更多关于MP4容器的信息。嗨,天墙,谢谢你的建议。我会朝这个方向看。也许MediaCodec会做你想做的事。请参阅Grafika()中的各种示例,例如“显示+捕获照相机”活动。API 18+。