解决Android录制视频时异常断电或apk闪退导致视频播放不了问题

  • 2025-07-31 16:23:06

问题点描述

Android录制mp4(h264+acc)视频,当设备异常断电时,导致apk没法正常关闭录制;

问题点分析

经度娘分析,没能正常关闭录制的视频文件缺少少moov box,导致视频没法正常播放;

解决方案

经验证度娘给出的方案,发现都不满足需求或者不太好操作。最后跟同事讨论了一下决定更换录制的视频格式,直接换成TS文件。再次经度娘验证逻辑没用问题后,上代码。

package com.example.demo;

import android.graphics.ImageFormat;

import android.graphics.SurfaceTexture;

import android.hardware.Camera;

import android.hardware.camera2.CameraAccessException;

import android.media.CamcorderProfile;

import android.media.MediaRecorder;

import android.os.Build;

import android.os.Environment;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.Surface;

import androidx.appcompat.app.AppCompatActivity;

import com.zlmediakit.jni.ZLMediaKit;

import java.io.File;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {

private static final String TAG = MainActivity.class.getSimpleName();

private MediaRecorder mediaRecorder;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initMediaRecorder();

}

private void initMediaRecorder() {

//new SurfaceTexture

Camera mCamera = Camera.open(0);

Camera.Parameters params = mCamera.getParameters();

params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

mCamera.setParameters(params);

SurfaceTexture surfaceTexture = new SurfaceTexture(0);

try {

mCamera.setPreviewTexture(surfaceTexture);

} catch (IOException e) {

throw new RuntimeException(e);

}

mCamera.startPreview();

mCamera.unlock();

mediaRecorder = new MediaRecorder();

mediaRecorder.setCamera(mCamera);

mediaRecorder.reset();

mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置麦克风获取声音

mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 设置摄像头获取图像

mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS); // 设置 ts 格式

mediaRecorder.setVideoSize(1920, 1080);

mediaRecorder.setVideoEncodingBitRate(2*1024*1024);// 2M 码率

mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

File f = new File(MainActivity.this.getExternalFilesDir(null).getAbsolutePath() + "/video");

if (!f.exists()) f.mkdirs();

String p = f.getAbsolutePath() + "/" + System.currentTimeMillis() + ".ts";

Log.e(TAG, "initMediaRecorder 录制路径: " + p);

mediaRecorder.setOutputFile(p); // 设置视频输出路径

mediaRecorder.setPreviewDisplay(new Surface(surfaceTexture)); // 设置使用SurfaceView预览视频

mediaRecorder.setOrientationHint(90); // 调整播放视频角度

try {

mediaRecorder.prepare(); // 准备录像

} catch (Exception e) {

e.printStackTrace();

Log.e("WillWolf", "mediaRecorder-->录制异常:" + e.toString());

}

mediaRecorder.start();

handler.sendEmptyMessageDelayed(1, 10 * 1000);

}

private Handler handler = new Handler(new Handler.Callback() {

@Override

public boolean handleMessage(Message msg) {

if (msg.what == 1) {

mediaRecorder.stop();

mediaRecorder.reset();

mediaRecorder.release();

mediaRecorder = null;

initMediaRecorder();

}

return false;

}

});

}

注意一:要有摄像头、音频、读写文件权限(读文件可以不要)

注意二:这里不能直接使用setMaxDuration进行视频分段录制,具体原因看官方介绍,可以按我上面贴的代码来实现,不过这个方案不太完美,有丢帧。针对这个问题问了以下度娘,有解决方案,具体可以参见:大佬的博客

友情链接
Copyright © 2022 中国世界杯_多哈世界杯 - dianxinto.com All Rights Reserved.