专栏首页落影的专栏GPUImage详细解析(六)-用视频做视频水印

GPUImage详细解析(六)-用视频做视频水印

回顾

之前解析介绍的是GPUImage源码解析、图片模糊、视频滤镜,明白了GPUImage的强大功能,这次介绍的是两个视频的重叠,可以把两个视频文件合并,也可以把视频和录像结合在一起。

效果展示

视频的截图如下,视频由两个视频合成,一个来自于文件abc.mp4,一个来自于摄像头。

核心思路

摄像头采集的数据通过GPUImageVideoCamera进入响应链,视频文件的数据通过GPUImageMovie进入响应链,在GPUImageDissolveBlenderFilter进行合并,最后把数据传给响应链的终点GPUImageView以显示到UI和GPUImageMovieWriter以写入临时文件,最后临时文件通过ALAssetsLibrary写入系统库。

具体细节

1、GPUImageDissolveBlendFilter

GPUImageDissolveBlendFilter类继承GPUImageTwoInputFilter,添加属性mix作为片元着色器的mix参数。GPUImageDissolveBlendFilter在响应链上需要接受两个输入,当两个输入都就绪时,会通过mix()操作把输入混合,并且输出到响应链上。

思考1:如果只有一个输入会如何?

2、GPUImageMovie

GPUImageMovie类继承了GPUImageOutput类,一般作为响应链的源头,可以通过url、playerItem、asset初始化。

3、GPUImageMovieWriter

GPUImageMovieWriter类实现GPUImageInput协议,一般作为响应链的终点。shouldPassthroughAudio表示是否使用源音源。 movieFile.audioEncodingTarget = movieWriter;表示音频来源是文件。

if (audioFromFile) {
        // 响应链
        [movieFile addTarget:filter];
        [videoCamera addTarget:filter];
        movieWriter.shouldPassthroughAudio = YES;
        movieFile.audioEncodingTarget = movieWriter;
        [movieFile enableSynchronizedEncodingUsingMovieWriter:movieWriter];
    }
    else {
        // 响应链
        [videoCamera addTarget:filter];
        [movieFile addTarget:filter];
        movieWriter.shouldPassthroughAudio = NO;
        videoCamera.audioEncodingTarget = movieWriter;
        movieWriter.encodingLiveVideo = NO;
    }

思考2:音频来源的不同会对响应链造成什么样的影响?为什么?

4、响应链 响应链以GPUImageVideoCamera和GPUImageMovie作为输入,最终以GPUImageMovieWriter为输出。

  • 开始响应链的输入。
    [videoCamera startCameraCapture];
    [movieWriter startRecording];
    [movieFile startProcessing];
  • 设置movieWriter的结束回调。
[movieWriter setCompletionBlock:^{
}];

思考3:movieWriter的回调是什么时候调用的?由哪里触发?

思考4:movieWriter的encodingLiveVideo有什么用?把其设置为YES和NO试试,观察是否有影响?

总结

做demo的过程中遇到坑,GPUImage上面有Issues,但是并没有人解答ʕ̡̢̡ʘ̅͟͜͡ʘ̲̅ʔ̢̡̢。 代码地址在这里,参考链接上有趟坑的时候查到的一些资料。

附录

几个思考题都是做demo过程比较迷惑不解的地方和遇到的问题,答案分别是:

思考1:输入只有一个输入的时候,会一直等待第二个输入,不会有输出。问题出现在把videoCamera声明为临时变量,以为添加target会持有videoCamera的引用。实际上就会发生输入只有一个的时候(只有视频文件的信号),同时屏幕是白屏。

思考2:音频的来源不同会导致CMTime的不同,响应链视频信息的CMTime默认采用第一个输入的CMTime,故而修改音频来源的时候需要修改响应链的输入顺序,否则几秒钟的视频文件会产生两个多小时的文件(CMTime不同步导致)。

思考3:movieWriter的回调会在视频处理结束的时候调用,由GPUImageMovie的 reader.status == AVAssetReaderStatusCompleted触发。

思考4:encodingLiveVideo影响的其实是expectsMediaDataInRealTime属性,YES时用于输入流是实时的,比如说摄像头。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 程序员进阶之算法练习(四十二)

    题目链接 题目大意: n个学生参加测试,一共有m道题,每道题的答案可能是(A, B, C, D , E)中的一个; m道题分别有?1,?2,…,??,共m...

    落影
  • Metal入门教程总结

    本文介绍Metal和Metal Shader Language,以及Metal和OpenGL ES的差异性,也是实现入门教程的心得总结。

    落影
  • 程序员进阶之算法练习(二十)

    前言 这四个题属于中等,有的需要一定的代码量,有的需要奇妙的思考。 正文 1. Sonya and Queries 题目链接 ** 题目大意:** 给出一...

    落影
  • 前几天有个同学问我,“什么是响应式编程”?另,它和函数式编程有啥区别?

    前几天有个同学问我,啥叫响应式编程?当时我正在讲课没顾得上回他。今天晚上仔细写个文章回复他,顺便我自己也学习一下。 响应式编程的英文名,Reactive Pro...

    web前端教室
  • 让执着成为一种习惯——仿网易数独玫瑰气泡图

    没有难学的技艺,只有不够辛勤的付出! 今天这篇文章推送仿的的是网易数独的一幅信息图,内容呈现的是全球各国人民对于养老所持的态度,数据来源于Pew Reserch...

    数据小磨坊
  • 用Ansible管理你的OpenStack cloud[Openstack]

    在OpenStack上管理应用程序对系统管理员来说是一大挑战,而找到降低复杂性和产生一致性的方法是取得成功的关键因素。通过使用Ansible,一种无代理的IT自...

    用户6667850
  • 实在忍受不了鸡啼的主题了 - 自己给定制了一下

    老码农
  • 5个基本Linux命令行工具的现代化替代品

    在日常使用 Linux/Unix 系统时,我们会使用许多命令行工具来完成我们的工作,并理解和管理我们的系统,像 du 用于监视磁盘利用率,top 用于显示系统资...

    用户2781897
  • 泛函编程(0)-什么是泛函编程

     什么是泛函编程(Functional Programming)?泛函编程就是用函数编写程序。这个回答太抽象,等于没说。 再说清楚一点:泛函编程就想砌积木一样把...

    用户1150956
  • 编程不需要天赋和激情

    编程不需要天赋和激情 以往从来没有一种技能被神化到这样的高度: 你不仅得有天赋,还得具备激情,才能成为一名优秀的程序员。 好像那些写代码的人是早就决定干这一行...

    用户1289394

扫码关注云+社区

领取腾讯云代金券