windows下使用FFMpeg转码视频并于VLC网络流上播放

引言

FFmpeg是一个开源免费跨平台的视频和音频流方案,它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行。

M3U8视频格式也是一种M3U,只是它的编码格式是UTF-8格式。M3U用Latin-1字符集编码。M3U8格式特点是带有一个目录信息或文件。它与mp4格式的区别在于,当用户打开一个视频播放的时候,浏览器会持续请求下载mp4文件直到下载完成,就算是用户暂停视频播放浏览器也会持续这种下载状态,如果这个视频文件是500M则会请求服务器下载500M文件,是1G则会不停下载1G,给服务器硬盘和宽带造成很大浪费和压力。所以m3u8格式的好处在于还可以实现流加密(视频文件本身加密)、分段下载播放、任意时间点拖拽播放、随机视频文件广告插入等等优势。

ffmpeg的安装

我们可以进入这个软件的官网,它有相应的资源可供直接下载,这里我用的是windows版本的:

https://ffmpeg.zeranoe.com/builds/

下载完成后我们可以直接解压这个软件包,而这个是和java一样,需要添加环境变量,所以我们最好是放C盘里面,比较好管理。下面是安装步骤:

首先我们直接将解压好的文件夹放到C盘:
windows下使用FFMpeg转码视频并于VLC网络流上播放

然后我们就可以直接添加环境变量了,一般我们只需要添加bin环境就行,然后我们就可以在cmd中查看它的相关信息了:
windows下使用FFMpeg转码视频并于VLC网络流上播放
所以我们打开cmd,输入ffmpeg命令,以及ffmpeg -version:
windows下使用FFMpeg转码视频并于VLC网络流上播放
windows下使用FFMpeg转码视频并于VLC网络流上播放
这两个都有显示,那么就说明安装成功。

ffmpeg命令介绍

我们可以在我们需要剪辑的视频目录下,打开powershell,然后我们就可以使用命令对其进行解压,ffmpeg的一些比较基本的命令我总结如下:

我们可以做出表格,表格是由参考与推荐中的第一篇整理了一小部分,因为我就了解了那么多,并尝试了一下,另外参考里的第四篇做出了比我更详细的表,我在这里mark一下。(做表做到途中看到已经有人总结好了,那我就不总结了。。)

参数 说明
-vcodec codec 强制使用codec编解码方式(‘copy’ to copy stream)
-newvideo 在现在的视频流后面加入新的视频流
-s 320x240 指定分辨率
-ac <数值> 设定声道数,1就是单声道,2就是立体声
-ar <采样率> 设定声音采样率,PSP只认24000
-vol <百分比> 设定音量
-y 覆盖输出文件
-b <比特率> 指定压缩比特
-r fps 设置帧频 缺省25
-y 覆盖输出文件
-b <比特率> 指定压缩比特
-r fps 设置帧频 缺省25

一些基本的命令如下:

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

ffmpeg的使用

ffmpeg的使用基本和命令行的使用基本一致,如果我们熟悉linux的操作,那么很容易就能比较好的上手ffmpeg,而其实本篇的目的在于将mp4格式的文件分解成多个ts文件和一个m3u8文件。这在我了解的概念里是叫点播,而直播的代码我也试了一下,以下分别介绍:

  • 点播就是将一个媒体文件切分成多个TS文件,并且m3u8文件包含全部的TS文件列表。
  • 直播则列表长度上会有所控制,也就是一般会比较短,并且为了减少延迟,可能会将每个分片的时长控制低于10秒,而点播应该都会直接使用10秒这个默认值吧。
  • 点播的m3u8是死的,也就是一旦分片完成后,一般不会再去修改m3u8文件(内容)。而直播的m3u8文件(内容)则会根据直播的时间进行更新。

点播:

先来介绍点播,点播的第一个特点就是速度快:

ffmpeg -i input.mp4 -codec copy -vbsf h264_mp4toannexb -map 0 -f segment -segment_list out.m3u8 -segment_time 10 out%03d.ts

首先对于前面的两个参数,我们比较清楚,-codec是表示编码格式,segment就是切片,segment_list是以列表的形式输出,segment_time表示10秒的间隔。而唯一有些不解的就是-vbsf h264_mp4toannexb是什么意思。

这个我是参考的使用FFMpeg将MP4转为m3u8

