HLS(HTTP Live Streaming)协议之m3u8文件生成方式
HLS(HTTP Live Streaming)是Apple的动态码率自适应技术。主要用于PC和Apple终端的音视频服务。包括一个m3u(8)的索引文件,TS媒体分片文件和key加密串文件。
HLS的关键其实是生成m3u8索引文件和TS媒体分片,下面我将通过以下几个步骤讲述m3u8及TS媒体分片的生成:
第一步---获取TS文件:
TS(Transport Stream)既传输流,标准制定于mpeg2文档协议中,当时TS格式主要是为了数字电视传输而制定,制定的年限相当早,在网上能找到很完备的mpeg2文档介绍。大家可以参考mpege-2文档标准中TS流介绍学习该格式。
现在的我们下载的高清电影以mkv格式居多,早期的的电影可能一rmvb和avi居多,更早的甚至还有mpg格式,现在流行的视频网站下载的视频基本都是flv格式。这些格式都是非TS格式,不过不要紧,现在视频转码的软件也非常多,我们可以通过以下两种方式进行转码。
1,通过格式工厂软件,这是一个比较成熟的软件,网上百度下载即可,不过只有软件,不利于后期源码的直接开发;
下载地址:http://www.pcfreetime.com/CN/index.html
2,通过ffmpeg进行格式转换,该工程为开源项目,我们在实际开发的过程中可以直接集成该源码,(具体的集成方式该篇文章不讲解,后期将对怎么封装调用ffmpeg做出相应介绍)。目前我们只是想获取TS文件用于生产m3u8索引文件和TS分片而已,直接下载ffmpeg的可执行程序,通过ffmpeg.exe转换即可:
下载地址:http://ffmpeg.org/
通过命令行模式进入到ffmpeg.exe所在的目录,在命令行中输入:ffmpeg.exe -i XXX.flv xxx.ts 即可,如下图:

