视频类网站的基本实现
Linux
准备视频:m3u8,ts切片,ffmpeg
一、安装ffmpeg
参考:https://www.cnblogs.com/freeweb/p/6897907.html
cd /usr/local/src
wget https://ffmpeg.org/releases/ffmpeg-4.0.2.tar.bz2
tar -xjf ffmpeg-4.0.2.tar.bz2
如果报错多半是没安装bzip2
yum install -y bzip2
yum install gcc
安装yasm
wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
tar -xf yasm-1.3.0.tar.gz
cd yasm-1.3.0
./configure
make && make install
cd ../
cd ffmpeg-4.0.2
./configure --enable-shared --prefix=/monchickey/ffmpeg
make && make install
编译过程有点长,耐心等待完成之后执行 cd /monchickey/ffmpeg/ 进入安装目录,查看一下发现有bin,include,lib,share这4个目录,
其中bin是ffmpeg主程序二进制目录,include是C/C++头文件目录,lib是编译好的库文件目录,share是文档目录,然后进入bin目录,
执行 ./ffmpeg -version 查看当前版本的详细信息。默认情况下一般会报libavdevice.so.57: cannot open shared object file: No such file or directory,
原因是lib目录未加载到链接到系统库中,系统ld目录列表在/etc/ld.so.conf中,打开文件会发现,里面引用了/etc/ld.so.conf.d/下面所有的.conf文件,
比如mariadb-x86_64.conf我们只需要创建一个文件并写入lib路径即可,执行命令: vi /etc/ld.so.conf.d/ffmpeg.conf 然后
添加一行内容: /monchickey/ffmpeg/lib 之后保存并退出,然后执行 ldconfig 使配置生效,现在再次执行 ./ffmpeg -version 显示就正常了.
ffmpeg version 4.0.2 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-28)
configuration: --enable-shared --prefix=/monchickey/ffmpeg
libavutil 56. 14.100 / 56. 14.100
libavcodec 58. 18.100 / 58. 18.100
libavformat 58. 12.100 / 58. 12.100
libavdevice 58. 3.100 / 58. 3.100
libavfilter 7. 16.100 / 7. 16.100
libswscale 5. 1.100 / 5. 1.100
libswresample 3. 1.100 / 3. 1.100
将bin目录添加至环境变量
vi /etc/profile
添加
export PATH=$PATH:/monchickey/ffmpeg/bin
保存退出,source /etc/profile
于是,命令
ffmpeg -version
得到相同效果
到此 ffmpeg安装完毕
二、视频操作
cd /mydata/data/hls
ffmpeg 后面的参数的位置会影响效果。
1、查看视频时长:
ffmpeg -i movie.mp4 2>&1 | grep Duration
2、TS切片
ffmpeg -i movie.mp4 -f segment -segment_time 300 -segment_format mpegts -segment_list item/movie.m3u8 -c copy -bsf:v h264_mp4toannexb -map 0 item/movie-%d.ts
得到ts文件和m3u8文件
3、TS切片带加密
当然,ffmpeg可以生成加密的m3u8,
key_info需要替换成自己的路径,因为需要加密,所以需要准备二个文件一个是:key.key,一个是key_info。
当前目录 hls/
key值
openssl rand 16 > item2/key.key
IV值
openssl rand -hex 16 ( 生成一段字符串,记下来)
key.info格式:
key.key网络地址,供播放器解码用的
key.key本机绝对地址,供ffmpeg加密用的
iv值(可选)
key.info示例:
http://192.168.83.135/hls/item2/key.key
/mydata/data/hls/item2/key.key
eab014087ad9551b5baf459248d8fcd1
命令:
ffmpeg -i movie.mp4 -c copy -bsf:v h264_mp4toannexb -hls_time 300 -hls_list_size 0 -hls_key_info_file item2/key.info -hls_segment_filename 'item2/movie-%d.ts' item2/movie.m3u8
-use_localtime 1 使用当前时间
-use_localtime_mkdir 1 使用当前自动生成文件夹
-hls_segment_filename 'xxx' 文件名组装模式
加密后的m3u8在播放时和不加密一样,只是加密后即使ts文件被下载下来也无法单独播放。
4、截图
获取第一帧
ffmpeg -i movie.mp4 -vframes 1 -f image2 -y poster.jpg
-vframes n 截取几帧,如果n大于1,会有多张图片,则后面的图片名字应为 poster-%d.jpg,
-y 覆盖输出
-f 编码器
-i 输入
%d 整形数字
指定开始时间(秒)
ffmpeg -ss 00:02:01 -i movie.mp4 -vframes 1 -f image2 -y poster.jpg
-ss:截图的起始时间(秒,支持三位小数),00:00:10 或者 10 ,建议使用后者
规定图片的尺寸
ffmpeg -i movie.mp4 -vframes 1 -s 320*280 -f image2 -y poster.jpg
-s:图片尺寸
间隔截图制作进度条上的预览图片
ffmpeg -i movie.mp4 -ss 30 -t 60 -r 1 -s 50*30 -f image2 -y poster-%02d.jpg
-r:fps 设置帧频,就是一秒有多少帧,默认25
%02d:不足两位的前面补零
帧频设置为1,就是1秒只抽取一帧,也就是一张图片,此命令将会得到60张图片,由于在播放视频的时候精确到秒,所以1秒1个刚好,
后续将这些小图以网格的形式顺序排铺到一张大图上,这样当鼠标放在进度条上不同位置就能显示出当前时刻的预览小图了。
才发现ffmpeg具有连续截图并拼接的命令
连续截图:
ffmpeg -i movie.mp4 -y -t 120 -vf "fps=1,scale=iw/8:-1,tile=10x10" -an %d.jpg
fps=1/2:每2秒截一张图,如果是每秒截一张的话应该是fps=1
scale:所截图片大小,上面的代码是设置宽为原始的1/8大小,高度自动,相当于iw/8:ih/8,也可以设置成固定值如120:80
tile:网格化,自动将100张图合并成一张大图
如果不要-t,将会对整个视频来截图拼接
连续截图的另外一个方法:
ffmpeg -i movie.mp4 -vf fps=1 -q:v 2 -s 120x67 %d.jpg
这种方式截出来的是小图,需要自己再拼合。
截图生成gif
ffmpeg -i movie.mp4 -ss 50 -vframes 30 -f gif -y poster.gif
将生成的图片放在浏览器观看
其他参数:
-t:持续时间(秒,支持三位小数),和ss配合实现区间操作,要知道一秒可能有很多帧
优化:
为了缩小生成文件的大小,建议使用-s减小尺寸, -r参数参数来降低帧频。
-ss, -t放在-i前面要快很多,会直接跳到那个时间点
5、剪切视频
ffmpeg -ss 10 -t 70 -accurate_seek -i movie.mp4 -codec copy cut.mp4
将-ss, -t 参数放在-i参数之前,对输入文件执行seek操作,会seek到-ss设置的时间点前面的关键帧上。时间不精确,但是不会出现黑屏。
-accurate_seek 剪切时间更加精确,accurate_seek必须放在-i参数之前。
如果编码格式采用的copy 最好加上 -avoid_negative_ts 1参数:
ffmpeg -ss 10 -t 70 -accurate_seek -i movie.mp4 -codec copy -avoid_negative_ts 1 cut.mp4
下面的命令剪切的视频时长精确:
ffmpeg -accurate_seek -i movie.mp4 -ss 10 -t 70 -codec copy -avoid_negative_ts 1 cut.mp4
6、连接视频
7、转换格式
ffmpeg -i input.avi output.mp4
增加一些要求:
ffmpeg -threads 4 -i input.avi -ab 32 -flags +loop -vol 200 -vf yadif input.mp4
-ab:设置比特率
-vol:音量提高到200%
8、添加水印
9、将图片合成gif
ffmpeg -f image2 -framerate 5 -i D:\foo-%03d.jpeg D:\c.gif
10、屏幕录制
ffmpeg的屏幕录制功能只能在Linux环境下有效
11、视频采集
把摄像头的实时视频录制下来,存储为文件
php调用ffmpeg
exec('ffmpeg -i movie.mp4 -ss 30 -t 60 -r 1 -s 50*30 -f image2 -y poster-%02d.jpg', $re);
// $re 为进程返回的字符串,使用 preg_match来匹配返回串,以此来判断是否执行成功。
// 当然也可以配置 ffmpeg-php 扩展来完成,只是很麻烦。
预览图的拼接使用php自带的函数来完成。
三、测试切片成功与否
下载vlc播放器并安装:https://get.videolan.org/vlc/3.0.4/win64/vlc-3.0.4-win64.exe
打开播放器,选择‘媒体’,‘打开网络串流’,输入url(比如:http://192.168.83.135/hls/item/movie.m3u8),点击播放。
或者使用 PotPlayer软件播放,打开->打开链接,输入 http://192.168.10.200/item2/movie.m3u8
无论是加密的还是不加密的,都可以播放,因为m3u8中保存了key.key的网络地址和IV的值。
四、ckplayer网页播放器播放m3u8点播文件
实际上flash就可以播放m3u8了,我们使用ckplayer的m3u8.swf来播放m3u8。
将crossdomain.xml 放到 ts 文件所在的服务器的根目录(也可以是七牛云上你的域名对应的根目录里),设置成 *
一般ts文件都是放在云服务器上的,而m3u8是放在自己的服务器上拒绝下载的,可以替换为接口返回其内容,而不是直接请求m3u8文件,
然后m3u8中的ts文件可以写完整的路径。这样,就可以起到加密的作用了。
下载老版的ckplayer:https://gitee.com/niandeng/ckplayer/repository/archive/master.zip
参考:http://www.cnblogs.com/saysmy/p/5689778.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ckplayer6.8</title>
<style type="text/css">
body,td,th {
font-size: 14px;
line-height: 26px;
}
body {
margin-left: 0px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 0px;
}
p {
margin-top: 5px;
margin-right: 0px;
margin-bottom: 0px;
margin-left: 0px;
padding-left: 10px;
}
#a1{
position:relative;
z-index: 100;
width:600px;
height:400px;
float: left;
}
</style>
</head>
<body>
<div id="a1"></div>
<script type="text/javascript" src="ckplayer/ckplayer.js" charset="utf-8"></script>
<script type="text/javascript">
var flashvars={
f:'ckplayer/m3u8.swf',
a:'http://192.168.83.135/hls/item/movie.m3u8',
s:4
};
var params={bgcolor:'#FFF',allowFullScreen:true,allowScriptAccess:'always'};
var video=[];
CKobject.embed('ckplayer/ckplayer.swf','a1','ckplayer_a1','100%','100%',false,flashvars,video,params);
</script>
</body>
</html>
测试可以播放。
存在的问题:
1、播放到第几节才加载第几节,并不会在空闲时把未播放的陆续加载下来。
2、鼠标拖动,点击进度条时的效果。
五,服务端的要求
播放m3u8视频,暂时不需要配置nginx
播放mp4,flv,f4v格式并且需要兼容flashplayer的播放,并且需要支持视频请求未下载到用户本地缓存区的内容播放,则服务器的环境需要支
持。具体的就是用户向服务器请求如:temp.mp4?start=60时,服务器能够直接从本视频的60秒发送数据流。
视频类网站的基本实现
最新推荐文章于 2023-03-27 18:22:18 发布