【问题标题】:Creating a video with MediaExtractor and MediaMuxer produces a video with shorter duration than the original one使用 MediaExtractor 和 MediaMuxer 创建视频会产生比原始视频持续时间更短的视频
【发布时间】:2022-01-05 16:19:49
【问题描述】:

出于测试目的,我使用 MediaExtractor 和 MediaMuxer 从现有视频创建新视频。我希望新视频的持续时间与原始视频完全相同,但事实并非如此。新的视频时长比原来的略短。

fun test(firstVideo: FileDescriptor,  outputFileAbsolutePathUri: String) {
    val extractor = MediaExtractor().apply {
        this.setDataSource(firstVideo)
    }

    val muxer = MediaMuxer(outputFileAbsolutePathUri, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
    try {
        val MAX_SAMPLE_SIZE = 20 * 1024 * 1024
        val bufferSize: Int = MAX_SAMPLE_SIZE
        val dstBuf: ByteBuffer = ByteBuffer.allocate(bufferSize)
        val bufferInfo = MediaCodec.BufferInfo()
        val indexMap = setMuxerTracks(extractor, muxer)
        muxer.start()
        muxDataFromExtractor(muxer, extractor, indexMap, dstBuf, bufferInfo)
        muxer.stop()
    } finally {
        extractor.release()
        muxer.release()
    }
}
               

private fun setMuxerTracks(extractor: MediaExtractor, muxer: MediaMuxer): Map<Int, Int> {
    val indexMap = HashMap<Int, Int>(extractor.trackCount)
    for (i in 0 until extractor.trackCount) {
        extractor.selectTrack(i)
        val format: MediaFormat = extractor.getTrackFormat(i)
        val dstIndex = muxer.addTrack(format)
        indexMap[i] = dstIndex
    }
    return indexMap
}

private fun muxDataFromExtractor(muxer: MediaMuxer,
                                extractor: MediaExtractor,
                                trackIndexMap: Map<Int, Int>,
                                dstBuf: ByteBuffer,
                                bufferInfo: MediaCodec.BufferInfo) {
    var sawEOS = false
    val initialPresentationTimeUs = bufferInfo.presentationTimeUs
    while (!sawEOS) {
        bufferInfo.offset = 0
        bufferInfo.size = extractor.readSampleData(dstBuf, 0)
        if (bufferInfo.size < 0) {
            sawEOS = true
            bufferInfo.size = 0
        } else {
            bufferInfo.presentationTimeUs = initialPresentationTimeUs + extractor.sampleTime
            bufferInfo.flags = extractor.sampleFlags
            val trackIndex = extractor.sampleTrackIndex
            muxer.writeSampleData(trackIndexMap[trackIndex]!!, dstBuf, bufferInfo)
            extractor.advance()
        }
    }
}

为了便于比较,原始视频时长为 3366666 微秒,而创建的视频时长为 3366366 微秒。视频长度取自 MediaFormat (MediaFormat.KEY_DURATION)

【问题讨论】:

    标签: android android-mediacodec mediamuxer mediaextractor


    【解决方案1】:

    没有答案,但一些输入可能会有所帮助:

    1. 我相信媒体提取器和媒体复用器是供应商拥有的,谷歌有默认的 cpp 实现,但供应商可以覆盖它。你可以在这里查看谷歌的实现: https://cs.android.com/android/platform/superproject/+/master:frameworks/av/media/libstagefright/MediaMuxer.cpp;l=173

      它帮助我解决了引擎中与“最后一帧”/时间不匹配相关的一个巫毒错误。注意:您需要确保您正在查看正确的版本(检查右侧的责备工具)。

    2. 媒体可以包含在创建文件时推送的任何元数据值。所以,你可以重新计算,或者直接使用你得到的。

    3. 您是否尝试拍摄您创建的视频,然后在此文件作为输入时运行测试?

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案2】:

    这似乎取决于源视频的创建方式:当我使用 ffprobe 获取源视频元数据时,我得到了以下信息:

    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'source.mp4':
      Metadata:
        major_brand     : isom
        minor_version   : 512
        compatible_brands: isomiso2avc1mp41
        encoder         : Lavf58.76.100
      Duration: 00:00:03.37, start: 0.000000, bitrate: 123 kb/s
        Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 400x136, 118 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
        Metadata:
          handler_name    : Core Media Video
    

    结果视频元数据是:

     Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'result.mp4':
      Metadata:
        major_brand     : mp42
        minor_version   : 0
        compatible_brands: isommp42
        creation_time   : 2022-01-06T12:01:21.000000Z
        com.android.version: 11
      Duration: 00:00:03.37, start: 0.000000, bitrate: 126 kb/s
        Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 400x136, 118 kb/s, SAR 1:1 DAR 50:17, 30 fps, 30 tbr, 90k tbn, 60 tbc (default)
        Metadata:
          creation_time   : 2022-01-06T12:01:21.000000Z
          handler_name    : VideoHandle  
    

    当我使用使用 MediaExtractor 和 MediaMuxer 创建的视频作为源时,视频持续时间相同(在 1 微秒阈值内)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-25
      • 1970-01-01
      • 2016-12-10
      • 2014-08-07
      • 2016-12-17
      • 1970-01-01
      相关资源
      最近更新 更多