Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
ffmpeg
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
ffmpeg
Commits
d02289c3
Commit
d02289c3
authored
Dec 23, 2017
by
Vishwanath Dixit
Committed by
Steven Liu
Dec 23, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avformat/hlsenc:addition of #EXT-X-MEDIA tag and AUDIO attribute
Signed-off-by:
Steven Liu
<
lq@chinaffmpeg.org
>
parent
4c78bbd3
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
79 additions
and
6 deletions
+79
-6
muxers.texi
doc/muxers.texi
+12
-0
dashenc.c
libavformat/dashenc.c
+2
-1
hlsenc.c
libavformat/hlsenc.c
+61
-3
hlsplaylist.c
libavformat/hlsplaylist.c
+3
-1
hlsplaylist.h
libavformat/hlsplaylist.h
+1
-1
No files found.
doc/muxers.texi
View file @
d02289c3
...
...
@@ -834,6 +834,18 @@ be a video only stream with video bitrate 1000k, the second variant stream will
be an audio only stream with bitrate 64k and the third variant stream will be a
video only stream with bitrate 256k. Here, three media playlist with file names
out_1.m3u8, out_2.m3u8 and out_3.m3u8 will be created.
@example
ffmpeg -re -i in.ts -b:a:0 32k -b:a:1 64k -b:v:0 1000k -b:v:1 3000k \
-map 0:a -map 0:a -map 0:v -map 0:v -f hls \
-var_stream_map "a:0,agroup:aud_low a:1,agroup:aud_high v:0,agroup:aud_low v:1,agroup:aud_high" \
-master_pl_name master.m3u8 \
http://example.com/live/out.m3u8
@end example
This example creates two audio only and two video only variant streams. In
addition to the #EXT-X-STREAM-INF tag for each variant stream in the master
playlist, #EXT-X-MEDIA tag is also added for the two audio only variant streams
and they are mapped to the two video only variant streams with audio group names
'aud_low' and 'aud_high'.
By default, a single hls variant containing all the encoded streams is created.
...
...
libavformat/dashenc.c
View file @
d02289c3
...
...
@@ -759,7 +759,8 @@ static int write_manifest(AVFormatContext *s, int final)
char
playlist_file
[
64
];
AVStream
*
st
=
s
->
streams
[
i
];
get_hls_playlist_name
(
playlist_file
,
sizeof
(
playlist_file
),
NULL
,
i
);
ff_hls_write_stream_info
(
st
,
out
,
st
->
codecpar
->
bit_rate
,
playlist_file
);
ff_hls_write_stream_info
(
st
,
out
,
st
->
codecpar
->
bit_rate
,
playlist_file
,
NULL
);
}
avio_close
(
out
);
if
(
use_rename
)
...
...
libavformat/hlsenc.c
View file @
d02289c3
...
...
@@ -144,6 +144,7 @@ typedef struct VariantStream {
AVStream
**
streams
;
unsigned
int
nb_streams
;
int
m3u8_created
;
/* status of media play-list creation */
char
*
agroup
;
/* audio group name */
char
*
baseurl
;
}
VariantStream
;
...
...
@@ -1110,7 +1111,7 @@ static int create_master_playlist(AVFormatContext *s,
VariantStream
*
const
input_vs
)
{
HLSContext
*
hls
=
s
->
priv_data
;
VariantStream
*
vs
;
VariantStream
*
vs
,
*
temp_vs
;
AVStream
*
vid_st
,
*
aud_st
;
AVDictionary
*
options
=
NULL
;
unsigned
int
i
,
j
;
...
...
@@ -1142,6 +1143,34 @@ static int create_master_playlist(AVFormatContext *s,
ff_hls_write_playlist_version
(
hls
->
m3u8_out
,
hls
->
version
);
/* For audio only variant streams add #EXT-X-MEDIA tag with attributes*/
for
(
i
=
0
;
i
<
hls
->
nb_varstreams
;
i
++
)
{
vs
=
&
(
hls
->
var_streams
[
i
]);
if
(
vs
->
has_video
||
vs
->
has_subtitle
||
!
vs
->
agroup
)
continue
;
m3u8_name_size
=
strlen
(
vs
->
m3u8_name
)
+
1
;
m3u8_rel_name
=
av_malloc
(
m3u8_name_size
);
if
(
!
m3u8_rel_name
)
{
ret
=
AVERROR
(
ENOMEM
);
goto
fail
;
}
av_strlcpy
(
m3u8_rel_name
,
vs
->
m3u8_name
,
m3u8_name_size
);
ret
=
get_relative_url
(
hls
->
master_m3u8_url
,
vs
->
m3u8_name
,
m3u8_rel_name
,
m3u8_name_size
);
if
(
ret
<
0
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"Unable to find relative URL
\n
"
);
goto
fail
;
}
avio_printf
(
hls
->
m3u8_out
,
"#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=
\"
group_%s
\"
"
,
vs
->
agroup
);
avio_printf
(
hls
->
m3u8_out
,
",NAME=
\"
audio_0
\"
,DEFAULT=YES,URI=
\"
%s
\"\n
"
,
m3u8_rel_name
);
av_freep
(
&
m3u8_rel_name
);
}
/* For variant streams with video add #EXT-X-STREAM-INF tag with attributes*/
for
(
i
=
0
;
i
<
hls
->
nb_varstreams
;
i
++
)
{
vs
=
&
(
hls
->
var_streams
[
i
]);
...
...
@@ -1174,6 +1203,25 @@ static int create_master_playlist(AVFormatContext *s,
continue
;
}
/**
* Traverse through the list of audio only rendition streams and find
* the rendition which has highest bitrate in the same audio group
*/
if
(
vs
->
agroup
)
{
for
(
j
=
0
;
j
<
hls
->
nb_varstreams
;
j
++
)
{
temp_vs
=
&
(
hls
->
var_streams
[
j
]);
if
(
!
temp_vs
->
has_video
&&
!
temp_vs
->
has_subtitle
&&
temp_vs
->
agroup
&&
!
av_strcasecmp
(
temp_vs
->
agroup
,
vs
->
agroup
))
{
if
(
!
aud_st
)
aud_st
=
temp_vs
->
streams
[
0
];
if
(
temp_vs
->
streams
[
0
]
->
codecpar
->
bit_rate
>
aud_st
->
codecpar
->
bit_rate
)
aud_st
=
temp_vs
->
streams
[
0
];
}
}
}
bandwidth
=
0
;
if
(
vid_st
)
bandwidth
+=
vid_st
->
codecpar
->
bit_rate
;
...
...
@@ -1181,7 +1229,8 @@ static int create_master_playlist(AVFormatContext *s,
bandwidth
+=
aud_st
->
codecpar
->
bit_rate
;
bandwidth
+=
bandwidth
/
10
;
ff_hls_write_stream_info
(
vid_st
,
hls
->
m3u8_out
,
bandwidth
,
m3u8_rel_name
);
ff_hls_write_stream_info
(
vid_st
,
hls
->
m3u8_out
,
bandwidth
,
m3u8_rel_name
,
aud_st
?
vs
->
agroup
:
NULL
);
av_freep
(
&
m3u8_rel_name
);
}
...
...
@@ -1532,6 +1581,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
/**
* Expected format for var_stream_map string is as below:
* "a:0,v:0 a:1,v:1"
* "a:0,agroup:a0 a:1,agroup:a1 v:0,agroup:a0 v:1,agroup:a1"
* This string specifies how to group the audio, video and subtitle streams
* into different variant streams. The variant stream groups are separated
* by space.
...
...
@@ -1540,6 +1590,7 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
* respectively. Allowed values are 0 to 9 digits (limited just based on
* practical usage)
*
* agroup: is key to specify audio group. A string can be given as value.
*/
p
=
av_strdup
(
hls
->
var_stream_map
);
q
=
p
;
...
...
@@ -1578,7 +1629,12 @@ static int parse_variant_stream_mapstring(AVFormatContext *s)
while
(
keyval
=
av_strtok
(
varstr
,
","
,
&
saveptr2
))
{
varstr
=
NULL
;
if
(
av_strstart
(
keyval
,
"v:"
,
&
val
))
{
if
(
av_strstart
(
keyval
,
"agroup:"
,
&
val
))
{
vs
->
agroup
=
av_strdup
(
val
);
if
(
!
vs
->
agroup
)
return
AVERROR
(
ENOMEM
);
continue
;
}
else
if
(
av_strstart
(
keyval
,
"v:"
,
&
val
))
{
codec_type
=
AVMEDIA_TYPE_VIDEO
;
}
else
if
(
av_strstart
(
keyval
,
"a:"
,
&
val
))
{
codec_type
=
AVMEDIA_TYPE_AUDIO
;
...
...
@@ -1969,6 +2025,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
av_free
(
old_filename
);
av_freep
(
&
vs
->
m3u8_name
);
av_freep
(
&
vs
->
streams
);
av_freep
(
&
vs
->
agroup
);
av_freep
(
&
vs
->
baseurl
);
}
...
...
@@ -2309,6 +2366,7 @@ fail:
av_freep
(
&
vs
->
m3u8_name
);
av_freep
(
&
vs
->
vtt_m3u8_name
);
av_freep
(
&
vs
->
streams
);
av_freep
(
&
vs
->
agroup
);
av_freep
(
&
vs
->
baseurl
);
if
(
vs
->
avf
)
avformat_free_context
(
vs
->
avf
);
...
...
libavformat/hlsplaylist.c
View file @
d02289c3
...
...
@@ -36,7 +36,7 @@ void ff_hls_write_playlist_version(AVIOContext *out, int version) {
}
void
ff_hls_write_stream_info
(
AVStream
*
st
,
AVIOContext
*
out
,
int
bandwidth
,
char
*
filename
)
{
int
bandwidth
,
char
*
filename
,
char
*
agroup
)
{
if
(
!
out
||
!
filename
)
return
;
...
...
@@ -50,6 +50,8 @@ void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
if
(
st
&&
st
->
codecpar
->
width
>
0
&&
st
->
codecpar
->
height
>
0
)
avio_printf
(
out
,
",RESOLUTION=%dx%d"
,
st
->
codecpar
->
width
,
st
->
codecpar
->
height
);
if
(
agroup
&&
strlen
(
agroup
)
>
0
)
avio_printf
(
out
,
",AUDIO=
\"
group_%s
\"
"
,
agroup
);
avio_printf
(
out
,
"
\n
%s
\n\n
"
,
filename
);
}
...
...
libavformat/hlsplaylist.h
View file @
d02289c3
...
...
@@ -38,7 +38,7 @@ typedef enum {
void
ff_hls_write_playlist_version
(
AVIOContext
*
out
,
int
version
);
void
ff_hls_write_stream_info
(
AVStream
*
st
,
AVIOContext
*
out
,
int
bandwidth
,
char
*
filename
);
int
bandwidth
,
char
*
filename
,
char
*
agroup
);
void
ff_hls_write_playlist_header
(
AVIOContext
*
out
,
int
version
,
int
allowcache
,
int
target_duration
,
int64_t
sequence
,
uint32_t
playlist_type
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment