来源:https://www.cnblogs.com/xusx2014/p/16243080.html
1. 切割视频的命令
1.1 将 mp4 文件切割为 ts 分片
ffmpeg -i Friends.S01E01.mkv.mp4 -force_key_frames "expr:gte(t,n_forced*2)" -strict -2 -c:a aac -c:v libx264 -hls_time 4 -f hls Friends.S01E01.mkv-ts/index.m3u8
默认的每片长度为 2 秒,m3u8 文件中默认只保存最新的 5 条片的信息,导致最后播放的时候只能播最后的一小部分(直播的时候特别注意)。
-hls_time n
设置每片的长度,默认值为 2,单位为秒。-hls_list_size n
设置播放列表保存的最多条目,设置为 0 会保存有所片信息,默认值为5。-hls_wrap n
设置多少片之后开始覆盖,如果设置为0则不会覆盖,默认值为0。这个选项能够避免在磁盘上存储过多的 片,而且能够限制写入磁盘的最多的片的数量。-hls_start_number n
设置播放列表中 sequence number 的值为 number,默认值为 0。
注意:播放列表的 sequence number 对每个 segment 来说都必须是唯一的,而且它不能和片的文件名(当使用 wrap 选项时,文件名有可能会重复使用)混淆。
1.2 html 播放 m3u8 文件
<html>
<head>
<meta name='viewport' content='width=device-width'>
<meta charset="UTF-8">
<link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-hls/5.14.1/videojs-contrib-hls.js"></script>
<script src="https://vjs.zencdn.net/7.2.3/video.js"></script>
</head>
<body>
<video id='hls-example' class="video-js vjs-default-skin" width="400" height="300" controls>
<source type="application/x-mpegURL" src="Friends.S01E01.mkv-ts/index.m3u8">
<track src='Friends.S01E01.mkv.mp4-zh.vtt' kind='subtitles' label='中文字幕' srclang='zh' default>
</video>
<script>
var player = videojs('hls-example');
player.play();
</script>
</body>
</html>
1.3 一种更快速的转换方式
先把视频整个转换为 ts 格式,然后在进行切片。(未测试)
# 1.视频整体转码ts
ffmpeg -y -i music.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb out\music.ts
# 2. ts 文件切片
ffmpeg -i music.ts -c copy -map 0 -f segment -segment_list out\music.m3u8 -segment_time 10 out\15s_%3d.ts
2. m3u8 格式
完整的 m3u8 文件有三部分:
- index.m3u8,保存视频的基本信息和分段文件顺序;
- key,如果视频加密,保存密钥;
- data文件,其他都是视频的数据文件。 具体内容解析:
#EXTM3U
,是文件开始
#EXT-X-VERSION
,标识HLS的协议版本号;
#EXT-X-TARGETDURATION
,表示每个视频分段最大的时长(单位秒);
#EXT-X-MEDIA-SEQUENCE
,表示播放列表第一个 URL 片段文件的序列号;
#EXT-X-PLAYLIST-TYPE
,表明流媒体类型;
#EXT-X-KEY
,加密方式,这里加密方式为AES-128,同时指定IV,在解密时需要;
#EXTINF
,表示其后 URL 指定的媒体片段时长(单位为秒)。