图1
第二步--生成m3u8索引文件和TS媒体分片
1, m3u8 源码下,
下载地址:
https://github.com/johnf/m3u8-segmenter/archive/master.zip 该地址的源码主要是在linux系统编译,不过也能修改成在windows下编译。
windows的源码下载 :
官网:http://www.espend.de/artikel/iphone-ipad-ipod-http-streaming-segmenter-and-m3u8-windows.html 源码地址http://code.google.com/p/httpsegmenter/ 不过也要依赖ffmpeg库,稍微修改下即可。
其实以上两个路径的源码其实是一样滴,下面那个是德国人修改写的,看后缀de就知道了,可能需要翻墙才能打开。
下面是截取segmenter.c中的代码分片片段:
do {
double segment_time = 0.0;
AVPacket packet;
double packetStartTime = 0.0;
double packetDuration = 0.0;
if (!decode_done)
{
decode_done = av_read_frame(ic, &packet);
if (!decode_done)
{
if (packet.stream_index != video_index &&
packet.stream_index != audio_index)
{
av_free_packet(&packet);
continue;
}
timeStamp =
(double)(packet.pts) *
(double)(ic->streams[packet.stream_index]->time_base.num) /
(double)(ic->streams[packet.stream_index]->time_base.den);
if (av_dup_packet(&packet) < )
{
fprintf(stderr, "Could not duplicate packet\n");
av_free_packet(&packet);
break;
}
insertPacket(streamLace, &packet, timeStamp);
}
}
if (countPackets(streamLace) < && !decode_done)
{
/* allow the queue to fill up so that the packets can be sorted properly */
continue;
}
if (!removePacket(streamLace, &packet))
{
if (decode_done)
{
/* the queue is empty, we are done */
break;
}
assert(decode_done);
continue;
}
packetStartTime =
(double)(packet.pts) *
(double)(ic->streams[packet.stream_index]->time_base.num) /
(double)(ic->streams[packet.stream_index]->time_base.den);
packetDuration =
(double)(packet.duration) *
(double)(ic->streams[packet.stream_index]->time_base.num) /
(double)(ic->streams[packet.stream_index]->time_base.den);
#if !defined(NDEBUG) && (defined(DEBUG) || defined(_DEBUG))
if (av_log_get_level() >= AV_LOG_VERBOSE)
fprintf(stderr,
"stream %i, packet [%f, %f)\n",
packet.stream_index,
packetStartTime,
packetStartTime + packetDuration);
#endif
segment_duration = packetStartTime + packetDuration - prev_segment_time;
// NOTE: segments are supposed to start on a keyframe.
// If the keyframe interval and segment duration do not match
// forcing the segment creation for "better seeking behavior"
// will result in decoding artifacts after seeking or stream switching.
if (packet.stream_index == video_index && (packet.flags & AV_PKT_FLAG_KEY || strict_segment_duration)) {
segment_time = packetStartTime;
}
else if (video_index < ) {
segment_time = packetStartTime;
}
else {
segment_time = prev_segment_time;
}
if (segment_time - prev_segment_time + segment_duration_error_tolerance >
target_segment_duration + extra_duration_needed)
{
avio_flush(oc->pb);
avio_close(oc->pb);
// Keep track of accumulated rounding error to account for it in later chunks.
segment_duration = segment_time - prev_segment_time;
rounded_segment_duration = (int)(segment_duration + 0.5);
extra_duration_needed += (double)rounded_segment_duration - segment_duration;
updatePlaylist(playlist,
playlist_filename,
output_filename,
output_index,
rounded_segment_duration);
_snprintf(output_filename, strlen(output_prefix) + , "%s-%u.ts", output_prefix, ++output_index);
if (avio_open(&oc->pb, output_filename, AVIO_FLAG_WRITE) < ) {
fprintf(stderr, "Could not open '%s'\n", output_filename);
break;
}
// close when we find the 'kill' file
if (kill_file) {
FILE* fp = fopen("kill", "rb");
if (fp) {
fprintf(stderr, "user abort: found kill file\n");
fclose(fp);
remove("kill");
decode_done = ;
removeAllPackets(streamLace);
}
}
prev_segment_time = segment_time;
}
ret = av_interleaved_write_frame(oc, &packet);
if (ret < ) {
fprintf(stderr, "Warning: Could not write frame of stream\n");
}
else if (ret > ) {
fprintf(stderr, "End of stream requested\n");
av_free_packet(&packet);
break;
}
av_free_packet(&packet);
} while (!decode_done || countPackets(streamLace) > );
2, 把下载下来的源码直接在vs中编译生成exe即可, 如我生成的exe为m3u8.exe:

图2
3, 通过命令行进入该目录,并在命令行中输入: m3u8.exe -d 10 -x m3u8list.m3u8 即可生成.m3u8文件和ts分片文件,如图2目录文件的m3u8list.m3u8 和-1.ts、-2.ts和-3.ts文件。

