FFmpeg+Video.js+Videojs-contrib-hls实现视频点播解决方案

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 FFmpeg+Video.js+Videojs-contrib-hls实现视频点播解决方案,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

视频点播解决方案

1、 播放器通过 http协议从http服务器上下载视频文件进行播放

问题:必须等到视频下载完才可以播放,不支持快进到某个时间点进行播放

2、 播放器通过rtmp协议连接媒体服务器以实时流方式播放视频

使用rtmp协议需要架设媒体服务器,造价高,对于直播多采用此方案。

3、 播放器使用HLS协议连接http服务器(Nginx、Apache等)实现近实时流方式播放视频

HLS协议规定:基于Http协议,视频封装格式为ts,视频的编码格式为H264,音频编码格式为MP3、AAC或者AC-3。

HLS

HLS (HTTP Live Streaming)是Apple的动态码率自适应技术。主要用于PC和Apple终端的音视频服务。包括一个m3u(8)的索引文件,TS媒体分片文件和key加密串文件。

HLS的工作方式是:

将视频拆分成若干ts格式的小文件,通过m3u8格式的索引文件对这些ts小文件建立索引。一般10秒一个ts文件,播放器连接m3u8文件播放,当快进时通过m3u8即可找到对应的索引文件,并去下载对应的ts文件,从而实现快进、快退以近实时 的方式播放视频。

FFmpeg

FFmpeg是一个视频编码软件,使用FFmpeg就可以对视频进行编码 。

简单使用

如将一个.mp4文件转成avi、mp3、gif。

命令:

ffmpeg -i test.mp4 test.avi 

ffmpeg -i test.mp4 test.mp3

ffmpeg -i test.mp4 test.gif

在FFmpeg软件的bin目录下执行: ffmpeg -i test.mp4 test.avi

\ffmpeg\bin>ffmpeg -i test.mp4 test.avi

在这里插入图片描述

生成m3u8/ts文件

1.将avi视频转成mp4

ffmpeg.exe -i test.avi -c:v libx264 -s 1364x728 -pix_fmt yuv420p -b:a 63k -b:v 409k -r 18 .\test2.mp4
-c:v 视频编码为x264 ,x264编码是H264的一种开源编码格式。

-s 设置分辨率

-pix_fmt yuv420p:设置像素采样方式,主流的采样方式有三种,YUV4:4:4,YUV4:2:2,YUV4:2:0,它的作用是
根据采样方式来从码流中还原每个像素点的YUV(亮度信息与色彩信息)值。

-b 设置码率,-b:a和-b:v分别表示音频的码率和视频的码率,-b表示音频加视频的总码率。码率对一个视频质量有
很大的作用,后边会介绍。

-r:帧率,表示每秒更新图像画面的次数,通常大于24肉眼就没有连贯与停顿的感觉了。

将mp4生成m3u8

ffmpeg -i test.mp4 -hls_time 10 -hls_list_size 0 -hls_segment_filename ./video/test%05d.ts ./video/test.m3u8
-hls_time 设置每片的长度,单位为秒

-hls_list_size n: 保存的分片的数量,设置为0表示保存所有分片

-hls_segment_filename :段文件的名称,%05d表示5位数字

结果:将test.mp4视频文件每10秒生成一个ts文件,最后生成一个m3u8文件,m3u8文件是ts的索引文件。

在这里插入图片描述
使用VLC或者PotPlayer等软件可打开m3u8文件

码率的设置

码率又叫比特率即每秒传输的bit数,单位为bps(Bit Per Second),码率越大传送数据的速度越快。

码率的计算公式是:文件大小(转成bit)/ 时长(秒)/1024 = kbps 即每秒传输千位数

例如一个9M的视频,它的时长是180s,它的码率等于

1*1024*1024*8/10/1024 = 819Kbps

video.js

Video.js是一款开源播放器,基于HTML5的网络视频播放器,支持HTML5和Flash视频,支持在台式机和移动设备上播放视频。

