From patchwork Thu Dec 6 21:03:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Philippe Symons X-Patchwork-Id: 11314 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 8425344C705 for ; Thu, 6 Dec 2018 23:10:16 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2D19168A862; Thu, 6 Dec 2018 23:10:08 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f67.google.com (mail-wr1-f67.google.com [209.85.221.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 5CD0E68A812 for ; Thu, 6 Dec 2018 23:10:02 +0200 (EET) Received: by mail-wr1-f67.google.com with SMTP id j2so1901714wrw.1 for ; Thu, 06 Dec 2018 13:10:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=LT7uCFCpEeo89aA5jhsPc6AA/cwFiN+T7FXqJkcWl7I=; b=gIdLo0h2siCU2BDib1I9Gp1oirRxlKwaVqqudfleRWa85Ed9AAvnoKLvA3s1Rj2KM8 e3wBTKVvWlN9Xn3pOe1r9AZHRfHLBSj4yy4dVlujEDtQ4FhZS1SQo9YOFSYp97ZOV3ox k3qg7MmW9vuzbrIC0G9qDJHBIVIyqSWPGvQSFbDjlyx+GSP9uLxiZHXGjB4tmDep/qY5 mYgWUo9tRlEXzADaN9vL/WVG20GemVs/+ltjRfx2xOS7381HDSZCR+WTGipSVKOz6SLq ObiU4SlIIoZXjZmwPyfaLGNysJF+8WRnsYlwv+65wu0sg1ifaL/O49gJ7CubSXuZK9AO QYPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=LT7uCFCpEeo89aA5jhsPc6AA/cwFiN+T7FXqJkcWl7I=; b=MYOlxsumYMI40QukmNkKv5YioiQdarjgZNjqtlSYUIxxfKFUAnRqkBXPdYrQPF01cT dAviLC34PmxonpcMgSvw7w+P+3zFEPlH28oEBgoY91dRuRG4/o9+nHRK2UCKtpWG21ZH 6G0nZktuPfeYhxb3vPXRK5esB7qmTVC3BiKW+lkUqemd0I2h42X8GFRmuwo81JsRj82x 9P1ixqtZFXAekZMO1O3fPVNZTcaI+1huqU5lphnErx2+vB1gOeaV3+TCm8T2S3v0GsqL sLw3SH7qtL8XacKoRqP3OSLdIzQESezcZU6fmy9ANtJ8rN5Tm7nOexDC8BnIW7thpsNC 8D9g== X-Gm-Message-State: AA+aEWbSl87Nn3Baha4yTAuqvnZjfviyWX3Id0cXOjOc+EIAz8MJQsLO 7j7bNrZh5GAWrNeBbH9UbIqVHHi3Q6MyTCcvVPhBuIHu X-Google-Smtp-Source: AFSGD/WXgavyvmbmMgilhtas9Md1K5c9m/gASOZX+u0d6I+J5mmZsf4ORLxGt0C828ljhdmsoP41Fjts39h+em+1Nzk= X-Received: by 2002:adf:f785:: with SMTP id q5mr28356036wrp.9.1544130228814; Thu, 06 Dec 2018 13:03:48 -0800 (PST) MIME-Version: 1.0 References: <1560DEDB-A8E6-45F9-82FE-5AEE9E56B8E1@chinaffmpeg.org> <20181117101954.GC4095@sunshine.barsnick.net> In-Reply-To: From: Philippe Symons Date: Thu, 6 Dec 2018 22:03:36 +0100 Message-ID: To: ffmpeg-devel@ffmpeg.org X-Content-Filtered-By: Mailman/MimeDel 2.1.20 Subject: Re: [FFmpeg-devel] [PATCH] [HLS] Add LANGUAGE attribute to #EXT-X-MEDIA tag for audio-only variant streams. X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 From 210be575ae324b89f940ff62e2dc11eb0f4e02e3 Mon Sep 17 00:00:00 2001 From: Philippe Symons 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 --- 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