无法使用媒体提取器和媒体多路复用器合并2个mp4文件

时间:2019-06-06 13:01:32

标签: android video mediacodec mediamuxer android-mediacodec

我正在尝试将多个视频文件(mp4)合并为一个文件。我尝试使用mp4解析器,但也无法获得所需的结果。 (稍后将在其github上发布问题)

我尝试了以下代码。

getVideoFile(int i)仅返回视频编号i的绝对路径。 (像这样的sample1.mp4,sample2.mp4)。

运行此代码后,我最终得到的mp4大小等于所有视频的大小之和。这意味着所有帧都将添加到最终mp4中。音频完美地结合在一起,我能很好听。

唯一的问题是视频。我猜是由于无效的presentationTime而使框架错位了。帧随机显示在视频上。

任何帮助将不胜感激。

    val muxer: MediaMuxer = MediaMuxer(getOutputPath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
    var tracksAdded = 0
    var muxerStarted = false
    val indexMap = HashMap<Int, Int>()

    for(i in 2 until 6){
        val extractor = MediaExtractor()
        extractor.setDataSource(getVideoFile(i))
        val trackCount = extractor.trackCount
        //assertEquals("wrong number of tracks", expectedTrackCount, trackCount)
        // Set up MediaMuxer for the destination.

        // Set up the tracks.
        for (i in 0 until trackCount) {
            val format = extractor.getTrackFormat(i) {
                extractor.selectTrack(i)
                if (tracksAdded != 2) {
                    val dstIndex = muxer.addTrack(format)
                    indexMap[i] = dstIndex
                    tracksAdded++
                }
        }

        if(!muxerStarted) {
            muxer.start()
            muxerStarted = true
        }

        // Copy the samples from MediaExtractor to MediaMuxer.
        var sawEOS = false
        val bufferSize = MAX_SAMPLE_SIZE
        var frameCount = 0
        val offset = 100
        val dstBuf = ByteBuffer.allocate(bufferSize)
        val bufferInfo = BufferInfo()

        while (!sawEOS) {
            bufferInfo.offset = offset
            bufferInfo.size = extractor.readSampleData(dstBuf, offset)

            if (bufferInfo.flags and MediaCodec.BUFFER_FLAG_CODEC_CONFIG !== 0){
                bufferInfo.size = 0
            }

            if (bufferInfo.size < 0) {
                Timber.d("newCombine saw eos")
                sawEOS = true
                bufferInfo.size = 0
            } else {
                bufferInfo.flags = extractor.sampleFlags
                val trackIndex = extractor.sampleTrackIndex

                if(extractor.sampleTime< prevOutputPTSUs) {
                    bufferInfo.presentationTimeUs = prevOutputPTSUs + 300
                }else{
                    bufferInfo.presentationTimeUs = extractor.sampleTime
                }
                muxer.writeSampleData(indexMap[trackIndex] ?: 0, dstBuf,
                        bufferInfo)
                prevOutputPTSUs = bufferInfo.presentationTimeUs
                extractor.advance()
                frameCount++
                Log.d("newCombine", "Frame (" + frameCount + ") " +
                        "PresentationTimeUs:" + bufferInfo.presentationTimeUs +
                        " Flags:" + bufferInfo.flags +
                        " TrackIndex:" + trackIndex +
                        " Size(KB) " + bufferInfo.size / 1024)
            }
        }
    }

    muxer.stop()
    muxer.release()

我知道,我用于演示的方法可能是完全错误的,但是音频已正确合并,但视频未正确合并。

0 个答案:

没有答案