图3
4, 如以图2的目录列表,直接用VLC播放器就可以播放m3u8list.m3u8文件, 用写字板查看m3u8文件内容为:
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:10,
-1.ts
#EXTINF:10,
-2.ts
#EXTINF:9,
-3.ts
#EXT-X-ENDLIST
好了,大功告成! 我们可以直接播放m3u8list.m3u8 和-1.ts、-2.ts、-3.ts文件 , 也可以直接用http协议传输这些文件,就成了hls协议了
HLS(HTTP Live Streaming)协议之m3u8文件生成方式的更多相关文章
- 如何生成HLS协议的M3U8文件
什么是HLS协议: HLS(Http Live Streaming)是由Apple公司定义的用于实时流传输的协议,HLS基于HTTP协议实现,传输内容包括两部分,一是M3U8描述文件,二是TS媒体文件 ...
- 将视频转换为 HLS(HTTP Live Streaming) 协议格式文件
就是将视频文件转码(H264+ACC).分片(n个.ts文件).生成列表(.m3u8) 方便网站提供视频播放服务,提升加载速度,节省流量. 1.准备好源视频文件. 2.下载 ffmpeg(http:/ ...
- linux下搭建生成HLS所需的.ts和.m3u8文件
要想利用HLS来实现视频的在线播放,就得需要将一个完整的视频文件切割成多个ts视频流,然后利用m3u8的索引文件来播放. 在Mac下,苹果提供了streamingTools的工具,里面有mediafi ...
- (HLS播放器之中的一个)HLS协议之M3U8解析
參照 http://tools.ietf.org/html/draft-pantos-http-live-streaming-08, 能够对M3U8有比較系统的认识. HLS(HTTP Live St ...
- [视频播放] HLS协议之M3U8、TS流详解
本文转载自:<hls之m3u8.ts流格式详解> HLS,Http Live Streaming 是由Apple公司定义的用于实时流传输的协议,HLS基于HTTP协议实现,传输内容包括两部 ...
- HLS的M3U8文件介绍
HLS的M3U8文件介绍 HLS (HTTP Live Streaming)是Apple的动态码率自适应技术.主要用于PC和Apple终端的音视频服务. 相较于实时传输协议(RTP),HLS可以穿过任 ...
- MP4大文件虚拟HLS分片技术,避免服务器大量文件碎片
MP4大文件虚拟HLS分片技术,避免点播服务器的文件碎片 本文主要介绍了通过虚拟分片技术,把MP4文件,映射为HLS协议中的一个个小的TS分片文件,实现了在不实际切分MP4文件的情况下,通过HLS协议 ...
- 基于HLS(HTTP Live Streaming)的视频直播分析与实现
转自:http://www.cnblogs.com/haibindev/archive/2013/01/30/2880764.html HLS(HTTP Live Streaming)的分析: HTT ...
- m3u8文件合并处理
m3u8文件合并处理 简介 M3U8 是 Unicode 版本的 M3U,用 UTF-8 编码."M3U" 和 "M3U8" 文件都是苹果公司使用的 HTTP ...
随机推荐
- 转自http://blog.slogra.com/post-13.html,关闭centos虚拟机的蜂鸣声
相信对经常在虚拟机做实验的人来说,每次按tab来补全命令的时候是最痛苦的,这个时候是最让人想把 电脑的蜂鸣器给拆下来,让我们来关闭这个烦人的东西吧. 在centos系统下的方法 1.临时解决办法:以 ...
- PclZip:强大的PHP压缩与解压缩zip类
PclZip简介PclZip是一个很强大的压缩与解压缩zip文件的PHP类,PclZip library能够压缩与解压缩Zip格式的压缩档(WinZip.PKZIP):且能对此类类档案进行处理,包括产 ...
- Decimal:解决0.3 != 0.1+0.1+0.1的方法(十进制浮点数)
0.普通情况 1.引入Decimal 也可以这样引入: from decimal import Decimal as D 相当于: from decimal import Decimal D = De ...
- python中的super
super用于类的继承.用super()代替父类名 (一)通过类名调用父类中的方法 (二 ...
- C 语言链表操作例程 (待完善)
#include<stdio.h>#include<malloc.h>#include<conio.h>#include<stdlib.h>#inclu ...
- ROW_NUMBER()/RANK()/DENSE_RANK()/ntile() over()
ROW_NUMBER()/RANK()/DENSE_RANK()/ntile() over() 今天女票问我SqlServer的四种排序,当场写了几句Sql让她了解,现把相关Sql放上来. 首先, ...
- Scala学习文档-访问修饰符
在scala里,对保护成员的访问比Java严格.Scala中,保护成员只在定义了成员的类的子类中可以访问,而Java中,还允许在同一个包的其他类中访问. package p1 { class FCla ...
- jquery幻灯片--渐变
网站上为了设计,需要一些幻灯片效果,现在网站有很多插件可以使用. 想要成为以为牛逼的程序员,绝对不允许只会用别人的插件而已,不然你只能是“代码”的搬运工,而不敢做出自己的创新. 首先使用jquery做 ...
- Effective Java Item4:Enforce noninstantiability with a private constructor
Item4:Enforce noninstantiability with a private constructor 通过构造私有化,禁止对象被实例化. public class UtilClass ...
- BOT、BT、PPP形式介绍(2)
BT1.什么是BT BT投资是BOT的一种变换形式,即Build-Transfer(建设—转让),政府通过特许协议,引入国外资金或民间资金进行专属于政府的基础设施建设,基础设施建设完工后,该项 ...