Skip to content
This repository was archived by the owner on Jun 30, 2022. It is now read-only.

Commit

Permalink
πŸ‘ŒοΈ More improvements, changes & fixed #51
Browse files Browse the repository at this point in the history
  • Loading branch information
alexmercerind committed Feb 2, 2021
1 parent 86085a6 commit 31e51f5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 49 deletions.
56 changes: 31 additions & 25 deletions youtubesearchpython/__future__/internal/streamurlfetcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,37 +37,43 @@ def __init__(self):
async def getJavaScript(self) -> None:
'''Gets player JavaScript from YouTube, avoid calling more than once.
'''
global js_url
async with httpx.AsyncClient() as client:
response = await client.get('https://youtube.com/watch', timeout = None)
watchHTML = response.text
loop = asyncio.get_running_loop()
self.js_url = await loop.run_in_executor(None, extract.js_url, watchHTML)
if js_url != self.js_url:
try:
global js_url
async with httpx.AsyncClient() as client:
response = await client.get(self.js_url, timeout = None)
self.js = response.text
response = await client.get('https://www.youtube.com/watch', timeout = None)
watchHTML = response.text
loop = asyncio.get_running_loop()
self.js_url = await loop.run_in_executor(None, extract.js_url, watchHTML)
if js_url != self.js_url:
async with httpx.AsyncClient() as client:
response = await client.get(self.js_url, timeout = None)
self.js = response.text
except:
raise Exception('ERROR: Could not make request.')

'''
Saving videoFormats inside a dictionary with key 'player_response' for apply_descrambler & apply_signature methods.
'''
async def _getDecipheredURLs(self, videoFormats: dict) -> None:
self.player_response = {'player_response': videoFormats}
if not videoFormats['streamingData']:
''' For getting streamingData in age restricted video. '''
async with httpx.AsyncClient() as client:
''' Derived from extract.video_info_url_age_restricted '''
response = await client.post(
'https://youtube.com/get_video_info',
params = {
'video_id': videoFormats['id'],
'eurl': f'https://youtube.googleapis.com/v/{videoFormats["id"]}',
'sts': None,
},
timeout = None,
)
''' Google returns content as a query string instead of a JSON. '''
self.player_response['player_response'] = await loads(parse_qs(response.text)["player_response"][0])
try:
''' For getting streamingData in age restricted video. '''
async with httpx.AsyncClient() as client:
''' Derived from extract.video_info_url_age_restricted '''
response = await client.post(
'https://youtube.com/get_video_info',
params = {
'video_id': videoFormats['id'],
'eurl': f'https://youtube.googleapis.com/v/{videoFormats["id"]}',
'sts': None,
},
timeout = None,
)
''' Google returns content as a query string instead of a JSON. '''
self.player_response['player_response'] = await loads(parse_qs(response.text)["player_response"][0])
except:
raise Exception('ERROR: Could not make request.')
self.video_id = videoFormats["id"]
await self._decipher()

Expand All @@ -84,8 +90,8 @@ async def _decipher(self, retry: bool = False):
These methods operate on the value of "player_response" key in dictionary of self.player_response & save _deciphered information in the "url_encoded_fmt_stream_map" key.
'''
loop = asyncio.get_running_loop()
loop.run_in_executor(None, apply_descrambler, self.player_response, 'url_encoded_fmt_stream_map')
loop.run_in_executor(None, apply_signature, self.player_response, 'url_encoded_fmt_stream_map', self.js)
await loop.run_in_executor(None, apply_descrambler, self.player_response, 'url_encoded_fmt_stream_map')
await loop.run_in_executor(None, apply_signature, self.player_response, 'url_encoded_fmt_stream_map', self.js)

except:
'''
Expand Down
56 changes: 32 additions & 24 deletions youtubesearchpython/internal/streamurlfetcher.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
isPyTubeInstalled = False


import httpx
from urllib.request import urlopen
from urllib.parse import parse_qs, urlencode
import json
try:
from pytube.__main__ import apply_descrambler, apply_signature
from pytube import YouTube, extract
Expand Down Expand Up @@ -32,18 +33,22 @@ def __init__(self):
def _getDecipheredURLs(self, videoFormats: dict) -> None:
self.player_response = {'player_response': videoFormats}
if not videoFormats['streamingData']:
''' For getting streamingData in age restricted video. '''
response = urlopen(
'https://youtube.com/get_video_info' + '?' + urlencode({
'video_id': videoFormats['id'],
'eurl': f'https://youtube.googleapis.com/v/{videoFormats["id"]}',
'sts': None,
}),
data = urlencode({}),
)
''' Derived from extract.video_info_url_age_restricted '''
''' Google returns content as a query string instead of a JSON. '''
self.player_response['player_response'] = json.loads(parse_qs(response.text)["player_response"][0])
try:
''' For getting streamingData in age restricted video. '''
response = urlopen(
'https://youtube.com/get_video_info' + '?' + urlencode({
'video_id': videoFormats['id'],
'eurl': f'https://youtube.googleapis.com/v/{videoFormats["id"]}',
'sts': '',
}),
data = ''.encode('utf_8'),
timeout = None,
)
''' Derived from extract.video_info_url_age_restricted '''
''' Google returns content as a query string instead of a JSON. '''
self.player_response['player_response'] = json.loads(parse_qs(response.read().decode('utf_8'))["player_response"][0])
except:
raise Exception('ERROR: Could not make request.')
self.video_id = videoFormats["id"]
self._decipher()

Expand All @@ -55,17 +60,20 @@ def _getDecipheredURLs(self, videoFormats: dict) -> None:
Removed v parameter from the query. (No idea about why PyTube bothered with that)
'''
def _getJS(self) -> None:
response = urlopen('https://youtube.com/watch', timeout = None)
watch_html = response.read().decode('utf_8')
age_restricted = extract.is_age_restricted(watch_html)
self.js_url = extract.js_url(watch_html)
if pytube.__js_url__ != self.js_url:
response = urlopen(self.js_url, timeout = None)
self.js = response.read().decode('utf_8')
pytube.__js__ = self.js
pytube.__js_url__ = self.js_url
else:
self.js = pytube.__js__
try:
response = urlopen('https://youtube.com/watch', timeout = None)
watch_html = response.read().decode('utf_8')
age_restricted = extract.is_age_restricted(watch_html)
self.js_url = extract.js_url(watch_html)
if pytube.__js_url__ != self.js_url:
response = urlopen(self.js_url, timeout = None)
self.js = response.read().decode('utf_8')
pytube.__js__ = self.js
pytube.__js_url__ = self.js_url
else:
self.js = pytube.__js__
except:
raise Exception('ERROR: Could not make request.')

'''
Not fetching for new player JavaScript if pytube.__js__ is not None or exception is not caused.
Expand Down

0 comments on commit 31e51f5

Please sign in to comment.