diff options
author | Jesus <heckyel@hyperbola.info> | 2025-03-08 16:40:51 -0500 |
---|---|---|
committer | Jesus <heckyel@hyperbola.info> | 2025-03-08 16:40:51 -0500 |
commit | 6f88b1cec6207abfe2b79ccd46e5ec50528f494f (patch) | |
tree | a04305786e84576ca81e9bad3bf342ee566909b1 /youtube/watch.py | |
parent | 03451fb8ae0d6d9d8affee715627e718244edcaf (diff) | |
download | yt-local-6f88b1cec6207abfe2b79ccd46e5ec50528f494f.tar.lz yt-local-6f88b1cec6207abfe2b79ccd46e5ec50528f494f.tar.xz yt-local-6f88b1cec6207abfe2b79ccd46e5ec50528f494f.zip |
Refactor extract_info in watch.py to improve client flexibility
Introduce primary_client, fallback_client, and last_resort_client variables for better configurability.
Replace hardcoded 'android_vr' with primary_client in fetch_player_response call.
Diffstat (limited to 'youtube/watch.py')
-rw-r--r-- | youtube/watch.py | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/youtube/watch.py b/youtube/watch.py index e2762cb..0274cd0 100644 --- a/youtube/watch.py +++ b/youtube/watch.py @@ -367,32 +367,42 @@ def fetch_watch_page_info(video_id, playlist_id, index): watch_page = watch_page.decode('utf-8') return yt_data_extract.extract_watch_info_from_html(watch_page) + def extract_info(video_id, use_invidious, playlist_id=None, index=None): + primary_client = 'android_vr' + fallback_client = 'ios' + last_resort_client = 'tv_embedded' + tasks = ( # Get video metadata from here gevent.spawn(fetch_watch_page_info, video_id, playlist_id, index), - gevent.spawn(fetch_player_response, 'android_vr', video_id) + gevent.spawn(fetch_player_response, primary_client, video_id) ) gevent.joinall(tasks) util.check_gevent_exceptions(*tasks) - info, player_response = tasks[0].value, tasks[1].value + + info = tasks[0].value or {} + player_response = tasks[1].value or {} yt_data_extract.update_with_new_urls(info, player_response) - # Age restricted video, retry - if info['age_restricted'] or info['player_urls_missing']: - if info['age_restricted']: - print('Age restricted video, retrying') - else: - print('Player urls missing, retrying') - player_response = fetch_player_response('tv_embedded', video_id) + # Fallback to 'ios' if no valid URLs are found + if not info.get('formats') or info.get('player_urls_missing'): + print(f"No URLs found in '{primary_client}', attempting with '{fallback_client}'.") + player_response = fetch_player_response(fallback_client, video_id) or {} + yt_data_extract.update_with_new_urls(info, player_response) + + # Final attempt with 'tv_embedded' if there are still no URLs + if not info.get('formats') or info.get('player_urls_missing'): + print(f"No URLs found in '{fallback_client}', attempting with '{last_resort_client}'") + player_response = fetch_player_response(last_resort_client, video_id) or {} yt_data_extract.update_with_new_urls(info, player_response) # signature decryption - decryption_error = decrypt_signatures(info, video_id) - if decryption_error: - decryption_error = 'Error decrypting url signatures: ' + decryption_error - info['playability_error'] = decryption_error + if info.get('formats'): + decryption_error = decrypt_signatures(info, video_id) + if decryption_error: + info['playability_error'] = 'Error decrypting url signatures: ' + decryption_error # check if urls ready (non-live format) in former livestream # urls not ready if all of them have no filesize @@ -406,21 +416,21 @@ def extract_info(video_id, use_invidious, playlist_id=None, index=None): # livestream urls # sometimes only the livestream urls work soon after the livestream is over - if (info['hls_manifest_url'] - and (info['live'] or not info['formats'] or not info['urls_ready']) - ): - manifest = util.fetch_url(info['hls_manifest_url'], - debug_name='hls_manifest.m3u8', - report_text='Fetched hls manifest' - ).decode('utf-8') - - info['hls_formats'], err = yt_data_extract.extract_hls_formats(manifest) - if not err: - info['playability_error'] = None - for fmt in info['hls_formats']: - fmt['video_quality'] = video_quality_string(fmt) - else: - info['hls_formats'] = [] + info['hls_formats'] = [] + if info.get('hls_manifest_url') and (info.get('live') or not info.get('formats') or not info['urls_ready']): + try: + manifest = util.fetch_url(info['hls_manifest_url'], + debug_name='hls_manifest.m3u8', + report_text='Fetched hls manifest' + ).decode('utf-8') + info['hls_formats'], err = yt_data_extract.extract_hls_formats(manifest) + if not err: + info['playability_error'] = None + for fmt in info['hls_formats']: + fmt['video_quality'] = video_quality_string(fmt) + except Exception as e: + print(f"Error obteniendo HLS manifest: {e}") + info['hls_formats'] = [] # check for 403. Unnecessary for tor video routing b/c ip address is same info['invidious_used'] = False |