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

 天晴的故事_665 发布于 2022-12-27 13:51

这是我的场景:

从网上下载avi电影

打开位图资源

在背景中的所有帧上将此位图叠加在电影的底部

将视频保存在extarnal存储上

视频长度通常为15秒

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

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

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

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

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

    从外部存储打开视频文件

    开始解码它

    每个解码的帧将被改变,内存中的位图覆盖

    帧被发送到编码器.

在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+上正常工作,而在旧版本上生成黑色视频文件.但是,在真实设备上进行测试似乎有效.

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

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

    在此输入图像描述

    2022-12-27 13:54 回答
  • 我对MediaMuxer知之甚少,但ffmpeg确实支持覆盖功能.FFMPEG有各种过滤器,其中一个是叠加过滤器.我所理解的是你想要在视频上叠加一个图像(即png),ffmpeg肯定是一个有用的框架来完成这项工作.您可以设置输出格式,您可以设置要过度显示的图像的坐标.

    例如

    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的性能,因为它是一个纯软件框架.

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

    2022-12-27 13:54 回答
  • 如果你需要在Android设备上没有ffmpeg的情况下这样做:

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

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

    脚步:

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

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

      在Surface上绘制此视频纹理.

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

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

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

      然后转到第2步.

    不要忘记调整解码速度.只需删除SpeedControlCallback示例中的哪个设置即可解码60 FPS视频.

    这种方式的优点:

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

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

    2022-12-27 13:56 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有