Loading... ## FFmpeg `FFmpeg` 是视频处理最常用的开源软件。它功能强大,用途广泛,大量用于视频网站和商业软件,也是许多音频和视频格式的标准编码/解码实现。 什么?! 你还没安装,可以根据 [官方文档](https://www.ffmpeg.org/download.html) 先完成安装。 然后把目录下的`bin`文件夹加到系统环境变量。然后`CMD`输入` ffmpeg`可以看见版本信息就说明好了   ## 基本概念 ### 1 .容器 视频文件本身其实是一个容器`(container)`,里面包括了视频和音频,也可能有字幕等其他内容。 常见的容器格式有以下几种。一般来说,视频文件的后缀名反映了它的容器格式。 - MP4 - MKV - WebM - AVI **查看 FFmpeg 支持的容器** ``` $ ffmpeg -formats ``` ### 2 .编码格式 视频和音频都需要经过编码,才能保存成文件。不同的编码格式`(CODEC)`,有不同的压缩率,会导致文件大小和清晰度的差异。 **常用的视频编码** - H.262 - H.264 - H.265 **上面的编码格式都是有版权的,但是可以免费使用。此外,还有几种无版权的视频编码格式** - VP8 - VP9 - AV1 **常用的音频编码** - MP3 - AAC 上面所有这些都是有损的编码格式,编码后会损失一些细节,以换取压缩后较小的文件体积。无损的编码格式压缩出来的文件体积较大,这里就不介绍了,可以查看 FFmpeg 支持的编码格式,视频编码和音频编码 ``` $ ffmpeg -codecs ``` ### 3 .编码器 编码器`(encoders)`是实现某种编码格式的库文件。只有安装了某种格式的编码器,才能实现该格式视频/音频的编码和解码。 **这是一些 FFmpeg 内置的视频编码器** - libx264:最流行的开源 H.264 编码器 - NVENC:基于 NVIDIA GPU 的 H.264 编码器 - libx265:开源的 HEVC 编码器 - libvpx:谷歌的 VP8 和 VP9 编码器 - libaom:AV1 编码器 **音频编码器如下** - libfdk-aac - aac **查看 FFmpeg 已安装的编码器** ``` $ ffmpeg -encoders ``` ## 参数 ``` $ ffmpeg {1} {2} -i {3} {4} {5} ``` **上面命令中,五个部分的参数依次如下** **1**. 全局参数 **2**. 输入文件参数 **3**. 输入文件 **4**. 输出文件参数 **5**. 输出文件 **参数太多的时候,为了便于查看,ffmpeg 命令可以写成多行** ``` $ ffmpeg \ [全局参数] \ [输入文件参数] \ -i [输入文件] \ [输出文件参数] \ [输出文件] ``` **例子** ``` $ ffmpeg \ -y \ # 全局参数 -c:a libfdk_aac -c:v libx264 \ # 输入文件参数 -i input.mp4 \ # 输入文件 -c:v libvpx-vp9 -c:a libvorbis \ # 输出文件参数 output.webm # 输出文件 ``` 上面的命令将 `mp4 `文件转成` webm `文件,这两个都是容器格式。输入的`mp4 `文件的音频编码格式是` aac`,视频编码格式是` H.264`;输出的 `webm` 文件的视频编码格式是 `VP9`,音频格式是 `Vorbis` 如果不指明编码格式,`FFmpeg `会自己判断输入文件的编码。 因此,上面的命令可以简单写成下面的样子 ``` $ ffmpeg -i input.avi output.mp4 ``` ## 实例 这是我最常用的,也是博客上视频使用的方式,把`MP4`切割成`TS`的切片,并生成`M3U8`索引,视频流`hls`和音频`ACC` ``` $ ffmpeg -i mp4\22.mp4 -c:v libx264 -hls_time 10 -hls_list_size 0 -c:a aac -threads 5 -preset ultrafast -strict -2 -f hls ia223\itgsa.m3u8 ``` **命令说明**: - -i 源视频绝对路径 - -c 视频流和没一片的时间 time这里 8,表示每片8秒时长 - -threads 5 -preset 使用多线程,如果你的设备好,可以多开几个 - acc 音频 - strict -2 -f hls 存放的绝对路径 - .m3u8 输入的文件名,不要写数字,顺序容易出错 **注:使用多线程切出来的积极较大,几乎会增加一半的体积,看个人需要,下面是使用默认线程切割** ``` $ ffmpeg -i mp4\33.mp4 -c:v libx264 -hls_time 8 -hls_list_size 0 -c:a aac -strict -2 -f hls ia223\itgsa.m3u8 ``` **开始切割**  **完成之后是这样子的,第一个是索引文件**  ## 转码 ``` $ ffmpeg -i out.ogv -vcodec h264 out.mp4 $ ffmpeg -i out.ogv -vcodec mpeg4 out.mp4 $ ffmpeg -i out.ogv -vcodec libxvid out.mp4 $ ffmpeg -i out.mp4 -vcodec wmv1 out.wmv $ ffmpeg -i out.mp4 -vcodec wmv2 out.wmv ``` `-i `后面是输入文件名,`-vcodec `后面是编码格式,`h264 `最佳,但 `Windows` 系统默认不安装,如果是要插入` ppt `的视频,选择 `wmv1 或 wmv2` 基本上万无一失。 **附加选项** - -r 指定帧率 - -s 指定分辨率 - -b 指定比特率 **于此同时可以对声道进行转码** - -acodec 指定音频编码 - -ab 指定音频比特率 - -ac 指定声道数 **例** ``` $ ffmpeg -i out.ogv -s 640x480 -b 500k -vcodec h264 -r 29.97 -acodec libfaac -ab 48k -ac 2 out.mp4 ``` ## 剪切 **用 `-ss `和` -t `选项, 从第` 30 `秒开始,向后截取` 10` 秒的视频,并保存** ``` $ ffmpeg -i input.wmv -ss 00:00:30.0 -c copy -t 00:00:10.0 output.wmv $ ffmpeg -i input.wmv -ss 30 -c copy -t 10 output.wmv ``` **达成相同效果,也可以用` -ss `和 `-to` 选项, 从第` 30 `秒截取到第` 40` 秒** ``` $ ffmpeg -i input.wmv -ss 30 -c copy -to 40 output.wmv ``` 值得注意的是,`ffmpeg` 为了加速,会使用关键帧技术, 所以有时剪切出来的结果在起止时间上未必准确。 通常来说,把 `-ss `选项放在 `-i `之前,会使用关键帧技术; 把 `-ss `选项放在 `-i `之后,则不使用关键帧技术。 如果要使用关键帧技术又要保留时间戳,可以加上 `-copyts` 选项 ``` $ ffmpeg -ss 00:01:00 -i video.mp4 -to 00:02:00 -c copy -copyts cut.mp4 ``` ## 合并 **把两个视频文件合并成一个,简单地使用` concat demuxer`** ``` $ cat mylist.txt file '/path/to/file1' file '/path/to/file2' file '/path/to/file3' $ ffmpeg -f concat -i mylist.txt -c copy output ``` **更多时候,由于输入文件的多样性,需要转成中间格式再合成** ``` ffmpeg -i input1.avi -qscale:v 1 intermediate1.mpg ffmpeg -i input2.avi -qscale:v 1 intermediate2.mpg cat intermediate1.mpg intermediate2.mpg > intermediate_all.mpg ffmpeg -i intermediate_all.mpg -qscale:v 2 output.avi ``` ## GPU `ffmpeg`默认使用`CPU`跑的,`CPU`跑这种任务性能自然就不必多说了,电脑一般的,直接爆炸,或者根本跑不动,好在`ffmpeg`是支持`GPU`的,`GPU`虽然速度快,但是质量不高,处理后的视频体积较大。而我主要是优化视频体积和质量的,因此在生产环境中我几乎没有用过`GPU`进行加速,只是在测试时用了下。**`AMD`显卡请直接放弃,不用折腾了,我已经折腾过了 <img src="https://www.itggg.cn/usr/themes/handsome/assets/img/emotion/aru/blood2.png" class="emotion-aru"> 吐血经历只有自己知道** **1、首先要先安装显卡驱动CUDA** `CUDA`是`Nvidia`出的一个`GPU`计算库,让程序可以驱动`Nvidia`显卡的`GPU`进行各种工作,其中就包含了视频的编解码,怎么安装请自行百度下,内容太多,又可以写两篇文章了,这里就不赘述了。 **2、查询使用的ffmpeg版本是否支持 CUDA,小站网盘提供的下载版本是支持的,在ZIP里,自己下载** ``` $ ffmpeg -hwaccels ```  **3、测试下** **参数** - -hwaccel cuvid:指定使用cuvid硬件加速 ``` $ ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 0.mp4 -c:v h264_nvenc -y 00.mp4 1 ``` **将当前目录下的0.mp4转成00.mp4** ``` $ ffmpeg -hwaccel cuvid -c:v h264_cuvid -i 0.mp4 -c:v h264_nvenc -r 15 -b 500k -y 00.mp4 ``` ## 个人站长视频解决方案 说实话,对于个人博客上放视频,有点难搞,涉及到两个最大的问题,第一无非就是流量和存储环境的问题,第二还有速度的问题,一个视频几百M,放几次流量就去没了几个G。视频储存是很多人的一个难题,如果自己买个服务器又需要带宽有需要硬盘够大,如果你服务器牛逼,放自己服务器也可以,那么这个方案就不用看了。小白请直接劝退,这部分内容不写教怎么一步一步做,而是解决思路和方法。 对于个人站长来说流量和存储两部分的费用一般人是玩不起的,反正我是玩不起。其次速度也很重要,不然放出来卡的鸭皮,谁TM看啊。放5秒 卡1秒,看的人直接心态爆炸,看尼玛 <img src="https://www.itggg.cn/usr/themes/handsome/assets/img/emotion/aru/knife.png" class="emotion-aru"> 这个方案也是目前我在使用的方案,在经历,从播放器,到视频格式,到兼容设备,到云存储,到播放效果几个环节的折腾,终于得出非常低成本,低维护,却高效的方案,我另一个音乐站`(blog.itggg.cn)`放了几十个视频上去,播放一点也不卡,进度条随便拖,几百个人同时看都可以,苹果,安卓,PC,都可以完美支持。 **1、播放器的选择**:我用的是 `DPlayer`,这个播放器非常好用,支持`HLS,MP4,flv,mkv`等众多格式的播放,在设备的兼容性也非常好,无论是移动端,还是苹果,PC,安卓都兼容。也很轻量化,我用了这么久是没发现任何问题的,并且是开源的。 [项目地址][1] **2、视频流的选择**:目前我的是使用`hls`的视频流,然后把视频进行切片处理,并生成`m3u8`索引,且`m3u8`也是目前主流的视频方案,许多大厂除了自己研发格式外,或者搞直播的,基本都是采用的这种方案。`hls`支持的设备很完全,其次是`MP4`的格式。`mkv和flv`等格式大部分都在苹果设备上都不支持的,第二就是视频源要进行`TS`切片,每片的大小约`2M`左右就好,这样利于加载速度和节约流量,再搭配一个好的存储环境基本可以做到秒开。 ### m3u8 与 MP4 对比 **对m3u8 与MP4 做一个简单对比** - `MP4` 对`HTML5`和`flash`播放器亲和度都挺好。但是文件头太大,需要加载完成才能播放,其次结构复杂,长视频的大文件头影响加载速度的视频体验,所以`MP4`在短视频的应用更常见 - `m3u8` 采用苹果的`HLS`协议,目前 `ios`与`android`设备均已支持。由于其工作原因是将整个视频流分成一个个小的基于`Http`的文件进行下载播放,因此支持视频直播,和视频加速播放。 **简单的来说就是,体积不大的视频用MP4更好,体积超过100M的视频用m3u8更好,更多信息可以自己百度下** **播放对比**,这个`MP4`源视频体积约`300M`,切片后总约大小`200M` <div class="tip inlineBlock info"> **MP4播放** </div> <iframe src="https://v.itggg.cn/?url=https://bos.itggg.cn/hls/va11/v1.mp4" allowfullscreen="allowfullscreen" mozallowfullscreen="mozallowfullscreen" msallowfullscreen="msallowfullscreen" oallowfullscreen="oallowfullscreen" webkitallowfullscreen="webkitallowfullscreen" width="100%" height="500px" frameborder="0"></iframe> *** <div class="tip inlineBlock success"> **M3U8播放** </div> <iframe src="https://v.itggg.cn/?url=https://bos.itggg.cn/hls/va11/vas.m3u8" allowfullscreen="allowfullscreen" mozallowfullscreen="mozallowfullscreen" msallowfullscreen="msallowfullscreen" oallowfullscreen="oallowfullscreen" webkitallowfullscreen="webkitallowfullscreen" width="100%" height="500px" frameborder="0"></iframe> **3、视频存储的选择**: **3.1**.稳定很重要,不要把视频传上去后,过不久就丢了,那你幸幸苦苦搞得全白费了。 **3.2**.速度要快,有钱的可以选择云厂商的对象存储,买个流量套餐包,体积在5G以内的视频基本上50块就就搞定,配上`m3u8`可以最大程度上节约流量。没钱的可以选择一些免费的图床啊啥的,比如github,npm这些。 还有一种非常快且安全的方法是,把你的站接入百度云加速,视频都放在服务器上,然后在百度云加速上面的 “**特定页面规则**” 去缓存目录里所有的`TS`切片,这样你服务器目录下的`TS`切片就全部缓存在百度云的节点上面了,百度云的节点有多快就不必多说了。 前两种免费的方法都有限制,`gitbuh`上传切片麻烦,且单一文件最大`20M`。百度云节点的缓存命中率也不是特别高,且免费流量每天`10G`,视频不多的可以考虑。想完全白嫖几乎不太可能,如果你真的做到了,请留言分享下好吗,我在这里先谢谢您了 我的存储是放在世纪互联的`OneDrive`上的,就完全不考虑流量和并发的问题,只是处理视频的时候麻烦点而已 **3.3**.视频源需要固定的直链,这个非常重要。 **需要注意一点**,使用`m3u8`做索引的时候,存储源一定要允许跨域请求,不然有时候会出现无法播放,或者播放一半就播放不了的情况。 <div class="tip inlineBlock info"> **最后,这个方案也是我折腾了很久才搞出来的屌丝站长视频播放终极解决方案,希望对你有帮助,请我喝杯奶茶也可以,谢谢您,谢谢您全家** </div> [1]: https://github.com/MoePlayer/DPlayer Last modification:December 22nd, 2020 at 08:53 pm © 禁止转载 Support 如果你想请我喝奶茶的话 ×Close Appreciate the author Sweeping payments Pay by AliPay Pay by WeChat
博主,我想问下本地切片后上传世纪互联,然后引用OneIndex的链接可以吗?
可以是可以,但是有个问题,OneIndex的连接不是固定的,是解析出来的,我之前采用的这个方案是写了一个脚本定时去解析,然后更改文章里的链接实现的。
额...那有没有什么办法能获取固定的直链呢
世纪互联版的可以,如果你视频不多,可以切片好打包发给我帮你存。
我视频挺多的...总不能每次都麻烦你吧 。要是可以的话告诉我怎么做就最好了
当然要是不方便的话也没关系 
不是不方便,脚本定时去解析这个方案我已经弃用了,用世纪互联的OneIndex,开放API权限,可以获取直连。可以自己百度下,篇幅较长。
好的,谢啦
我的怎么报错呀
osss设置了跨域 而且在放在本机都播放失败
报的什么错? 有没有地址或者截图看一下
截图有点麻烦 你进我博客
就是加载失败
dplayer插件开启了HLS支持
三个问题:
第一:视频源地址不要加中文,在解码的时候可能有某种未知的问题
第二:视频源放在服务器上,需要FTP的访问,你如果用的是nginx的话,可能是无法播放的,nginx不能做这中反向请求到服务器里的,
第三:跨域了,配置下CORS跨域请求
OK 我在帮你看 你加我QQ吧 546960041
哈哈,想不想试试搞视频
想哦!
那就开搞
请你喝奶茶