在一个包含不同MediaCodec
和(其他Android.Media
命名空间的东西)概念证明的应用程序中,我在 opengl 帧上生成一个视频以及一个 PCM 音调,以便我有数据发送到两个MediaCodec
编码器(PCM 块发送到MediaCodec
音频编码器和带有表面颜色格式的帧发送到MediaCodec
视频编码器)。
你看我来了:我制作 AVC/mp4a 电影。这些生成的电影在任何播放器中都播放得很好。
我正在使用MediaMuxer
将视频合并在一起。我知道MediaFormat
视频需要相同才能将它们合并在一起。但是,假设我有这些电影:
Happy_cat.mp4 320x20024fps1 i-frame per secondSource: Interwebz
甲乙_Yellow background.mp4320x20024fps1 i-frame per secondSource: Me
使用MediaMuxer
,我可以将 A 的任何拆分或完整版本混合在一起,或者将 B 混合在一起,但我不能将 A 与 B 合并。
如果我连接 A(1) + B(1) + A(2) + B(2),我会看到玩家玩 A(1) 然后跳到 A(2),跳过 B 的确切持续时间。话,它会显示猫,然后跳到猫而不显示黄色背景。如果我连接 B(1)+A(1)+B(2)+A(2),则相同。我的声音会看到黄色,它会跳过猫,然后会显示黄色,然后在播放猫之前停止。
知道电影需要共享相同的格式,我有一个参考电影,我使用MediaExtractor
.
由于在将轨道添加到复用器之前无法在 MediaFormat 中设置的参数,我是否仅限于具有相同来源的电影?MediaFormat 中是否csd-0
重要?csd-1
因为我认为视频之间可能会有所不同。这是我比较视频时最担心的问题。我担心MediaMuxer
可能会在某些原生 API 方法中消化 csd-0 中的这些数据,以及如果存在基于 csd-0/csd-1 中数据的媒体配置差异的错误。[更新] 在阅读了有关 csd-x 的http://bigflake.com/mediacodec/部分后,我越来越确信这是 csd 的问题。唯一的解决方案是对所有内容进行转码。:(
来自 B(1) A(1) B(2) A(2) 合并的数据
B(1) 黄色:
format {{max-input-size=266, durationUs=2809569, channel-count=1,
mime=audio/mp4a-latm, csd-
0=java.nio.ByteArrayBuffer[position=0,limit=2,capacity=2], sample-
rate=44100}}
format {{max-input-size=431, durationUs=3041666, csd-
1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8], height=480,
mime=video/avc, csd-
0=java.nio.ByteArrayBuffer[position=0,limit=18,capacity=18], width=270}}
A(1) 猫:
format {{max-input-size=23243, durationUs=7000000, csd-
1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8], height=480,
mime=video/avc, csd-
0=java.nio.ByteArrayBuffer[position=0,limit=14,capacity=14], width=270}}
format {{max-input-size=220, durationUs=7066621, channel-count=1,
mime=audio/mp4a-latm, csd-
0=java.nio.ByteArrayBuffer[position=0,limit=2,capacity=2], sample-
rate=44100}}
B(2) 黄色:
format {{max-input-size=266, durationUs=2809569, channel-count=1,
mime=audio/mp4a-latm, csd-
0=java.nio.ByteArrayBuffer[position=0,limit=2,capacity=2], sample-
rate=44100}}
format {{max-input-size=431, durationUs=3041666, csd-
1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8], height=480,
mime=video/avc, csd-
0=java.nio.ByteArrayBuffer[position=0,limit=18,capacity=18], width=270}}
A(2) 猫:
format {{max-input-size=23243, durationUs=7000000, csd-
1=java.nio.ByteArrayBuffer[position=0,limit=8,capacity=8], height=480,
mime=video/avc, csd-
0=java.nio.ByteArrayBuffer[position=0,limit=14,capacity=14], width=270}}
format {{max-input-size=220, durationUs=7066621, channel-count=1,
mime=audio/mp4a-latm, csd-
0=java.nio.ByteArrayBuffer[position=0,limit=2,capacity=2], sample-
rate=44100}}
[更新]
在我的原始源代码中,我没有正确设置曲目顺序。解决这个问题后,我可以说用手机(MediaCodec/MediaMuxer/3rd 方应用程序)制作的任何东西都将具有相同的音频和视频 CSD,并且会优雅地合并。任何外部 AVC 电影通常都会有不同的 CSD,如果是这样,则不会合并,因此在能够合并之前,必须从支持/可播放的 AVC 转码到手机 CODEC AVC。请注意,可以播放的任何内容都可以与所有其他 MediaCodec 功能一起使用。由于它是用未知的编码器编码的,因此播放该视频变得不那么简单了。可能有一些可能性可以从外部来源的电影中复制 CSD,但我没有成功。
为了确定电影是使用所有者手机还是其他手机编码的,在启动我的应用程序时,我创建了一个空电影并将捕获的 CSD 保存到文件中。然后我可以将它与任何电影进行比较。如果有一个开发良好的助手可以使 CSD 数据人性化,这样至少它很容易理解并且更容易使编码适应该源,这将是很有趣的。