ytdl_hook: merge separate audio tracks via EDL

This merges separate audio and video tracks into one virtual stream,
which helps the mpv caching layer. See previous EDL commit for details.

It's apparently active for most of evil Silicon Valley giant's streaming
videos.

Initial tests seem to work fine, except it happens pretty often that
playback goes into buffering immediately even when seeking within a
cached range, because there is not enough forward cache data yet to
fully restart playback. (Or something like this.)

The audio stream title used to be derived from track.format_note; this
commit stops doing so. It seemed pointless anyway. If really necessary,
it could be restored by adding new EDL headers.

Note that we explicitly don't do this with subtitle tracks. Subtitle
tracks still have a chance with on-demand loading or loading in the
background while video is already playing; merging them with EDL would
prevent this. Currently, subtitles are still added in a "blocking"
manner, but in theory this could be loosened. For example, the Lua API
already provides a way to run processes asynchronously, which could be
used to add subtitles during playback. EDL will probably be never
flexible enough to provide this. Also, subtitles are downloaded at
once, rather than streamed like audio and video.

Still missing: disabling EDL's pointless chapter generation, and
propagating download speed statistics through the EDL wrapper.
This commit is contained in:
wm4 2019-01-04 14:01:56 +01:00
parent d2ef2f98a8
commit f485e34fc9
1 changed files with 15 additions and 5 deletions

View File

@ -303,6 +303,8 @@ local function add_single_video(json)
-- DASH/split tracks
elseif reqfmts then
local streams = {}
for _, track in pairs(reqfmts) do
local edl_track = nil
edl_track = edl_track_joined(track.fragments,
@ -313,15 +315,23 @@ local function add_single_video(json)
end
if track.vcodec and track.vcodec ~= "none" then
-- video track
streamurl = edl_track or track.url
streams[#streams + 1] = edl_track or track.url
elseif track.vcodec == "none" then
-- according to ytdl, if vcodec is None, it's audio
mp.commandv("audio-add",
edl_track or track.url, "auto",
track.format_note or "")
-- audio track
streams[#streams + 1] = track.url
end
end
if #streams > 1 then
-- merge them via EDL
for i = 1, #streams do
streams[i] = edl_escape(streams[i])
end
streamurl = "edl://" .. table.concat(streams, ";!new_stream;") .. ";"
else
streamurl = streams[1]
end
elseif not (json.url == nil) then
local edl_track = nil
edl_track = edl_track_joined(json.fragments, json.protocol,