33

这是我的场景:

  • 从网上下载 avi 电影
  • 打开位图资源
  • 将此位图叠加在影片底部的所有背景帧上
  • 将视频保存在外部存储上
  • 视频长度通常为 15 秒

这可以使用 MediaMuxer 来实现吗?很高兴收到有关此事的任何信息

我一直在寻找http://bigflake.com/mediacodec/#DecodeEditEncodeTest(感谢@fadden),它在那里说:

“在 Nexus 5 上解码帧并将其复制到 ByteBuffer glReadPixels()中大约需要 8 毫秒,速度足以跟上 30fps 输入的速度,但是将其作为 PNG 保存到磁盘所需的额外步骤非常昂贵(大约半秒) "

所以几乎 1 秒/帧是不可接受的。从我的想法来看,一种方法是将每个帧保存为 PNG,打开它,在其上添加位图叠加,然后保存。然而,这将花费大量时间来完成。

我想知道是否有办法做这样的事情:

  1. 从外部存储打开视频文件
  2. 开始解码
  3. 每个解码的帧都将随着内存中的位图覆盖而改变
  4. 帧被发送到编码器。

在iOS上,我看到有一种方法可以获取原始音频+原始视频+图像并将它们添加到容器中,然后对整个内容进行编码......

我应该切换到 ffmpeg 吗?ffmpeg 的稳定性和兼容性如何?我是否冒着与 android 4.0+ 设备的兼容性问题的风险?有没有办法使用 ffmpeg 来完成这个?我是这个领域的新手,还在做研究。


多年后的编辑:
问题已经过去了很多年,而且 ffmpeg 在许可方面并不是很容易添加到商业软件中。这是如何演变的?使用默认 sdk 的较新版本的 android 在这方面的能力更强?


稍后再编辑

我因发布信息作为答案而获得了一些反对票,因此我将编辑原始问题。这是一个很棒的库,从我的测试来看,它确实将水印应用于视频,并使用进度回调进行处理,从而更容易向用户显示进度,并且还使用默认的 android sdks。https://github.com/MasayukiSuda/Mp4Composer-android

该库使用 Android MediaCodec API 生成 Mp4 电影并应用过滤器、缩放和旋转 Mp4。

示例代码,可能如下所示:

new mp4Composer(sourcePath, destinationPath)
        .filter(new GlWatermarkFilter(watermarkBitmap)
        .listener(){
              @Override 
              private void onProgress(double value){}

              @Override 
              private void onCompleted(double value){
                  runOnUiThread( () ->{
                     showSneakbar
                  }
              }

              @Override 
              private void onCancelled(double value){}

              @Override 
              private void onFailed(Exception e){}

        }).start();

在模拟器上进行测试,似乎在 android 8+ 上运行良好,而在旧版本上会生成黑色视频文件。但是,在真实设备上进行测试时似乎可以正常工作。

4

4 回答 4

22

I don't know much about the MediaMuxer but ffmpeg does support overlaying functionality. FFMPEG has various filters one of them is overlay filter. What I understand is you want to overlay an image (i.e. png) on the video, ffmpeg surely is a useful framework to do this job. You can set the output format you can set the co-ordinates of the image which is to be overplayed.

E.g.

ffmpeg -i input.avi -i logo.png -filter_complex 'overlay=10:main_h-overlay_h-10' output.avi

Above command adds overlays logo.png on the input.avi video file in bottom left corner.

More information about the filters is available at following website,

https://www.ffmpeg.org/ffmpeg-filters.html#overlay-1

If this is a solution to your problem you need the C code equivalent to the above command. You also need to see the performance of the ffmpeg because it a pure software framework.

Hope I have understood your question correctly and this helps.

于 2014-08-26T11:26:53.463 回答
14

如果您需要在 Android 设备上不使用 ffmpeg执行此操作:

开始于:https ://github.com/google/grafika

播放视频 (PlayMovieActivity.java)Record Gl App (RecordFBOActivity.java)示例之间的问题的答案。

脚步:

  1. 将 mInputWindowSurface 设置为 Video Encoder Input Surface。

  2. 使用 MoviePlayer 作为视频(外部)纹理从视频流中解码帧。

  3. 在 Surface 上绘制此视频纹理。

  4. 在视频纹理的同一表面上绘制水印。

  5. 通知 MediaCodec 表面准备好编码:

    mVideoEncoder.frameAvailableSoon(); 
    mInputWindowSurface.setPresentationTime(timeStampNanos);
    

    然后转到第 2 步。

不要忘记调整解码速度。只需删除SpeedControlCallback示例中设置为解码 60 FPS 视频的内​​容。

这种方式的优点:

  1. 媒体编解码器使用硬件解码器/编码器进行视频处理。

  2. 您可以更改结果视频的比特率。

于 2017-04-05T12:29:34.717 回答
8

您可以尝试 INDE 媒体包 - https://software.intel.com/en-us/articles/intel-inde-media-pack-for-android-tutorials

它具有作为 MediaComposer 类的转码\remuxing 功能和几个示例效果,如 JpegSubstituteEffect - 它显示了如何用 jpg 文件中的图片和 TextOverlayEffect 替换视频帧以覆盖视频帧上的文本等。它可以很容易地增强为水印效果

在此处输入图像描述

于 2014-08-18T08:59:46.040 回答
1

这对我有用:

ffmpeg -i input.avi -i logo.png -filter_complex 'overlay=10:main_h-overlay_h-10' -strict -2 output.avi

ffmpeg 建议使用-strict -2以允许使用实验性编解码器。如果没有包含,上面接受的答案将无法工作。

于 2015-08-01T16:10:39.270 回答