这个问题在用ffmpeg从mp4里提取码流的时候(命令:ffmpeg -i foo.mp4 -vcodec copy -an foo.h264)也会碰到,生成的264文件无法播放,码流走中并没有00 00 00 01来分隔每一帧,这是因为默认是使用length prefixed mode,而不是以00 00 00 01起始码作为prefixed,也就是说没使用start code prefixed mode.

不太清楚是不是必须,但我后来看了其它的博文感觉是有其它方式去替代的,但也没有深究了,那么运行上面那段程序的结果如下:
windows下使用FFMpeg转码视频并于VLC网络流上播放
我们会发现运行的时间很快,基本上差不多几秒以内就完成了转码。视频如下:
windows下使用FFMpeg转码视频并于VLC网络流上播放

直播:
直播的速度就非常慢了,获取考虑了原视频的相关变动,我们可以从powershell中清晰的看到每一个视频的转码流程,以下是程序,参考自使用FFmpeg生成HLS

ffmpeg -i input.mp4 -codec:v libx264 -codec:a mp3 -map 0 -f ssegment -segment_format mpegts -segment_list playlist.m3u8 -segment_time 10 out%03d.ts

与点播的区别就是在加了-segment_list_flags +live以示直播,并且加上了-re参数(不加这个参数,一下子就切片过去,客户端还来不及播放,列表已经被更新了,该参数表示ffmpeg将会按照source.mp4的播放速率进行转码)。带上segment_list_size参数对列表数量进行控制在6个。但是目前的话,ssegment模块有个缺点,虽然可以通过以上方式达到直播,但是生成的TS文件并不会循环,会一直被保留(当然如果要顺带将内容录制下来,这反倒是一个优点,只能说其实现的还是切片的功能,并非纯粹的直播)。这时候,HLS模块就可以更好的胜任直播功能了(能独立成模块,相对术业有专攻吧!)。HLS模块实现于libavformat/hlsenc.c libavformat/hls.c 以及 libavformat/hlsproto.c

windows下使用FFMpeg转码视频并于VLC网络流上播放
差不多等了有两三分钟吧,和点播的十秒左右区别略大,但我发现比较有趣的一个地方是直播确实能称得上自适应切割了,点播方式全部都以10秒为界限,而直播的方式不定,有9秒的,也有14秒的,所以最后视频比点播少了两个:
windows下使用FFMpeg转码视频并于VLC网络流上播放

.m3u8文件播放

我这里是用阿里云服务器的Nginx,我之前有篇部署的文章详细介绍了Nginx,这里就不再过多说明了。

首先我们查看Nginx是否支持相应的视频文件,我这里的位置是/www/server/nginx/conf/下,进入阿里云是有的,不过我之前自己的Ubuntu好像没有,找到mime.types然后用vim进入:
windows下使用FFMpeg转码视频并于VLC网络流上播放
这里显示支持该格式文件,如果没有的话在相应的配置下加上这两个:

application/x-mpegURL   m3u8;
video/MP2T              ts;

然后将我们上面的视频上传至/Nginx/html下,我这里新创建了一个文件夹first,然后将视频传上去:
windows下使用FFMpeg转码视频并于VLC网络流上播放
至此配置完成了,那么我们就可以打开VLC播放器播放了,只需要用其打开out.m3u8,如果用编辑器打开这个文件就会发现它里面相当于索引,ts文件会自动播放:
windows下使用FFMpeg转码视频并于VLC网络流上播放
因为我是上传的云服务器,我上述视频目前还没有删,如果想测试的,都能直接输入上述地址,如果没有用,表示我已经删了:
windows下使用FFMpeg转码视频并于VLC网络流上播放

总结

本篇的测试视频我是拿的b站上的一个mad,想看完整版的可以进我的个人博客 https://www.xuzhenggen.com/ 在首页的右下角点播放就能直接看了,我当初本来是想用m3u8代替mp4的,但我视频本来就只有37M,两个都测试过后我发现速度没差别,另外还考虑了一些cdn加速的问题,我就省得麻烦了。
windows下使用FFMpeg转码视频并于VLC网络流上播放



参考与推荐:
[1]. FFmpeg常用命令及参数
[2]. 苹果http视频点播技术
[3]. ffmpeg转码视频真的好用!(ffmpeg的简单使用方法)
[4]. ffmpeg常用参数一览表
[5]. 使用FFmpeg生成HLS