diff --git a/DOCS/interface-changes/program-editions.txt b/DOCS/interface-changes/program-editions.txt index 476b88d216..f9ce685f08 100644 --- a/DOCS/interface-changes/program-editions.txt +++ b/DOCS/interface-changes/program-editions.txt @@ -1,3 +1,4 @@ ``track-list`` is now filtered by the currently selected edition add ``edition-list/N/metadata`` sub-property add ``program_id`` support to EDL ``!track_meta`` header +add ``--flatten-editions`` option to disable program-based edition grouping diff --git a/DOCS/man/options.rst b/DOCS/man/options.rst index 62c5b6afbc..b4858328a1 100644 --- a/DOCS/man/options.rst +++ b/DOCS/man/options.rst @@ -120,6 +120,17 @@ Track Selection to ``auto`` (the default), mpv will choose the first edition declared as a default, or if there is no default, the first edition defined. +``--flatten-editions=`` + Some container formats (such as HLS or MPEG-TS with multiple programs) + expose multiple programs or rendition groups. By default, mpv respects the + format and groups tracks into editions, filtering the track list to only + show tracks belonging to the currently selected edition. + + Setting this option to ``yes`` ignores the program structure of the file. + No editions are created, and all tracks from all programs are shown as a + flat list. Note that depending on the file, tracks from different programs + may be completely unrelated to each other. + ``--track-auto-selection=`` Enable the default track auto-selection (default: yes). Enabling this will make the player select streams according to ``--aid``, ``--alang``, and diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index d2b571563a..f7b4ff989d 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -981,6 +981,16 @@ static void build_editions(demuxer_t *demuxer) if (avfc->nb_programs <= 1) return; + struct MPOpts *mp_opts = mp_get_config_group(NULL, demuxer->global, &mp_opt_root); + int hls_bitrate = mp_opts->hls_bitrate; + int edition_id = mp_opts->edition_id; + bool flatten_editions = mp_opts->flatten_editions; + TA_FREEP(&mp_opts); + if (flatten_editions) { + MP_VERBOSE(demuxer, "Flattening track-based editions.\n"); + return; + } + for (unsigned i = 0; i < avfc->nb_programs; i++) { AVProgram *prog = avfc->programs[i]; @@ -1037,11 +1047,6 @@ static void build_editions(demuxer_t *demuxer) demuxer->edition_is_track_mapping = true; - struct MPOpts *mp_opts = mp_get_config_group(priv, demuxer->global, &mp_opt_root); - int hls_bitrate = mp_opts->hls_bitrate; - int edition_id = mp_opts->edition_id; - TA_FREEP(&mp_opts); - int selected = -1; if (edition_id >= 0 && edition_id < demuxer->num_editions) selected = edition_id; diff --git a/demux/demux_timeline.c b/demux/demux_timeline.c index 8333d8c37b..0dc7ca0e66 100644 --- a/demux/demux_timeline.c +++ b/demux/demux_timeline.c @@ -653,6 +653,16 @@ static void build_editions(struct demuxer *demuxer) if (demuxer->num_editions > 0) return; + struct MPOpts *mp_opts = mp_get_config_group(NULL, demuxer->global, &mp_opt_root); + int hls_bitrate = mp_opts->hls_bitrate; + int edition_id = mp_opts->edition_id; + bool flatten_editions = mp_opts->flatten_editions; + TA_FREEP(&mp_opts); + if (flatten_editions) { + MP_VERBOSE(demuxer, "Flattening track-based editions.\n"); + return; + } + int num_streams = demux_get_num_stream(demuxer); for (int n = 0; n < num_streams; n++) { struct sh_stream *sh = demux_get_stream(demuxer, n); @@ -693,11 +703,6 @@ static void build_editions(struct demuxer *demuxer) demuxer->edition_is_track_mapping = true; - struct MPOpts *mp_opts = mp_get_config_group(demuxer, demuxer->global, &mp_opt_root); - int hls_bitrate = mp_opts->hls_bitrate; - int edition_id = mp_opts->edition_id; - TA_FREEP(&mp_opts); - int selected = -1; if (edition_id >= 0 && edition_id < demuxer->num_editions) selected = edition_id; diff --git a/options/options.c b/options/options.c index 9f3edebdd1..64b75be38b 100644 --- a/options/options.c +++ b/options/options.c @@ -587,6 +587,7 @@ static const m_option_t mp_opts[] = { {"dvd", OPT_SUBSTRUCT(dvd_opts, dvd_conf)}, #endif {"edition", OPT_CHOICE(edition_id, {"auto", -1}), M_RANGE(0, 8190)}, + {"flatten-editions", OPT_BOOL(flatten_editions)}, #if HAVE_LIBBLURAY {"bluray", OPT_SUBSTRUCT(stream_bluray_opts, stream_bluray_conf)}, #endif /* HAVE_LIBBLURAY */ diff --git a/options/options.h b/options/options.h index 82717baf51..7beb99572d 100644 --- a/options/options.h +++ b/options/options.h @@ -254,6 +254,7 @@ typedef struct MPOpts { bool use_filedir_conf; int hls_bitrate; int edition_id; + bool flatten_editions; bool initial_audio_sync; double sync_max_video_change; double sync_max_audio_change; diff --git a/player/loadfile.c b/player/loadfile.c index 59f2de1790..56609b2ddb 100644 --- a/player/loadfile.c +++ b/player/loadfile.c @@ -607,6 +607,14 @@ struct track *select_default_track(struct MPContext *mpctx, int order, { struct MPOpts *opts = mpctx->opts; int tid = opts->stream_id[order][type]; + const struct demuxer *demuxer = mpctx->demuxer; + // Prefer tracks from the same program as the selected video when not using editions. + int preferred_program = -1; + if (type != STREAM_VIDEO && mpctx->current_track[0][STREAM_VIDEO] && + (!demuxer || !demuxer->edition_is_track_mapping || demuxer->num_editions <= 1)) + { + preferred_program = mpctx->current_track[0][STREAM_VIDEO]->program_id; + } if (tid == -2) return NULL; char **langs = process_langs(opts->stream_lang[type]); @@ -636,6 +644,9 @@ struct track *select_default_track(struct MPContext *mpctx, int order, continue; if (!opts->autoload_files && track->is_external) continue; + if (preferred_program != -1 && !track->is_external && + track->program_id != -1 && track->program_id != preferred_program) + continue; if (duplicate_track(mpctx, order, type, track)) continue; if (sub) {