美文网首页
MediaMuxer对音视频进行混合封装

MediaMuxer对音视频进行混合封装

作者: ZebraWei | 来源:发表于2019-12-07 15:44 被阅读0次

    版权声明:本文为卫伟学习总结文章,转载请注明出处!
    MediaMuxer的使用比较简单,方法很少,就那么几个。但是需要注意的是我们添加音视频轨的时候,MediaMuxer.addTrack(MediaFormat)需要一个MediaFormat参数,而这个参数不是我们打开的MediaCodec的时候简单构造的那个,这个MediaFormat必须是从MediaCodec.getOutputFormat()获取的,他们完全不一样。如果我们直接使用自己简单构造的MediaFormat,是无法写入音视频数据的。
    我们也可以自己构造自己添加音视频轨道的MediaFormat,MediaMuxer的主要方法:

    • 1.int addTrack(@NonNull MediaFormat format)
      一个视频文件是包含一个或多个音视频轨道的,这个方法就是用于添加一个视频或视频轨道,并返回对应的ID.之后通过这个ID向相应的轨道写入数据。用于新建音视频轨道的MediaFormat是需要从MediaCodec.getOutputFormat()获取的,而不是简单构造的MediaFormat。
    • 2.start()
      添加完所有音视频轨道之后,需要调用这个方法告诉Muxer,开始写入数据。需要注意的是,调用这个方法之后,无法再次addTrack了。
    • 3 void writeSampleData(int trackIndex, @NonNull ByteBuffer byteBuf, @NonNull BufferInfo bufferInfo)
      用于向Muxer写入编码后的音视频数据。trackIndex是addTrack的时候返回的ID,byteBuf便是要写入的数据,而bufferInfo是跟这一帧byteBuf相关的信息,包括时间戳、数据长度和数据在ByteBuffer中的位移
      1. void stop()
        与start()向对应,用于停止写入数据,并生成文件。
    • 5.void release()
      释放Muxer资源。
      整个流程用到的就是这五个方法。先构造一个Muxer,需要两个参数,第一个是音视频文件的保存路径,第二个是音视频封装文件的格式,可以选择mp4或3gp,用mp4就好。
    private fun start() {
    //用于标记是否已经添加视频轨道
    mVideoTrackReady = false
    //用于标记是否已经添加银频轨道
    mAudioTrackReady = false
    //用于标记是否已经开始
    mStart = false
    //删除已存在的文件
    val file = File(path)
    if (file.exists()) file.delete()
    muxer = MediaMuxer(path, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
    }
    

    需要在添加音频和视频轨道之后才能开始Muxer,所以分别用两个bool来标记对应的轨道已经添加,并且每次添加轨道时,都使用ready()检查是否开启Muxer.

    private fun ready() {
    if (mVideoTrackReady && mAudioTrackReady) {
        muxer?.start()
        mStart = true
        debug_e("Muxer start")
        }
    }
    
    override fun addVideoTrack(format: MediaFormat) {
    try {
        videoTrack = muxer!!.addTrack(format)
    } catch (e: Exception) {
        //Add video track failed
        e.printStackTrace()
        return
    }
    mVideoTrackReady = true
     ready()
    }
    
    override fun addAudioTrack(format: MediaFormat) {
    try {
        audioTrack = muxer!!.addTrack(format)
    } catch (e: Exception) {
        //Add audio track failed
        e.printStackTrace()
        return
    }
    mAudioTrackReady = true
    ready()
    }
    

    添加完轨道之后,就可以开始给Muxer写入数据了,这部分也很简单。我们只需要根据addTrack时返回的ID对应的写入数据就好。

    private fun writeSample(track: Int, sample: Sample) {
    try {
        muxer?.writeSampleData(track, sample.sample, sample.bufferInfo)
    } catch (e: Exception) {
        //Write sample failed
        e.printStackTrace()
    }
    

    最后我们写完数据之后,一定要记得调用stop()来生成文件和release()释放资源。

    private fun stop() {
    if (mStart) {
        mStart = false
        try {
            muxer?.stop()
        } catch (e: IllegalStateException) {
            e.printStackTrace()
        }
    }
    muxer?.release()
    }
    

    使用MediaMuxer对音视频进行混合封装。

    相关文章

      网友评论

          本文标题:MediaMuxer对音视频进行混合封装

          本文链接:https://www.haomeiwen.com/subject/ptfugctx.html