ytdl_hook: replace skip_muxed with force_all_formats option

I don't think the skip_muxed option was overlay useful. While it was
nice to filter out the low quality muxed versions (as it happens on the
alphabetic site, I suspect it's compatibility stuff), it's not really
necessary, and just makes for another tricky and rarely used
configuration option. (This was different before muxed tracks were also
delay-loaded, and including the muxed versions slowed down loading.)

Add the force_all_formats option instead, which handles the HLS case.
Set it to true because they are also delay-loaded now, and don't slow
down startup as much.
This commit is contained in:
wm4 2020-02-21 11:50:58 +01:00
parent fbbfbfc772
commit 6d09a042e6
2 changed files with 41 additions and 40 deletions

View File

@ -814,7 +814,6 @@ Program Behavior
``--script-opts`` option (using ``ytdl_hook-`` as prefix):
``try_ytdl_first=<yes|no>``
If 'yes' will try parsing the URL with youtube-dl first, instead of the
default where it's only after mpv failed to open it. This mostly depends
on whether most of your URLs need youtube-dl parsing.
@ -855,22 +854,40 @@ Program Behavior
slow, which can't be really fixed.) In general, this option is not
useful, and was only added to show that it's possible.
``skip_muxed=<yes|no>``
There are two cases that must be considered when doing quality/bandwidth
selection:
1. Completely separate audio and video streams (DASH-like). Each of
these streams contain either only audio or video, so you can
mix and combine audio/video bandwidths without restriction. This
intuitively matches best with the concept of selecting quality
by track (what ``all_formats`` is supposed to do).
2. Separate sets of muxed audio and video streams. Each version of
the media contains both an audio and video stream, and they are
interleaved. In order not to waste bandwidth, you should only
select one of these versions (if, for example, you select an
audio stream, then video will be downloaded, even if you selected
video from a different stream).
mpv will still represent them as separate tracks, but will set
the title of each track to ``muxed-N``, where ``N`` is replaced
with the youtube-dl format ID of the originating stream.
Some sites will mix 1. and 2., but we assume that they do so for
compatibility reasons, and there is no reason to use them at all.
``force_all_formats=<yes|no>``
If set to 'yes', and ``all_formats`` is also set to 'yes', this will
skip formats that have both audio and video streams (default: yes).
try to represent all youtube-dl reported formats as tracks, even if
mpv would normally use the direct URL reported by it (default: yes).
Some sites that provide multiple qualities will do so with separated
audio and video streams (which is what ``all_formats`` is supposed to
make use of), still provide formats that include both audio and video.
We assume that they do so for compatibility reasons, and ``skip_muxed``
filters them out. This will make loading faster, and potentially avoid
wasting bandwidth by using only one stream of a muxed stream. On the
other hand, if muxed streams are present, but the separate streams lack
either video or audio or do not exist at all, then the stream selection
as done by youtube-dl (via ``--ytdl-format``) is used.
It appears this normally makes a difference if youtube-dl works on a
master HLS playlist.
This appears to terribly break with some sites that provide a HLS master
playlist on the lowest level.
If this is set to 'no', this specific kind of stream is treated like
``all_formats`` is set to 'no', and the stream selection as done by
youtube-dl (via ``--ytdl-format``) is used.
``use_manifests=<yes|no>``
Make mpv use the master manifest URL for formats like HLS and DASH,

View File

@ -7,7 +7,7 @@ local o = {
try_ytdl_first = false,
use_manifests = false,
all_formats = false,
skip_muxed = true,
force_all_formats = true,
}
options.read_options(o)
@ -343,8 +343,6 @@ local function formats_to_edl(json, formats, use_all_formats)
local duration = as_integer(json["duration"])
local single_url = nil
local streams = {}
local separate_present = {}
local muxed_present = false
for index, track in ipairs(formats) do
local edl_track = nil
@ -376,14 +374,10 @@ local function formats_to_edl(json, formats, use_all_formats)
local url = edl_track or track.url
local hdr = {"!new_stream", "!no_clip", "!no_chapters"}
local as_muxed = false
local skip = false
local params = ""
if use_all_formats then
if #tracks > 1 and o.skip_muxed then
as_muxed = true
tracks = {} -- skip
end
for _, sub in ipairs(tracks) do
-- A single track that is either audio or video. Delay load it.
local codec = map_codec_to_mpv(sub.codec)
@ -418,10 +412,6 @@ local function formats_to_edl(json, formats, use_all_formats)
hdr[#hdr + 1] = "!track_meta,title=" ..
edl_escape(title) .. ",byterate=" .. byterate
if #tracks == 1 then
separate_present[sub.media_type] = true
end
if duration > 0 then
params = params .. ",length=" .. duration
end
@ -430,23 +420,12 @@ local function formats_to_edl(json, formats, use_all_formats)
hdr[#hdr + 1] = edl_escape(url) .. params
if as_muxed then
muxed_present = true
else
streams[#streams + 1] = table.concat(hdr, ";")
end
streams[#streams + 1] = table.concat(hdr, ";")
-- In case there is only 1 of these streams.
-- Note: assumes it has no important EDL headers
single_url = url
end
-- If "skip_muxed" is enabled, we discard formats that have both audio
-- and video aka muxed (because it's a pain). But if the single-media
-- type formats do not provide both video and audio, then discard them
-- and use the muxed streams instead.
res.muxed_needed = muxed_present and (not (separate_present["video"] and
separate_present["audio"]))
-- Merge all tracks into a single virtual file, but avoid EDL if it's
-- only a single track (i.e. redundant).
if #streams == 1 and single_url then
@ -495,8 +474,13 @@ local function add_single_video(json)
if streamurl == "" then
-- possibly DASH/split tracks
local res = nil
local has_requested_formats = requested_formats and #requested_formats > 0
if all_formats and o.all_formats then
-- Not having requested_formats usually hints to HLS master playlist
-- usage, which we don't want to split off, at least not yet.
if (all_formats and o.all_formats) and
(has_requested_formats or o.force_all_formats)
then
format_info = "all_formats (separate)"
res = formats_to_edl(json, all_formats, true)
-- Note: since we don't delay-load muxed streams, use normal stream
@ -506,7 +490,7 @@ local function add_single_video(json)
end
end
if (not res) and requested_formats and #requested_formats > 0 then
if (not res) and has_requested_formats then
format_info = "youtube-dl (separate)"
res = formats_to_edl(json, requested_formats, false)
end