下载video.js与videojs-contrib-hls

video.js
videojs-contrib-hls是播放hls的一个插件

常用属性与事件

vjs-big-play-centered 控制按钮居中显示
preload="auto" 预加载
poster=" " 设置封面图
ready 表示视频已就绪
currentTime() 当前时间
current(time) 设置当前播放时间
duration() 获取视频总时长
buffered() 视频已经缓冲了多
volume() 获取和设置声音
width()   height()  获取和设置视频的宽高

事件监听

muted : true/false 是否静音
controls: true/false 是否拥有控制条 【默认true】,如果设为false ,那么只能通过api进行控制
loop : true/false 视频播放结束后,是否循环播放
playbackRates: [0.5, 1, 1.5, 2]  倍速播放 1表示常速(100%),0.5表示半速(50%),2表示双速(200%)等。

属性与事件的使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>视频播放</title>
    <link rel="stylesheet" href="./video-js-7.10.2/video-js.css">
</head>
<body>
<video id="player" class="video-js vjs-big-play-centered"  data-setup="{}" width="960" height="400"
       preload="auto" poster="./picture.png">
    <source src="./test.mp4" type="video/mp4"></source>
</video>
<input type="button" onClick="play()" value="播放"/>
<input type="button" onClick="pause()" value="暂停"/>
<input type="button" onClick="dispose()" value="销毁"/>
<input type="button" onClick="currentTime()" value="从88秒处播放"/>
<input type="button" onClick="getCurrentTime()" value="获取当前播放进度"/>
<input type="button" onClick="duration()" value="获取视频时间总长度"/>
<input type="button" onClick="volume()" value="获取声音"/>
<input type="button" onClick="setVolume()" value="设置声音"/>
<input type="button" onClick="widthAndHeight()" value="获取宽高"/>
<input type="button" onClick="setWidthAndHeight()" value="设置宽高"/>


<script src="./video-js-7.10.2/video.js"></script>

<script>

    var player = videojs("player",{
        //muted : true/false 是否静音
        muted:false,
        //controls: true/false 是否拥有控制条 【默认true】,如果设为false ,那么只能通过api进行控制
        controls:true,
       //loop : true/false 视频播放结束后,是否循环播放
        loop:true,
        //倍速播放 1表示常速(100%),0.5表示半速(50%),2表示双速(200%)等。允许用户从选择数组中选择播放速度。选项以从下到上的指定顺序显示。
        playbackRates: [0.5, 1, 1.5, 2],
    });
    console.log(player);


    player.ready(function () {
        console.log("初始化完成");
        //缓冲
        console.log(this.buffered());
    });


    function currentTime() {
        console.log("从88秒处开始播放")
        player.currentTime(88);
    }

    function getCurrentTime() {
        console.log("获取当前播放进度")
        console.log(player.currentTime());
    }

    function dispose() {
        console.log("销毁")
        player.dispose()
    }

    function duration() {
        console.log("获取视频时间总长度")
        console.log(player.duration());
    }

    function volume() {
        console.log("获取声音")
        console.log(player.volume());
    }

    function setVolume() {
        console.log("设置声音")
        player.volume(0.5);
        console.log(player.volume());
    }

    function widthAndHeight() {
        console.log("获取宽高")
        console.log(player.width());
        console.log(player.height());
    }

    function setWidthAndHeight() {
        console.log("设置宽高")
        player.width(300);
        player.height(200);
        console.log(player.width());
        console.log(player.height());
    }

    //点击播放
    function play() {
        console.log("点击播放");
        player.play();
    }

    //监听播放
    player.on("play", function () {
        console.log("监听播放");
    })

    //点击暂停
    function pause() {
        console.log("点击暂停");
        player.pause();
    }

    player.on("pause", function () {
        console.log("监听暂停");
    })


    //监听视频播放状态
    player.on("timeupdate", function () {
        console.log("监听视频播放状态");
    })

    //监听视频播放结束
    player.on("ended", function () {
        console.log("监听视频播放结束");
    })

    //监听视频跳转结束
    player.on("seeked", function () {
        console.log("监听视频跳转结束");
    })

    //监听视频跳转结束
    player.on("seeked", function () {
        console.log("监听视频跳转结束");
    })

