Android 使用MediaCodec和MediaExtractor对视频进行解码和编码

Android 使用MediaCodec和MediaExtractor对视频进行解码和编码,android,video,bitmap,android-mediacodec,mediaextractor,Android,Video,Bitmap,Android Mediacodec,Mediaextractor,我需要将视频解码成一系列位图,这样我就可以修改它们,然后在android中将它们压缩回视频文件 我计划通过使用getFrameAtTime并将其保存到图像序列来管理它。然后我可以修改序列中的图像并将其编码回电影。但我有两个问题: 首先,正如我所读到的,getFrameAtTime用于创建缩略图,不能保证返回正确的帧。这使得视频滞后 其次,保存图像并将其读回需要很长时间 我了解到正确的解码方法是使用MediaExtractor,这很好,但我只有一些示例可以将其直接渲染到surfaceView。

我需要将视频解码成一系列位图,这样我就可以修改它们,然后在android中将它们压缩回视频文件

我计划通过使用
getFrameAtTime
并将其保存到图像序列来管理它。然后我可以修改序列中的图像并将其编码回电影。但我有两个问题:

  • 首先,正如我所读到的,
    getFrameAtTime
    用于创建缩略图,不能保证返回正确的帧。这使得视频滞后
  • 其次,保存图像并将其读回需要很长时间
我了解到正确的解码方法是使用MediaExtractor,这很好,但我只有一些示例可以将其直接渲染到
surfaceView
。有没有办法将
outputBuffer
转换成位图


我需要它让它在api级别为16及以上的情况下工作

你可以在网站上找到一系列有用的例子

特别是,
ExtractMpegFramesTest
演示如何将.mp4文件解码为
Bitmap
,而
DecodeEditEncodeTest
则解码并重新编码H.264流,使用GLES着色器修改帧

许多示例使用API 18中引入的功能,例如
Surface
输入到
MediaCodec
(这避免了许多颜色格式问题)和
MediaMuxer
(这允许您将从
MediaCodec
输出的原始H.264基本流转换为.mp4文件)。某些设备允许您将视频提取到
ByteBuffer
中的YUV数据,对其进行修改并重新编码,但其他设备提取到专有的YUV颜色格式,这些格式可能会被API 16版本的
MediaCodec
拒绝


我建议为API 18(Android 4.3“Jellybean”MR2)或更高版本进行编码。

有很多人说从未调用过方法
onFrameAvailable()
。嗯,侦听器应该位于与主线程不同的线程中。要设置侦听器,请执行以下操作:(其中这是实现
SurfaceTexture.IOnFrameAvailableListener
)的类侦听器:


好吧,问题是我已经看到了这个网站,但不幸的是,我必须为API lvl 16做这件事。尽管它说ExtractMpegFramesTest.java需要API 16,但当我尝试构建它时,它至少需要17。。。所以这不是一个选择。你有一个艰难的战斗。它是否需要正常工作,或者只是为特定设备而构建?(我将检查ExtractMpegFramesTest——我认为它不需要17+中的任何内容)这就是问题所在,它需要是通用的,api 16+级。。。我得到的getFrameAtTime解决方案在不保存到png的情况下可以工作,并且像这样加速了好几次,但是我仍然有一个问题,它会将一些帧提取两次,这会使视频滞后,我仍然不知道如何向其中添加音频。因此,任何将视频分割为位图并创建带有音频的新视频文件的建议都将受到欢迎,但它需要与16+配合使用。ExtractMPegFramest示例已修改为与API 16配合使用(需要EGL 1.0而不是EGL 1.4--cf.)。在API 18引入
MediaMuxer
类之前,没有创建.mp4文件(仅视频或视频+音频)的工具,因此如果需要,您可能希望研究外部库(可能是ffmpeg)。@fadden hi,我正试图让ExtractMpegFramesTest示例正常工作,但SurfaceTexture onFrameAvailable()电话从不打,或打得太晚。我在这里补充了一个问题-
mSurfaceTexture.SetOnFrameAvailableListener(this);