diff --git a/Changelog b/Changelog index 56f3a29d83..6260d0ca3d 100644 --- a/Changelog +++ b/Changelog @@ -6,6 +6,7 @@ version : - ported lenscorrection filter from frei0r filter - large optimizations in dctdnoiz to make it usable - request icecast metadata by default +- support for using metadata in stream specifiers in fftools version 2.3: diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index f741a053f5..158f4ed6cc 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -821,6 +821,11 @@ To map all the streams except the second audio, use negative mappings ffmpeg -i INPUT -map 0 -map -0:a:1 OUTPUT @end example +To pick the English audio stream: +@example +avconv -i INPUT -map 0:m:language:eng OUTPUT +@end example + Note that using this option disables the default mappings for this output file. @item -map_channel [@var{input_file_id}.@var{stream_specifier}.@var{channel_id}|-1][:@var{output_file_id}.@var{stream_specifier}] diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index ab627ca4a9..6ee6292c5f 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -46,6 +46,13 @@ in the program with the id @var{program_id}. Otherwise, it matches all streams i program. @item #@var{stream_id} or i:@var{stream_id} Match the stream by stream id (e.g. PID in MPEG-TS container). +@item m:@var{key}[:@var{value}] +Matches streams with the metadata tag @var{key} having the specified value. If +@var{value} is not given, matches streams that contain the given tag with any +value. + +Note that in @command{avconv}, matching by metadata will only work properly for +input files. @end table @section Generic options diff --git a/libavformat/utils.c b/libavformat/utils.c index 13d4c6b1ee..5bb56428f0 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -4216,6 +4216,29 @@ int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, stream_id = strtol(spec, &endptr, 0); if (!*endptr) return stream_id == st->id; + } else if (*spec == 'm' && *(spec + 1) == ':') { + AVDictionaryEntry *tag; + char *key, *val; + int ret; + + spec += 2; + val = strchr(spec, ':'); + + key = val ? av_strndup(spec, val - spec) : av_strdup(spec); + if (!key) + return AVERROR(ENOMEM); + + tag = av_dict_get(st->metadata, key, NULL, 0); + if (tag) { + if (!val || !strcmp(tag->value, val + 1)) + ret = 1; + else + ret = 0; + } else + ret = 0; + + av_freep(&key); + return ret; } else if (!*spec) /* empty specifier, matches everything */ return 1;