</script>
</body>
</html>

在这里插入图片描述

在这里插入图片描述

视频点播方案的实现

页面HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>视频播放</title>
    <link rel="stylesheet" href="http://127.0.0.1:8888/video-js-7.10.2/video-js.css">
</head>
<body>
<video id="player" class="video-js vjs-big-play-centered"  data-setup="{}" width="960" height="400"
       preload="auto" poster="http://127.0.0.1:8888/picture.png">
    <!-- <source src="http://127.0.0.1:8888/test.mp4" type="video/mp4"></source>-->
    <source src="http://127.0.0.1:8888/video/test.m3u8" type="application/x-mpegURL"></source>
</video>

<script src="http://127.0.0.1:8888/video-js-7.10.2/video.js"></script>

</body>
</html>

配置Nginx

利用Nginx访问视频资源

  server {
	listen   8888;
        server_name  localhost;
	location / {
	   alias   D:/test/;
        }
     }

准备

在这里插入图片描述

测试

在这里插入图片描述
分断请求
在这里插入图片描述

流媒体相关概念

流媒体(streaming media)是指将一连串的媒体数据压缩后,经过网上分段发送数据,在网上即时传输影音以供观赏的一种技术与过程,此技术使得数据包得以像流水一样发送;如果不使用此技术,就必须在使用前下载整个媒体文件。流式传输可传送现场影音或预存于服务器上的影片,当观看者在收看这些影音文件时,影音数据在送达观看者的计算机后立即由特定播放软件播放。

流媒体特征

(1)内容主要是时间上连续的媒体数据(音频、视频、动画、多媒体等)。

(2)内容可以不经过转换就采用流式传输技术传输。

(3)具有较强的实时性,交互性。

(4)启动延时大幅度缩短,缩短了用户的等待时间;用户不用等到所有内容都下载到硬盘上才能开始浏览,在经过一段启动延时后就能开始观看。

(5)对系统缓存容量的要求大大降低。

Internet是以包传输为基础进行的异步传输,数据被分解成许多包进行传输,由于每个包可能选择不同的路由,所以到达用户计算机的时间延迟就会不同,而在客户端就需要缓存系统来弥补延迟和抖动的影响以及保证数据包传输的顺序在流媒体文件的播放过程中,由于不再需要把所有的文件都下载到缓存,因此对缓存的要求很低。

流式传输方式

流媒体最主要的技术特征就是流式传输,它使得数据可以像流水一样传输。

流式传输是指通过网络传送媒体(音频、视频等)技术的总称。实现流式传输主要有两种方式:顺序流式传输( progressive streaming)和实时流式传输( real timestreaming)。采用哪种方式依赖于具体需求,下面就对这两种方式进行简要的介绍。

顺序流式传输

顺序流式传输是顺序下载,用户在观看在线媒体的同时下载文件,在这一过程中,用户只能观看下载完的部分,而不能直接观看未下载部分。也就是说,用户总是在一段延时后才能看到服务器传送过来的信息。由于标准的HTTP服务器就可以发送这种形式的文件,它经常被称为HTTP流式传输。

由于顺序流式传输能够较好地保证节目播放的质量,因此比较适合在网站上发布的、可供用户点播的、高质量的视频。

顺序流式文件是放在标准HTTP或FTP服务器上,易于管理,基本上与防火墙无关。顺序流式传输不适合长片段和有随机访问要求的视频,如:讲座、演说与演示。它也不支持现场广播。

实时流式传输

