fix: show fully uncached range for network streams (#214)

* fix: show fully uncached range for network streams

* fix: correctly filter and fuse uncached ranges

Overlapping cached ranges were not handled correctly and sometimes it
could end up with very short uncached ranges.

Now overlaps and small gaps are fused together, and very short ranges
are filtered out.
This commit is contained in:
christoph-heinrich
2022-09-19 18:47:50 +02:00
committed by GitHub
parent d63d5a7434
commit 13afa971cc

View File

@@ -4102,7 +4102,6 @@ mp.observe_property('duration', 'number', create_state_setter('duration', update
mp.observe_property('speed', 'number', create_state_setter('speed', update_human_times))
mp.observe_property('track-list', 'native', function(name, value)
-- checks the file dispositions
local path = mp.get_property_native('path')
local has_audio, has_sub, is_video, is_image = false, false, false, false
for _, track in ipairs(value) do
if track.type == 'audio' then has_audio = true end
@@ -4119,7 +4118,6 @@ mp.observe_property('track-list', 'native', function(name, value)
set_state('has_audio', has_audio)
set_state('has_sub', has_sub)
set_state('is_video', is_video)
set_state('is_stream', is_protocol(path))
Elements:trigger('dispositions')
end)
mp.observe_property('chapter-list', 'native', function(_, chapters)
@@ -4148,10 +4146,14 @@ mp.observe_property('osd-dimensions', 'native', function(name, val)
request_render()
end)
mp.observe_property('display-hidpi-scale', 'native', update_display_dimensions)
mp.observe_property('demuxer-via-network', 'native', create_state_setter('is_stream', function()
set_state('uncached_ranges', state.is_stream and state.duration and {0, state.duration} or nil)
Elements:trigger('dispositions')
end))
mp.observe_property('demuxer-cache-state', 'native', function(prop, cache_state)
local cached_ranges = cache_state and cache_state['seekable-ranges'] or {}
local uncached_ranges = nil
if state.duration and #cached_ranges > 0 then
if state.duration and state.is_stream then
-- Normalize
local ranges = {}
for _, range in ipairs(cached_ranges) do
@@ -4162,17 +4164,20 @@ mp.observe_property('demuxer-cache-state', 'native', function(prop, cache_state)
end
table.sort(ranges, function(a, b) return a[1] < b[1] end)
-- Invert cached ranges into uncached ranges, as that's what we're rendering
uncached_ranges = {}
local inverted_ranges = {{0, state.duration}}
for _, cached in pairs(ranges) do
local last_uncached = uncached_ranges[#uncached_ranges]
if cached[2] - cached[1] > 0.5 then
if not last_uncached then
if cached[1] > 0.5 then uncached_ranges[#uncached_ranges + 1] = {0, cached[1]} end
else
if last_uncached[2] > cached[1] then last_uncached[2] = cached[1] end
end
if state.duration - cached[2] > 0.5 then
uncached_ranges[#uncached_ranges + 1] = {cached[2], state.duration}
inverted_ranges[#inverted_ranges][2] = cached[1]
inverted_ranges[#inverted_ranges + 1] = {cached[2], state.duration}
end
uncached_ranges = {}
local last_range = nil
for _, range in ipairs(inverted_ranges) do
if last_range and last_range[2] + 0.5 > range[1] then -- fuse ranges
last_range[2] = range[2]
else
if range[2] - range[1] > 0.5 then -- skip short ranges
uncached_ranges[#uncached_ranges+1] = range
last_range = range
end
end
end