aboutsummaryrefslogtreecommitdiffstats
path: root/youtube/watch.py
diff options
context:
space:
mode:
authorLibravatarLibravatar Biswa Kalyan Bhuyan <biswa.bhuyan@vegastack.com> 2025-03-29 12:35:50 +0530
committerLibravatarLibravatar Biswa Kalyan Bhuyan <biswa.bhuyan@vegastack.com> 2025-03-29 12:35:50 +0530
commit3fbaff704571293be83e2b56d36b761f42cce1ec (patch)
tree38ff650730359360c21f296b4ad5c47f01f20c30 /youtube/watch.py
parenta4e01da27c08e43a67b2618ad1e71c1f8f86d5cd (diff)
downloadyt-local-3fbaff704571293be83e2b56d36b761f42cce1ec.tar.gz
yt-local-3fbaff704571293be83e2b56d36b761f42cce1ec.tar.bz2
yt-local-3fbaff704571293be83e2b56d36b761f42cce1ec.zip
Update version v0.3.2HEADmaster
Diffstat (limited to 'youtube/watch.py')
-rw-r--r--youtube/watch.py134
1 files changed, 68 insertions, 66 deletions
diff --git a/youtube/watch.py b/youtube/watch.py
index 2cfece5..0274cd0 100644
--- a/youtube/watch.py
+++ b/youtube/watch.py
@@ -2,7 +2,6 @@ import youtube
from youtube import yt_app
from youtube import util, comments, local_playlist, yt_data_extract
from youtube.util import time_utc_isoformat
-from youtube.util import INNERTUBE_CLIENTS
import settings
from flask import request
@@ -344,7 +343,6 @@ def _add_to_error(info, key, additional_message):
def fetch_player_response(client, video_id):
return util.call_youtube_api(client, 'player', {
'videoId': video_id,
- 'params': 'CgIIAdgDAQ==',
})
@@ -369,84 +367,94 @@ 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):
- for client in INNERTUBE_CLIENTS:
- tasks = (
- gevent.spawn(fetch_watch_page_info, video_id, playlist_id, index),
- gevent.spawn(fetch_player_response, client, video_id) # Use client from INNERTUBE_CLIENTS
- )
- gevent.joinall(tasks)
- util.check_gevent_exceptions(*tasks)
- info, player_response = tasks[0].value, tasks[1].value
+ 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, primary_client, video_id)
+ )
+ gevent.joinall(tasks)
+ util.check_gevent_exceptions(*tasks)
+ info = tasks[0].value or {}
+ player_response = tasks[1].value or {}
+
+ yt_data_extract.update_with_new_urls(info, player_response)
+
+ # 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)
- # 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)
- 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
+ # signature decryption
+ if info.get('formats'):
decryption_error = decrypt_signatures(info, video_id)
if decryption_error:
- decryption_error = 'Error decrypting url signatures: ' + decryption_error
- info['playability_error'] = 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
- if info['was_live']:
- info['urls_ready'] = False
- for fmt in info['formats']:
- if fmt['file_size'] is not None:
- info['urls_ready'] = True
- else:
- info['urls_ready'] = True
+ # check if urls ready (non-live format) in former livestream
+ # urls not ready if all of them have no filesize
+ if info['was_live']:
+ info['urls_ready'] = False
+ for fmt in info['formats']:
+ if fmt['file_size'] is not None:
+ info['urls_ready'] = True
+ else:
+ info['urls_ready'] = True
- # 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'])
- ):
+ # livestream urls
+ # sometimes only the livestream urls work soon after the livestream is over
+ 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)
- else:
+ 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
- info['invidious_reload_button'] = False
- info['tor_bypass_used'] = False
- if (settings.route_tor == 1
- and info['formats'] and info['formats'][0]['url']):
- try:
- response = util.head(info['formats'][0]['url'],
- report_text='Checked for URL access')
- except urllib3.exceptions.HTTPError:
- print('Error while checking for URL access:\n')
- traceback.print_exc()
- return info
-
- if response.status == 403:
- print('Access denied (403) for video urls.')
- print('Routing video through Tor')
- info['tor_bypass_used'] = True
- for fmt in info['formats']:
- fmt['url'] += '&use_tor=1'
- elif 300 <= response.status < 400:
- print('Error: exceeded max redirects while checking video URL')
- return info
+ # check for 403. Unnecessary for tor video routing b/c ip address is same
+ info['invidious_used'] = False
+ info['invidious_reload_button'] = False
+ info['tor_bypass_used'] = False
+ if (settings.route_tor == 1
+ and info['formats'] and info['formats'][0]['url']):
+ try:
+ response = util.head(info['formats'][0]['url'],
+ report_text='Checked for URL access')
+ except urllib3.exceptions.HTTPError:
+ print('Error while checking for URL access:\n')
+ traceback.print_exc()
+ return info
+
+ if response.status == 403:
+ print('Access denied (403) for video urls.')
+ print('Routing video through Tor')
+ info['tor_bypass_used'] = True
+ for fmt in info['formats']:
+ fmt['url'] += '&use_tor=1'
+ elif 300 <= response.status < 400:
+ print('Error: exceeded max redirects while checking video URL')
+ return info
def video_quality_string(format):
@@ -651,12 +659,6 @@ def get_watch_page(video_id=None):
'/videoplayback',
'/videoplayback/name/' + filename)
- if settings.gather_googlevideo_domains:
- with open(os.path.join(settings.data_dir, 'googlevideo-domains.txt'), 'a+', encoding='utf-8') as f:
- url = info['formats'][0]['url']
- subdomain = url[0:url.find(".googlevideo.com")]
- f.write(subdomain + "\n")
-
download_formats = []
for format in (info['formats'] + info['hls_formats']):