mirror of
https://github.com/mpv-player/mpv
synced 2025-04-23 15:47:54 +00:00
player: simplistic HLS bitrate selection
--hls-bitrate=min/max lets you select the min or max bitrate. That's it. Something more sophisticated might be possible, but is probably not even worth the effort.
This commit is contained in:
parent
8d92128f6b
commit
5f14543668
@ -2838,11 +2838,9 @@ Network
|
||||
Use ``<string>`` as user agent for HTTP streaming.
|
||||
|
||||
``--cookies``, ``--no-cookies``
|
||||
(network only)
|
||||
Support cookies when making HTTP requests. Disabled by default.
|
||||
|
||||
``--cookies-file=<filename>``
|
||||
(network only)
|
||||
Read HTTP cookies from <filename>. The file is assumed to be in Netscape
|
||||
format.
|
||||
|
||||
@ -2882,6 +2880,17 @@ Network
|
||||
network transport when playing ``rtsp://...`` URLs. The value ``lavf``
|
||||
leaves the decision to libavformat.
|
||||
|
||||
``--hls-bitrate=<no|min|max>``
|
||||
If HLS streams are played, this option controls what streams are selected
|
||||
by default. The option allows the following parameters:
|
||||
|
||||
:no: Don't do anything special. Typically, this will simply pick the
|
||||
first audio/video streams it can find. (Default.)
|
||||
:min: Pick the streams with the lowest bitrate.
|
||||
:max: Same, but highest bitrate.
|
||||
|
||||
The bitrate as used is sent by the server, and there's no guarantee it's
|
||||
actually meaningful.
|
||||
|
||||
DVB
|
||||
---
|
||||
|
@ -429,6 +429,19 @@ static void export_replaygain(demuxer_t *demuxer, sh_audio_t *sh, AVStream *st)
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return a dictionary entry as (decimal) integer.
|
||||
static int dict_get_decimal(AVDictionary *dict, const char *entry, int def)
|
||||
{
|
||||
AVDictionaryEntry *e = av_dict_get(dict, entry, NULL, 0);
|
||||
if (e && e->value) {
|
||||
char *end = NULL;
|
||||
long int r = strtol(e->value, &end, 10);
|
||||
if (end && !end[0] && r >= INT_MIN && r <= INT_MAX)
|
||||
return r;
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
static void handle_stream(demuxer_t *demuxer, int i)
|
||||
{
|
||||
lavf_priv_t *priv = demuxer->priv;
|
||||
@ -505,13 +518,9 @@ static void handle_stream(demuxer_t *demuxer, int i)
|
||||
if (sd)
|
||||
sh_video->rotate = -av_display_rotation_get((uint32_t *)sd);
|
||||
#else
|
||||
AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0);
|
||||
if (rot && rot->value) {
|
||||
char *end = NULL;
|
||||
long int r = strtol(rot->value, &end, 10);
|
||||
if (end && !end[0])
|
||||
sh_video->rotate = r;
|
||||
}
|
||||
int rot = dict_get_decimal(st->metadata, "rotate", -1);
|
||||
if (rot >= 0)
|
||||
sh_video->rotate = rot;
|
||||
#endif
|
||||
sh_video->rotate = ((sh_video->rotate % 360) + 360) % 360;
|
||||
|
||||
@ -589,6 +598,7 @@ static void handle_stream(demuxer_t *demuxer, int i)
|
||||
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
||||
if (lang && lang->value)
|
||||
sh->lang = talloc_strdup(sh, lang->value);
|
||||
sh->hls_bitrate = dict_get_decimal(st->metadata, "variant_bitrate", 0);
|
||||
}
|
||||
|
||||
select_tracks(demuxer, i);
|
||||
|
@ -55,6 +55,7 @@ struct sh_stream {
|
||||
char *title;
|
||||
char *lang; // language code
|
||||
bool default_track; // container default track flag
|
||||
int hls_bitrate;
|
||||
|
||||
// stream is a picture (such as album art)
|
||||
struct demux_packet *attached_picture;
|
||||
|
@ -202,6 +202,9 @@ const m_option_t mp_opts[] = {
|
||||
OPT_STRING("quvi-format", quvi_format, 0),
|
||||
OPT_FLAG("quvi-fetch-subtitles", quvi_fetch_subtitles, 0),
|
||||
|
||||
OPT_CHOICE("hls-bitrate", hls_bitrate, M_OPT_FIXED,
|
||||
({"no", 0}, {"min", 1}, {"max", 2})),
|
||||
|
||||
#if HAVE_CDDA
|
||||
OPT_SUBSTRUCT("cdda", stream_cdda_opts, stream_cdda_conf, 0),
|
||||
OPT_STRING("cdrom-device", cdrom_device, 0),
|
||||
|
@ -123,6 +123,7 @@ typedef struct MPOpts {
|
||||
char *force_configdir;
|
||||
int use_filedir_conf;
|
||||
int network_rtsp_transport;
|
||||
int hls_bitrate;
|
||||
struct mp_cache_opts stream_cache;
|
||||
int chapterrange[2];
|
||||
int edition_id;
|
||||
|
@ -464,13 +464,15 @@ static int match_lang(char **langs, char *lang)
|
||||
* 1b) track was passed explicitly (is not an auto-loaded subtitle)
|
||||
* 2) earlier match in lang list
|
||||
* 3) track is marked default
|
||||
* 4) lower track number
|
||||
* If select_fallback is not set, 4) is only used to determine whether a
|
||||
* 4) attached picture, HLS bitrate
|
||||
* 5) lower track number
|
||||
* If select_fallback is not set, 5) is only used to determine whether a
|
||||
* matching track is preferred over another track. Otherwise, always pick a
|
||||
* track (if nothing else matches, return the track with lowest ID).
|
||||
*/
|
||||
// Return whether t1 is preferred over t2
|
||||
static bool compare_track(struct track *t1, struct track *t2, char **langs)
|
||||
static bool compare_track(struct track *t1, struct track *t2, char **langs,
|
||||
struct MPOpts *opts)
|
||||
{
|
||||
bool ext1 = t1->is_external && !t1->no_default;
|
||||
bool ext2 = t2->is_external && !t2->no_default;
|
||||
@ -485,6 +487,11 @@ static bool compare_track(struct track *t1, struct track *t2, char **langs)
|
||||
return t1->default_track;
|
||||
if (t1->attached_picture != t2->attached_picture)
|
||||
return !t1->attached_picture;
|
||||
if (t1->stream && t2->stream && opts->hls_bitrate) {
|
||||
int d = t1->stream->hls_bitrate - t2->stream->hls_bitrate;
|
||||
if (d)
|
||||
return opts->hls_bitrate == 1 ? d < 0 : d > 0;
|
||||
}
|
||||
return t1->user_tid <= t2->user_tid;
|
||||
}
|
||||
static struct track *select_track(struct MPContext *mpctx,
|
||||
@ -500,7 +507,7 @@ static struct track *select_track(struct MPContext *mpctx,
|
||||
continue;
|
||||
if (track->user_tid == tid)
|
||||
return track;
|
||||
if (!pick || compare_track(track, pick, langs))
|
||||
if (!pick || compare_track(track, pick, langs, mpctx->opts))
|
||||
pick = track;
|
||||
}
|
||||
if (pick && !select_fallback && !(pick->is_external && !pick->no_default)
|
||||
|
Loading…
Reference in New Issue
Block a user