在android:4.3&#39的MediaMuxer或ffmpeg中添加水印位图

时间:2014-08-18 07:47:21

标签: android ffmpeg mp4 mediacodec mediamuxer

以下是我的情景:

  • 从网上下载avi电影
  • 打开位图资源
  • 在背景中所有帧上的电影底部覆盖此位图
  • 将视频保存在extarnal storage
  • 视频长度通常为15秒

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

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

  

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

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

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

  1. 从外部存储打开视频文件
  2. 开始解码
  3. 每个解码后的帧都将通过内存中的位图重叠进行更改
  4. 帧被发送到编码器。
  5. 在iOS上,我看到有一种方法可以将原始音频+原始视频+图像添加到容器中,然后对整个事物进行编码......

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


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


    稍后再编辑

    我发布了一些负面投票信息作为回答,所以我将编辑原始问题。这是一个很棒的库,从我的测试中确实将水印应用于视频并使用进度回调进行处理,这使得向用户显示进度变得更加容易,并且还使用默认的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 个答案:

答案 0 :(得分:19)

我对MediaMuxer了解不多,但ffmpeg确实支持覆盖功能。 FFMPEG有各种过滤器,其中一个是叠加过滤器。我所理解的是你想要在视频上叠加一个图像(即png),ffmpeg肯定是一个有用的框架来完成这项工作。您可以设置输出格式,您可以设置要过度显示的图像的坐标。

E.g。

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

上面的命令在左下角的input.avi视频文件中添加了overlays logo.png。

有关过滤器的更多信息,请访问以下网站

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

如果这是您问题的解决方案,则需要与上述命令等效的C代码。您还需要查看ffmpeg的性能,因为它是一个纯软件框架。

希望我能正确理解你的问题,这会有所帮助。

答案 1 :(得分:10)

如果您需要在Android设备上执行 而不使用ffmpeg

从:https://github.com/google/grafika

开始

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

步骤:

  1. 将mInputWindowSurface设置为视频编码器输入曲面。

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

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

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

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

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

    然后转到第2步。

  6. 不要忘记调整解码速度。只需删除SpeedControlCallback,其中示例设置为解码60 FPS视频。

    这种方式的优点:

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

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

答案 2 :(得分:7)

您可以尝试使用INDE Media Pack - https://software.intel.com/en-us/articles/intel-inde-media-pack-for-android-tutorials

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

enter image description here

答案 3 :(得分:1)

这对我有用:

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

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