在 android 中将叠加层添加到视频导出为视频

Adding Overlays to Videos export as a video in android

所以我有一个视频,例如。一个赛车视频,我创建了一个覆盖视图(透明的相对布局),其中包括一些与速度和性能相关的进度条现在我需要导出在此视图中看到的完整视频所以任何人都可以帮助我我已经通过 ffmpeg,opencv但没有成功。

Similar Ios Overlay

我认为您可以使用 OpenCV 或 ffmpeg 来完成此任务,但它们似乎不是完成此任务的正确工具。 OpenCV 非常适合高级视频处理,并且在底层使用 ffmpeg 进行解码和编码功能。当您需要支持多种媒体格式时,ffmpeg 非常有用。对于 ffmpeg,您可以尝试 运行 运行 它作为一个独立的进程,但这对于权限问题和错误处理来说不太理想。您也可以编写自己的 Android NDK API 并结合 ffmpeg,但这可能需要付出很多努力。假设您需要的输出媒体格式是 supported by Android,最简单的方法是使用 Android MediaCodec 库。

查看 Google 中的 this test code,了解如何解码、编辑和编码。您可以将视频文件解码为 SurfaceTexture。对于编辑部分,您将使用 OpenGL ES 进行叠加。叠加图像可以上传到纹理并在视频帧 SurfaceTexture 上绘制。绘制场景后,可以将输出的纹理发送到 MediaCodec 编码器。这都可以在导出过程中完成,不一定需要与您的可视视频和透明相对布局相关联。

要将视频解码为位图并将位图编码回 mp4 视频,您可以使用 jcodec

SequenceEncoder sequenceEncoder = new SequenceEncoder(new File(pathToSaveVideo));

循环执行这些步骤

  1. 提取每一帧视频的位图
  2. 结合叠加位图

     Canvas canvas = new Canvas(backgroundBitmap);
     Paint rectpaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     int width = overlayBitmap.getWidth();
     int height = overlayBitmap.getHeight();
     Rect des = new Rect(0, 0, canvas.getWidth(), canvas.getHeight());
     Rect src = new Rect(0, 0, width, height);
     canvas.drawBitmap(overlayBitmap, src, des, rectpaint);
    
  3. 将其编码回视频

    sequenceEncoder.encodeImage(backgroundBitmap);
    

循环后终于完成编码器

sequenceEncoder.finish()

您将能够使用 opencv org.bytedeco.javacpp 实现,我使用 FFmpegFrameGrabber 制作装饰帧,并使用 FFmpegFrameRecorder 使用相同的音频编解码器将此图像记录回 mp4。

Dependencies needed:

    compile group: 'org.bytedeco', name: 'javacv', version: '1.4'
    compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.4.0-1.4', classifier: 'android-arm'
    compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '3.4.1-1.4', classifier: 'android-arm'