我想在我的Android设备上播放(渲染到表面)两个或多个连续的mp4视频序列(每个存储在我的设备上的单独文件中,并且可能在启动时不存在),顺畅(无档位,闪烁等) 。)方式。因此,观众可能会看到只观看一个连续视频的印象。在第一步中,只为我的Nexus 7平板电脑实现这一目标就足够了。 我只使用 MediaCodec API 显示一个视频,其方式与http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/类似,但效果很好。通过仅在第一个序列完成后创建(并配置)第二个解码器(第一个被调用的 decoder.stop 和 decoder.release ),可以看到混合。为了在两个不同的视频序列之间平滑淡入淡出,我正在考虑使用 init 功能,其中第二个视频已经通过 decoder.configure(format,surface,null,0)初始化在播放第一个播放期间。此外,第一帧也通过 decoder.queueInputBuffer 排队。 但这样做会导致以下错误:
01-13 16:20:37.182: E/BufferQueue(183): [SurfaceView] connect: already connected (cur=3, req=3)
01-13 16:20:37.182: E/MediaCodec(9148): native_window_api_connect returned an error: Invalid argument (-22)
01-13 16:20:37.182: E/Decoder Init(9148): Exception decoder.configure: java.lang.IllegalStateException
在我看来,一个表面只能由一个解码器同时使用。那么,还有其他可能吗?也许使用OpenGL?
最佳, 亚历克斯。
答案 0 :(得分:1)
您使用MediaCodec
的多个实例所描述的内容将起作用,但您一次只能将一个“生产者”连接到Surface。你需要拆掉第一个,然后继续第二个,我不确定你能得到多少时间。
您可以做的是解码为SurfaceTexture
,然后在SurfaceView上绘制(使用,如您所想,使用OpenGL)。
您可以在ExtractMpegFramesTest示例中看到将MP4文件呈现为SurfaceTexture
的示例。从那里你只需要使用像CameraToMpegTest中的SurfaceView
类那样的表面(TextureView
?STextureRender
?)渲染纹理。
在Grafika中还有一些其他示例,尽管那里的视频播放器更接近您已有的(解码器输出到TextureView
)。
顺便提一下,你需要弄清楚在电影N的最后一帧和电影N + 1的第一帧之间放置了多少延迟。如果录制是以固定的帧速率拍摄的,那很容易,但有些来源(例如screenrecord
)不会记录那种方式。
更新:如果您可以保证您的影片剪辑具有相同的特征(大小,编码类型 - 基本上是MediaFormat
中的所有内容),则可以采用更简单的方法。当您点击流末尾时,您可以flush()
解码器,然后开始输入下一个文件。我用它在Grafika视频播放器中循环播放视频(见MoviePlayer#doExtract())。
答案 1 :(得分:0)
疯狂的想法。试试margin the two videos to one。它们都在你的设备上,所以它不应该花很长时间。你可以自己实现淡入淡出效果。