---
libavformat/segment.c | 27 +++
1 file changed, 27 insertions(+)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 8ac04e2..07bb675 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -37,6 +37,7 @@ typedef struct {
AVFormatContext *avf;
char *format; /**< Set by a private option. */
char *list;/**< Set by a private option. */
+int list_type;/**< Set by a private option. */
float time;/**< Set by a private option. */
int size; /**< Set by a private option. */
int wrap; /**< Set by a private option. */
@@ -48,6 +49,11 @@ typedef struct {
AVIOContext *pb;
} SegmentContext;
+enum {
+LIST_FLAT,
+LIST_HLS
+};
+
static int segment_mux_init(AVFormatContext *s)
{
SegmentContext *seg = s->priv_data;
@@ -72,6 +78,17 @@ static int segment_mux_init(AVFormatContext *s)
return 0;
}
+static void segment_hls_header(SegmentContext *seg)
+{
+avio_printf(seg->pb, "#EXTM3U\n");
+
+avio_printf(seg->pb, "#EXT-X-VERSION:3\n");
+
+avio_printf(seg->pb, "#EXT-X-TARGETDURATION:%d\n", (int)seg->time);
+
+avio_printf(seg->pb, "#EXT-X-MEDIA-SEQUENCE:%d)", seg->number % seg->size);
+}
+
static int segment_start(AVFormatContext *s, int write_header)
{
SegmentContext *c = s->priv_data;
@@ -211,6 +228,10 @@ static int seg_write_header(AVFormatContext *s)
}
if (seg->list) {
+if (seg->list_type == LIST_HLS) {
+segment_hls_header(seg);
+avio_printf(seg->pb, "#EXTINF:%d,\n", (int)seg->time);
+}
avio_printf(seg->pb, "%s\n", oc->filename);
avio_flush(seg->pb);
}
@@ -252,6 +273,8 @@ static int seg_write_packet(AVFormatContext *s, AVPacket
*pkt)
oc = seg->avf;
if (seg->list) {
+if (seg->list_type == LIST_HLS)
+avio_printf(seg->pb, "#EXTINF:%d,\n", (int)seg->time);
avio_printf(seg->pb, "%s\n", oc->filename);
avio_flush(seg->pb);
if (seg->size && !(seg->number % seg->size)) {
@@ -259,6 +282,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket
*pkt)
if ((ret = avio_open2(&seg->pb, seg->list, AVIO_FLAG_WRITE,
&s->interrupt_callback, NULL)) < 0)
goto fail;
+segment_hls_header(seg);
}
}
}
@@ -301,6 +325,9 @@ static const AVOption options[] = {
{ "segment_time", "segment length in seconds",
OFFSET(time),AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E },
{ "segment_list", "output the segment list",
OFFSET(list),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E },
{ "segment_list_size", "maximum number of playlist entries",
OFFSET(size),AV_OPT_TYPE_INT,{.i64 = 5}, 0, INT_MAX, E },
+{ "segment_list_type", "segment list format",
OFFSET(list_type),AV_OPT_TYPE_INT,{.i64 = 0}, 0, 2, E, "list_type"
},
+{ "flat","plain list (default)",0,
AV_OPT_TYPE_CONST, {.i64 = LIST_FLAT}, 0, 0, E, "list_type" },
+{ "hls", "Apple HTTP Live Streaming compatible",0,
AV_OPT_TYPE_CONST, {.i64 = LIST_HLS}, 0, 0, E, "list_type" },
{ "segment_wrap", "number after which the index wraps",
OFFSET(wrap),AV_OPT_TYPE_INT,{.i64 = 0}, 0, INT_MAX, E },
{ "individual_header_trailer", "write header/trailer to each segment",
OFFSET(individual_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E },
{ "write_header_trailer", "write a header to the first segment and a
trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_INT, {.i64
= 1}, 0, 1, E },
--
1.7.12
___
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel