Add setting to prefer uni or pair sources and fix selection b/w them

pair_quality != uni_quality was the wrong condition to check,
since there are cases where the target_resolution is 360, and
there are no pair sources at 360, but there are some at other
resolutions, which would falsely select the pair sources.

Signed-off-by: Jesús <heckyel@hyperbola.info>
This commit is contained in:
James Taylor 2021-08-29 13:00:39 -07:00 committed by Jesús
parent 99cb1c48ea
commit 2ae81f2a78
No known key found for this signature in database
GPG Key ID: F6EE7BC59A315766
2 changed files with 22 additions and 4 deletions

View File

@ -168,6 +168,15 @@ For security reasons, enabling this is not recommended.''',
'category': 'playback', 'category': 'playback',
}), }),
('prefer_uni_sources', {
'label': 'Prefer integrated sources',
'type': bool,
'default': True,
'comment': '',
'category': 'playback',
'description': 'If enabled and the default resolution is set to 360p or 720p, uses the unified (integrated) video files which contain audio and video, with buffering managed by the browser. If disabled, always uses the separate audio and video files through custom buffer management in av-merge via MediaSource.',
}),
('use_video_player', { ('use_video_player', {
'type': int, 'type': int,
'default': 1, 'default': 1,

View File

@ -23,7 +23,7 @@ except FileNotFoundError:
decrypt_cache = {} decrypt_cache = {}
def get_video_sources(info): def get_video_sources(info, target_resolution):
'''return dict with organized sources: { '''return dict with organized sources: {
'uni_sources': [{}, ...], # video and audio in one file 'uni_sources': [{}, ...], # video and audio in one file
'uni_idx': int, # default unified source index 'uni_idx': int, # default unified source index
@ -35,7 +35,6 @@ def get_video_sources(info):
video_only_sources = [] video_only_sources = []
uni_sources = [] uni_sources = []
pair_sources = [] pair_sources = []
target_resolution = settings.default_resolution
for fmt in info['formats']: for fmt in info['formats']:
if not all(fmt[attr] for attr in ('ext', 'url')): if not all(fmt[attr] for attr in ('ext', 'url')):
continue continue
@ -563,7 +562,8 @@ def get_watch_page(video_id=None):
'codecs': codecs_string, 'codecs': codecs_string,
}) })
source_info = get_video_sources(info) target_resolution = settings.default_resolution
source_info = get_video_sources(info, target_resolution)
uni_sources = source_info['uni_sources'] uni_sources = source_info['uni_sources']
pair_sources = source_info['pair_sources'] pair_sources = source_info['pair_sources']
uni_idx, pair_idx = source_info['uni_idx'], source_info['pair_idx'] uni_idx, pair_idx = source_info['uni_idx'], source_info['pair_idx']
@ -577,8 +577,17 @@ def get_watch_page(video_id=None):
pair_quality = yt_data_extract.deep_get(pair_sources, pair_idx, 0, pair_quality = yt_data_extract.deep_get(pair_sources, pair_idx, 0,
'quality') 'quality')
uni_quality = yt_data_extract.deep_get(uni_sources, uni_idx, 'quality') uni_quality = yt_data_extract.deep_get(uni_sources, uni_idx, 'quality')
pair_error = abs((pair_quality or 360) - target_resolution)
uni_error = abs((uni_quality or 360) - target_resolution)
if uni_error == pair_error:
# use settings.prefer_uni_sources as a tiebreaker
closer_to_target = 'uni' if settings.prefer_uni_sources else 'pair'
elif uni_error < pair_error:
closer_to_target = 'uni'
else:
closer_to_target = 'pair'
using_pair_sources = ( using_pair_sources = (
bool(pair_sources) and (not uni_sources or pair_quality != uni_quality) bool(pair_sources) and (not uni_sources or closer_to_target == 'pair')
) )
# 1 second per pixel, or the actual video width # 1 second per pixel, or the actual video width