目录
起因
思考
简单测试
基于目标完成开发
实际运行的问题
总结
起因
这篇博客其实是ffmpeg多媒体框架的一个完整篇,我将从未知的状态去推导我是怎么找到答案的。
我的初始目标是希望合并一些视频,视频的情况是:300+个文件夹,每个文件夹是一个小时的视频,每个文件夹中有60个视频,每个视频时长是1分钟。
目录结构是这样:
文件夹:
2021050811
2021050812
2021050813
.....
2021050811文件夹下面:
20210508110000.mp4
20210508110100.mp4
20210508110200.mp4
......
所以明白了吧?在这种情况下,我想观看视频,我就只能一个个翻,每个视频只能看1分钟!
我的目标是按照文件夹(每小时)把60个视频合并成1个时长1小时的完整的视频,并且保证播放顺序正确。
而我是一个对视频剪辑一窍不通的人,如果要我去学习视频剪辑,对我来说学习成本太大,而且手动拼接这300*60约18000
个视频,也是很不现实的事情——而且人工就意味着出错的可能!
再一个,我认为按照顺序拼接视频
并不是一个需要人工介入太多的工作(不是复杂的脑力劳动),是一个机械化的工作,也就说明,它可以完全可以自动化实现。
综上所述,我觉得可以写个小程序帮助自己完成自动化合并视频的工作。
我的输入是指定时间内的多个视频文件,我的输出是一个合并了这些视频的大视频文件。
思考
在此之前,我没有接触过视频相关的开发工作,所以我对视频相关的开发工具没有任何概念。那么我该怎么开始搜索呢?
我盲猜C#/.NET应该有解决方案,因为视频的操作(合并、裁剪、播放等)是一个普遍
的需求,所以我的关键词是技术栈+目标
,最后得到的关键词是C# mp4 merge
,.NET# mp4 merge
,如果觉得mp4
关键词没有概括性,可以换成video
。
然后我得到了比较直接的答案,包括:
Split and Merge MP4 video
merge two mp4 video as single video using ffmpeg in C# is not working
How to merge 2 video files together in C#?
在以上三篇文章中,我发现了两个关键词,两种思路,一个是ffmpeg
,一个是splicer
。
尝试splicer
我并不知道ffmpeg
是什么,而splicer
看起来很简单,甚至在给出的链接splicer中有代码段和demo!
所以我下载了splicer的demo,并且通过随意录制的两个mp4视频来做测试,结果它们并没有办法合并在一起。
Tips:因为我们的目标文件是.mp4格式的,所以测试文件准备.mp4格式的。我们并不是要去做一个通用性的工具,所以不要节外生枝。
这里有两种选择,1.根据报错,继续搜索splicer
相关的解决方案,或者2.回到上一个点,选择ffmpeg
。
是否继续了解splicer
,可以根据1.代码是否开源,2.搜索结果有多少,3.作者是否活跃,4.(如果有)社区是否活跃来判断,简单来说,代码开源、搜索结果多、作者依然在更新、社区活跃,就可以继续。
我认为splicer
并不符合这个条件,所以我选择去看ffmpeg
。
ffmpeg
直接搜索ffmpeg
,然后进入官网,看第一句话:
A complete, cross-platform solution to record, convert and stream audio and video.
完整的跨平台解决方案,用于记录,转换和流式传输音频和视频。
这正是我们想要的!
但我该如何在C#中使用它呢?可以看看官网有没有例子,如果觉得懒得翻,可以搜索C# ffmpeg
,对不对?(其实也可以倒回去看上面两个链接是怎么用的)
这里搜索一下C# ffmpeg
,可以找到中文的、英文的,很好的教程了。
总结了一下搜索结果,有两种选择:
1、直接通过命令行使用ffmpeg
2、使用基于ffmpeg开发的C#开发库
这里两种方式都可以,如果对ffmpeg底层比较感兴趣,可以选择第一种,如果想快速实现,一般来说第二种更快。第二种选择,根据选择的开发库不同,学习成本、使用结果和效率也会不同。
我选择第一种方式。
简单测试
我们现在找到了一个可以达成目标的工具ffmpeg
,也通过搜索和阅读了解了一些它的使用方式,现在应该写代码了么?对于这个问题来说,不是。
现在最重要的还是通过简单
、快速
的方式确定ffmpeg可以达成目标。
根据博客我们知道,ffmpeg
是通过运行ffmpeg.exe
来执行操作的,ffmpeg.exe
可以在官网下载最新版或者稳定版;
根据官方资料concat命令中关于合并文件的指令,我们知道了怎么写命令。
所以我手动编辑了一个批处理文件test.bat
,命令是:
ffmpeg -f concat -i merge.txt -c copy output.mp4
然后编写了merge.txt
的内容
file 20210423_195727.mp4
file 20210423_195743.mp4
然后把下载的ffmpeg.exe
放到当前目录(当然也可以选择把ffmpeg.exe加入环境变量,但是这里没必要)。
然后执行test.bat
。
cmd显示执行成功,当前目录顺利输出output.mp4
。打开output.mp4,视频正确播放。
我们确定了ffmpeg
可以完成目标,接下来就是去把上述手动的过程,改成自动化了。
基于目标完成开发
根据上面的测试,我整理出来我需要以下步骤:
1.生成包含了视频列表的txt文件
这里我需要遍历下面这些文件夹,把里面的.mp4
文件写入txt中,并且按照我的需求,分小时录入,所以最后会生成300+个txt文件。
2021050811
2021050812
2021050813
.....
2.生成批处理.bat文件
类似1,会生成300+个.bat文件。
3.使用C#执行bat文件
C#执行bat文件是很简单的基础功能(如果不知道也可以继续搜索)。
因为执行文件有300+个,所以手动执行是不可能的,还是得遍历bat文件执行。
根据这样的思路,剩下的就是简单的板砖工作了。
实际运行的问题
本来我是打算把批处理文件全部一次性运行的,结果理想和现实的差距有点大(大雾)。
测试的视频文件是很小的,两个加起来只有十几秒,所以合并操作很快,也并不费电脑(>ω・* )ノ
但是我实际需要合并的视频,每次有60个,总大小在700M左右,是一个耗时操作,而且根据我电脑的配置,一次性开3个合并任务,CPU就跑满了。
所以这里需要把3.使用C#执行bat文件的思路改一下,改成先检查现在有几个任务在跑,不满3个,就启动1个,做个定时器。
总结
总的来说,这项工作有两个大的部分的内容:
1.以最小的资源付出,最快的速度找到核心问题的解决方案,即自动合并视频;
2.将合并视频技术和自己的技术栈结合起来使用,以达到自动化的目的。