[FFmpeg-devel,HLS] Add LANGUAGE attribute to #EXT-X-MEDIA tag for audio-only variant streams.

Submitted by Philippe Symons on Dec. 6, 2018, 9:03 p.m.

Details

Message ID CACS3z+abGrqzYsuBRNUNBbkAwpXhtW8kb6LURECnZ9+v+jvZnw@mail.gmail.com
State New
Headers show

Commit Message

Philippe Symons Dec. 6, 2018, 9:03 p.m.
Hello everyone,

I was hoping I could get some new feedback on my patch, so I have rebased
it to the latest commit on master.

Could someone take a look at it?

Thanks!

Kind regards,

Philippe Symons

Patch hide | download patch | download mbox

From 210be575ae324b89f940ff62e2dc11eb0f4e02e3 Mon Sep 17 00:00:00 2001
From: Philippe Symons <philippe.symons@gmail.com>
Date: Thu, 6 Dec 2018 21:57:24 +0100
Subject: [PATCH] avformat/hls,dash: add LANGUAGE attribute to #EXT-X-MEDIA tag
 for audio-only variant streams

Signed-off-by: Philippe Symons <philippe.symons@gmail.com>
---
 libavformat/dashenc.c     |  2 +-
 libavformat/hlsenc.c      | 23 ++++++++++++++++++++---
 libavformat/hlsplaylist.c |  6 +++++-
 libavformat/hlsplaylist.h |  2 +-
 4 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 4d9b564a94..d121f6b04b 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -964,7 +964,7 @@  static int write_manifest(AVFormatContext *s, int final)
             if (os->segment_type != SEGMENT_TYPE_MP4)
                 continue;
             get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i);
-            ff_hls_write_audio_rendition(c->m3u8_out, (char *)audio_group,
+            ff_hls_write_audio_rendition(c->m3u8_out, (char *)audio_group, NULL,
                                          playlist_file, i, is_default);
             max_audio_bitrate = FFMAX(st->codecpar->bit_rate +
                                       os->muxer_overhead, max_audio_bitrate);
diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c
index 31ef0237ae..af7fe54aea 100644
--- a/libavformat/hlsenc.c
+++ b/libavformat/hlsenc.c
@@ -1185,10 +1185,12 @@  static int create_master_playlist(AVFormatContext *s,
     HLSContext *hls = s->priv_data;
     VariantStream *vs, *temp_vs;
     AVStream *vid_st, *aud_st;
-    AVDictionary *options = NULL;
+    AVFormatContext *var_context;
+    AVDictionary *options = NULL, *meta_dict = NULL;
+    AVDictionaryEntry *lang_entry;
     unsigned int i, j;
     int m3u8_name_size, ret, bandwidth;
-    char *m3u8_rel_name, *ccgroup;
+    char *m3u8_rel_name, *ccgroup, *language;
     ClosedCaptionsStream *ccs;
 
     input_vs->m3u8_created = 1;
@@ -1228,11 +1230,26 @@  static int create_master_playlist(AVFormatContext *s,
 
     /* For audio only variant streams add #EXT-X-MEDIA tag with attributes*/
     for (i = 0; i < hls->nb_varstreams; i++) {
+        var_context = vs->avf;
         vs = &(hls->var_streams[i]);
+        language = NULL;
 
         if (vs->has_video || vs->has_subtitle || !vs->agroup)
             continue;
 
+        /*
+         * Try to obtain the language code of the audio stream.
+         * -if available- it will be used to write the LANGUAGE
+         * attribute in the #EXT-X-MEDIA tag
+         */
+        if (var_context && var_context->nb_streams > 0) {
+            meta_dict = vs->streams[0]->metadata;
+            lang_entry = av_dict_get(meta_dict, "language", NULL, 0);
+
+            if (lang_entry)
+                language = lang_entry->value;
+        }
+
         m3u8_name_size = strlen(vs->m3u8_name) + 1;
         m3u8_rel_name = av_malloc(m3u8_name_size);
         if (!m3u8_rel_name) {
@@ -1247,7 +1264,7 @@  static int create_master_playlist(AVFormatContext *s,
             goto fail;
         }
 
-        ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, m3u8_rel_name, 0, 1);
+        ff_hls_write_audio_rendition(hls->m3u8_out, vs->agroup, language, m3u8_rel_name, 0, 1);
 
         av_freep(&m3u8_rel_name);
     }
diff --git a/libavformat/hlsplaylist.c b/libavformat/hlsplaylist.c
index efcbff0009..ef2abedc83 100644
--- a/libavformat/hlsplaylist.c
+++ b/libavformat/hlsplaylist.c
@@ -35,12 +35,16 @@  void ff_hls_write_playlist_version(AVIOContext *out, int version) {
     avio_printf(out, "#EXT-X-VERSION:%d\n", version);
 }
 
-void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
+void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup, char* language,
                                   char *filename, int name_id, int is_default) {
     if (!out || !agroup || !filename)
         return;
 
     avio_printf(out, "#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID=\"group_%s\"", agroup);
+
+    if (language)
+        avio_printf(out, ",LANGUAGE=\"%s\"", language);
+
     avio_printf(out, ",NAME=\"audio_%d\",DEFAULT=%s,URI=\"%s\"\n", name_id,
                      is_default ? "YES" : "NO", filename);
 }
diff --git a/libavformat/hlsplaylist.h b/libavformat/hlsplaylist.h
index 5054b01c8f..360ca0ae53 100644
--- a/libavformat/hlsplaylist.h
+++ b/libavformat/hlsplaylist.h
@@ -37,7 +37,7 @@  typedef enum {
 } PlaylistType;
 
 void ff_hls_write_playlist_version(AVIOContext *out, int version);
-void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup,
+void ff_hls_write_audio_rendition(AVIOContext *out, char *agroup, char *language,
                                   char *filename, int name_id, int is_default);
 void ff_hls_write_stream_info(AVStream *st, AVIOContext *out,
                               int bandwidth, char *filename, char *agroup,
-- 
2.17.1