实时流式传输必须保证匹配连接带宽,使媒体可以被实时观看到。在观看过程中用户可以任意观看媒体前面或后面的内容,但在这种传输方式中,如果网络传输状况不理想,则收到的图像质量就会比较差实时流式传输需要特定服务器,如Quick Time Streaming Server、 Realserver或 Windows Media server。这些服务器允许对媒体发送进行更多级别的控制,因而系统设置、管理比标准HTTP服务器更复杂。实时流式传输还需要特殊网络协议,如:RTSP(realtime streaming protocol)或MMS(microsoft media server)。在有防火墙时,有时会对这些协议进行屏闭,导致用户不能看到一些地点的实时内容,实时流式传输总是实时传送,因此特别适合现场事件。

流媒体传输的网络协议

TCP需要较多的开销,故不太适合传输实时数据;流式传输一般采用HTTP/TCP(RTCP来传输控制信息,而用RTP/UDP(RTP)来传输实时声音数据。

实时传输协议RTP

实时传输协议RTP被定义为在一对一或一对多的传输情况下工作,其目的是提供时间信息和实现流同步;RTP通常使用UDP来传送数据;当应用程序开始一个RTP会话时将使用两个端口:一个给RTP,一个给RTCP。RTP本身并不能为按顺序传送数据包提供可靠的传送制,也不提供流量控制或拥塞控制,它依靠RTCP提供这些服务;通常RTP算法并不作为一个独立的网络层来实现,而是作为应用程序代码的一部分。

实时传输控制协议RTCP

实时传输控制协议RTCP和RTP一起提供流量控制和拥塞控制服务;在RTP会话期间各参与者周期性地传送RTCP包;RTCP包中含有已发送的数据包的数量、丢失的数据包数量等统计资料,因此,服务器可以利用这些信息动态地改变传输速率,甚至改变有效载荷类型。RTP和RTCP配合使用,它们能以有效的反馈和最小的开销使传输效率最佳化,因而特适合传送网上的实时数据。

实时流协议RTSP

实时流协议RTSP定义了一对多应用程序如何有效地通过IP网络传送多媒体数据;RTSE在体系结构上位于RTP和RTCP之上,它使用TCP或RTP完成数据传输;HTTP与RTSP相比,HTP传送HTML超链接文档,而RTSP传送的是多媒体数据;HTTP请求由客户机发出,册务器做出响应;使用RTSP时,客户机和服务器都可以发出请求,即RTSP可以是双向的。点对点的手机可视通话,必须在手机终端实现RTSP。

文件格式

在运用流媒体技术时,音视频文件要采用相应的格式,不同格式的文件需要用不同的播放器软件来播放。采用流媒体技术的音视频文件主要有以下几种:

①微软的ASF(advanced stream format)。这类文件的扩展名是.asf和.wmv,与它对应的播放器是微软公司的Media Player。用户可以将图形、声音和动画数据组合成一个ASF格式的文件,也可以将其他格式的视频和音频转换为ASF格式,而且用户还可以通过声卡和视频捕获卡将诸如麦克风、录像机等外设的数据保存为ASF格式。

②RealNetworks公司的ReaIMedia。它包括RealAudio、RealVideo和RealFlash三类文件,其中RealAudio用来传输接近CD音质的音频数据,RealVideo用来传输不间断的视频数据,RealFlash则是ReaINetworks公司与Macromedia公司联合推出的一种高压缩比的动画格式,这类文件的扩展名是.rm、.ra、.rmvb,文件对应的播放器是ReaIPlayer。

③苹果公司的QuickTime。这类文件扩展名通常是.mov,它所对应的播放器是QuickTime。
此外,MPEG、AVI、DVI、SWF等都是适用于流媒体技术的文件格式。

系统组成

流媒体系统包括以下方面的内容,这部分有些是服务器端需要的,有些是客户端需要的,不同的流媒体标准和不同公司的解决方案会在某些方面有所不同。

(1)编码工具:用于创建、捕捉和编辑多媒体数据,形成流媒体格式。

(2)流媒体数据。 

(3)服务器:存放和控制流媒体的数据。

(4)网络:适合多媒体传输协议甚至是实时传输协议的网络

(5)播放器:供客户端浏览流媒体文件。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/136993.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!