使用 MediaRecorder实现分段录制视频

使用 MediaRecorder实现分段录制视频

使用 MediaCodec 和 MediaMuxer 也可以实现分段录制视频,而也是一直这样做,但是遇到一个问题,就是 MediaMuxer 的 OutputFormat 支持 4 种格式,分别是 MUXER_OUTPUT_MPEG_4、MUXER_OUTPUT_WEBM、MUXER_OUTPUT_3GPP、MUXER_OUTPUT_HEIF,一般经常用的也就是 MUXER_OUTPUT_MPEG_4,录制 .mp4 格式的文件。

但是在录制时,有一个情况,就是我的设备突然断电时,最后录制的那段视频是损坏的,无法播放。合作伙伴的录像是录出 .ts 文件格式,设备突然断电文件依然可以正常播放,公司领导让我调研一下。我发现 MediaRecorder 可以录制 .ts 视频,MediaRecorder 的 OutputFormat 包含 MPEG_2_TS 这个格式,也就可以录制 .ts 文件,确实录制 .ts 文件过程中,中途给设备断电,最后那段文件依然可以播放。

但是在实现分段录制时,遇到了各种各样的情况,首先官方 api 提供了 setMaxDuration 的方法,到了设定的时间,会有回调方法进行通知,但是,通知收到后,MediaRecorder 就进入了 stop 状态,无法继续录制,想要继续录制,要重新初始化 MediaRecorder。

下面是我最终实现的解决方法,代码中有我的注释,有不对的地方请帮忙指出。

private void initMediaRecorder() {
        mediaRecorder = new MediaRecorder();
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);// 这里我是用的 surface 作为源,一般这里设置 camera
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_2_TS);// 设置 ts 格式
        mediaRecorder.setVideoFrameRate(25);
        mediaRecorder.setVideoSize(1920, 1080);
        mediaRecorder.setVideoEncodingBitRate(2097152);// 2M 码率
        mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        // 这里有一个问题,当我的格式设置成 ts 格式时,下面的 MaxDuration 就不起作用了,不知道为什么,MPEG_4 格式就可以。
//        mediaRecorder.setMaxDuration(1000 * 10);// 测试 10 秒钟路一段
//        mediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() {
//            @Override
//            public void onInfo(MediaRecorder mr, int what, int extra) {
//                Log.e("WillWolf", "onInfo-->" + what);
//                if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
//                    // 官方文档说明,设置了最大时长时,回调会进入 stop 状态,如果需要继续录制,则需要重新初始化
//                    mediaRecorder.stop();
//                    mediaRecorder.reset();
//                    mediaRecorder.release();
//                    mediaRecorder = null;
//                    isFirstStart = false;
//                    initMediaRecorder();
//                }
//            }
//        });
        mediaRecorder.setOutputFile("/sdcard/" + System.currentTimeMillis() + ".ts");
        try {
            mediaRecorder.prepare();
            mediaRecorderSurface = mediaRecorder.getSurface();
            mediaRecorder.start();
            // 我改用 handler 测试分段,10 秒种后,handler 录制下一段。
            handler.sendEmptyMessageDelayed(1, 10 * 1000);
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("WillWolf", "mediaRecorder-->" + e.toString());
        }
    }
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;
                isFirstStart = false;
                initMediaRecorder();
            }
            return false;
        }
    });

这也算是曲线救国了,测试程序看起来可以录制 .ts 文件,并且实现了分段录制,当意外断电时,最后的 .ts 文件依然可以播放。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值