FFmpeg+Video.js+Videojs-contrib-hls实现视频点播解决方案
视频点播解决方案
1、 播放器通过 http协议从http服务器上下载视频文件进行播放
问题:必须等到视频下载完才可以播放,不支持快进到某个时间点进行播放
2、 播放器通过rtmp协议连接媒体服务器以实时流方式播放视频
使用rtmp协议需要架设媒体服务器,造价高,对于直播多采用此方案。
3、 播放器使用HLS协议连接http服务器(Nginx、Apache等)实现近实时流方式播放视频
HLS协议规定:基于Http协议,视频封装格式为ts,视频的编码格式为H264,音频编码格式为MP3、AAC或者AC-3。
HLS
HLS的工作方式是:
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与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/;
}
}
准备
测试
分断请求
流媒体相关概念
流媒体特征
(1)内容主要是时间上连续的媒体数据(音频、视频、动画、多媒体等)。
(2)内容可以不经过转换就采用流式传输技术传输。
(3)具有较强的实时性,交互性。
(4)启动延时大幅度缩短,缩短了用户的等待时间;用户不用等到所有内容都下载到硬盘上才能开始浏览,在经过一段启动延时后就能开始观看。
(5)对系统缓存容量的要求大大降低。
流式传输方式
顺序流式传输
实时流式传输
流媒体传输的网络协议
实时传输协议RTP
实时传输控制协议RTCP
实时流协议RTSP
文件格式
在运用流媒体技术时,音视频文件要采用相应的格式,不同格式的文件需要用不同的播放器软件来播放。采用流媒体技术的音视频文件主要有以下几种:
系统组成
(1)编码工具:用于创建、捕捉和编辑多媒体数据,形成流媒体格式。
(2)流媒体数据。
(3)服务器:存放和控制流媒体的数据。
(4)网络:适合多媒体传输协议甚至是实时传输协议的网络
(5)播放器:供客户端浏览流媒体文件。