使用ffmpeg转码m3u8并播放

2019-02-15 10:35:31

简介

随着客户的增加,mp4文件播放的弊端也日益凸显,主要集中在两个方面


当视频时长比较长的时候,mp4的关键帧元素往往很大,需要加载很长时间才能开始播放,网速不好的情况缓冲加载就要20多秒的时间,客户早已急不可耐。

当用户打开一个视频播放的时候,浏览器会持续请求下载mp4文件直到下载完成,就算是用户暂停视频播放浏览器也会持续这种下载状态,如果这个视频文件是500M则会请求服务器下载500M文件,是1G则会不停下载1G,给服务器硬盘和宽带造成很大浪费和压力。

为了解决上述问题,公司打算使用m3u8格式来替代mp4格式。


m3u8是苹果公司开发的一项新型播放格式,这种播放格式支持目前市面的windows、androis、ios设备主流的浏览器,同样的视频文件既可以在flash环境播放,又能在无flash的html5环境播放,它的优势还不止于此,它可以实现多种码率在不同网速下的自动切换,网速好自动切换高清晰度视频,网速慢自动播放低清晰度文件,还可以实现流加密(视频文件本身加密)、分段下载播放、任意时间点拖拽播放、随机视频文件广告插入等等优势,所以公司打算是用m3u8格式作为视频格式。


mp4转码m3u8

如果视频不为mp4格式,需先将视频转码为mp4,可使用如下命令进行转换


ffmpeg -i 本地视频地址 -y -c:v libx264 -strict -2 转换视频.mp4

1

将mp4格式转换为ts格式


ffmpeg -y -i 本地视频.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb 转换视频.ts

1

将ts文件进行切片


ffmpeg -i 本地视频.ts -c copy -map 0 -f segment -segment_list 视频索引.m3u8 -segment_time 5 前缀-%03d.ts

1

其中segment 就是切片,-segment_time表示隔几秒进行切一个文件,上面命令是隔5s,你也可以调整成更大的参数。


转换好的文件




跨域问题

在跨域的网站根目录放crossdomain.xml文件,下面是允许所有的网站(一般不采取这样的方式,只是方便调试)均可以跨越访问资源配置如下:


<?xml version="1.0" encoding="utf-8"?>

<cross-domain-policy> 

    <allow-access-from domain="*"/>  

</cross-domain-policy> 

1

2

3

4

限制指定网站访问,可以参考百度https://www.baidu.com/crossdomain.xml配置


<cross-domain-policy>

    <allow-access-from domain="*.baidu.com"/>

    <allow-access-from domain="*.bdstatic.com"/>

    <allow-http-request-headers-from domain="*.baidu.com" headers="*"/>

    <allow-http-request-headers-from domain="*.bdstatic.com" headers="*"/>

</cross-domain-policy>

1

2

3

4

5

6

如果文件存储在第三方平台上,比如阿里云OSS,就把crossdomain.xml放在bucket根目录下


播放

这里推荐使用第三方h5播放器ckplayer,集成完成后看下视频请求




可以看到视频先加载的m3u8格式的索引文件,然后开始加载视频,跟据所以文件依次加载abc000.ts、abc001.ts、abc002.ts,这时候拖动视频,视频开始加载abc011.ts、abc012.ts、abc013.ts跳过了4~10的文件,这就是m3u8的好处,按需加载


  • 2018-08-07 20:00:42

    xUtils3.0版本的发送同步网络请求的方式

    对于Android开发来说,基本都是用异步来从网络上请求数据,很少用到同步请求的。近日项目有个地方需要使用到同步请求(以我目前的知识储备来说好像只能用同步请求来解决这个问题了),去网上搜索相关资料,又没有找到什么明确的使用方法。所以记下来,以备不时之需。

  • 2018-08-14 23:35:28

    Retrofit 设置 超时时间

    今天开发的时候遇到一个网络请求超时的问题,后台处理是成功的,但是移动端返回的总是提示请求超时,在设置了retrofit请求超时的时间延长以后,就可以请求成功了,下面是配置的方法:

  • 2018-08-16 16:10:43

    Laravel 跨域解决方案

    我们在用 laravel 进行开发的时候,特别是前后端完全分离的时候,由于前端项目运行在自己机器的指定端口(也可能是其他人的机器) , 例如 localhost:8000 , 而 laravel 程序又运行在另一个端口,这样就跨域了,而由于浏览器的同源策略,跨域请求是非法的。其实这个问题很好解决,只需要添加一个中间件就可以了。

  • 2018-08-18 20:30:12

    laravel5.5 路由分割成不同文件

    routes.php/api.php文件用来放置laravel路由,当项目越来越大,相应的路由文件也会越来越多。如果能够将不同功能的路由分割到不同的文件,那么对以后的维护将很有帮助。

  • 2018-08-20 15:26:19

    关于OnTouch 和OnClick同时调用冲突的解决方案

    大家在搞轮播图的时候会碰到这样的情况,点击进入webview界面,长按轮播图停止轮播,手松开图又开始轮播,这里就涉及到了OnTouch 和OnClick同时调用。两者是有冲突的。这里简单介绍,给大家提供思路。

  • 2018-08-20 15:29:11

    揭开RecyclerView的神秘面纱(二):处理RecyclerView的点击事件

    主要讲述了RecyclerView的基本使用方法,不同的布局管理器而造成的多样化展示方式,展示了数据之后,一般都会与用户进行交互,因此我们需要处理用户的点击事件。在ListView和GridView提供了onItemClickListener这个监听器,然而我们查找RecyclerView的API却没有类似的监听器,因此我们需要自己手动处理它的点击事件。 以下提供两种方法来实现处理RecyclerView点击事件的功能,以下代码均基于上一篇文章的代码做出修改。