Improve video extractor
This commit is contained in:
parent
5d510101ab
commit
ebe1b10c92
@ -372,16 +372,28 @@ def channel(id):
|
||||
|
||||
return render_template('channel.html', form=form, btform=button_form, channel=channelData[0], videos=channelData[1], restricted=config['restrictPublicUsage'], config=config)
|
||||
|
||||
def get_best_urls(urls):
|
||||
'''Gets URLS in youtube format (format_id, url, height) and returns best ones for yotter'''
|
||||
best_formats = ["22", "18", "34", "35", "36", "37", "38", "43", "44", "45", "46"]
|
||||
best_urls=[]
|
||||
for url in urls:
|
||||
for f in best_formats:
|
||||
if url['format_id'] == f:
|
||||
best_urls.append(url)
|
||||
return best_urls
|
||||
|
||||
@app.route('/watch', methods=['GET'])
|
||||
@login_required
|
||||
def watch():
|
||||
id = request.args.get('v', None)
|
||||
info = ytvids.get_video_info(id)
|
||||
hostName = urllib.parse.urlparse(info['video']['url']).netloc
|
||||
# Use nginx
|
||||
try:
|
||||
url = info['video']['url'].replace("https://{}".format(hostName), "")+"&host="+hostName
|
||||
for url in info['video']['urls']:
|
||||
hostName = urllib.parse.urlparse(url['url']).netloc
|
||||
url['url'] = url['url'].replace("https://{}".format(hostName), "")+"&host="+hostName
|
||||
except:
|
||||
hostName = "#"
|
||||
url = "#"
|
||||
|
||||
try:
|
||||
@ -389,6 +401,11 @@ def watch():
|
||||
audioUrl = info['video']['audio']['url'].replace("https://{}".format(audioHostName), "")+"&host="+audioHostName
|
||||
except:
|
||||
audioUrl = False
|
||||
|
||||
if info['video']['isUpcoming']:
|
||||
vid_urls=[]
|
||||
else:
|
||||
vid_urls = get_best_urls(info['video']['urls'])
|
||||
|
||||
video={
|
||||
'title':info['video']['title'],
|
||||
@ -399,8 +416,6 @@ def watch():
|
||||
'channelId': info['owner']['id'],
|
||||
'id':id,
|
||||
'averageRating': str((float(info['video']['rating'])/5)*100),
|
||||
'nginxUrl': url,
|
||||
'videoUrl': info['video']['url'],
|
||||
'videoHostName': hostName,
|
||||
'isLive': info['video']['isLive'],
|
||||
'isUpcoming': info['video']['isUpcoming'],
|
||||
@ -408,7 +423,7 @@ def watch():
|
||||
'nginxAudioUrl': audioUrl,
|
||||
'premieres': info['video']['premieres']
|
||||
}
|
||||
return render_template("video.html", video=video, title='{}'.format(video['title']), config=config)
|
||||
return render_template("video.html", video=video, title='{}'.format(video['title']), config=config, urls=vid_urls)
|
||||
|
||||
def markupString(string):
|
||||
string = string.replace("\n\n", "<br><br>").replace("\n", "<br>")
|
||||
|
@ -15,16 +15,25 @@
|
||||
<h5 class="ui header">{{video.premieres}}</h5>
|
||||
</div>
|
||||
</div>
|
||||
{% elif video.isLive %}
|
||||
<div class="ui center aligned text container">
|
||||
<div class="ui segment">
|
||||
<h4 class="ui header">LIVESTREAM VIDEO</h4>
|
||||
<h5 class="ui header">Livestreams are still not supported on Yotter.</h5>
|
||||
</div>
|
||||
</div>
|
||||
{%else%}
|
||||
<div class="video-js-responsive-container vjs-hd">
|
||||
<video class="video-js vjs-default-skin"
|
||||
data-setup='{ "playbackRates": [0.5, 1, 1.25,1.5, 2] }'
|
||||
data-setup='{ "playbackRates": [0.5, 0.75, 1, 1.25,1.5, 1.75, 2] }'
|
||||
width="1080"
|
||||
controls
|
||||
buffered
|
||||
preload="none">
|
||||
{% if config.nginxVideoStream %}
|
||||
<source src="{{video.nginxUrl}}" type="video/mp4">
|
||||
{% for url in urls %}
|
||||
<source src="{{url.url}}" type="video/{{url.ext}}">
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<source src="{{url_for('stream', url=video.videoUrl.replace('/', 'YotterSlash'))}}" type="video/mp4">
|
||||
{% endif %}
|
||||
|
@ -122,54 +122,55 @@ def get_video_primary_info(datad, datai):
|
||||
contents = datai["contents"]["twoColumnWatchNextResults"]['results']['results']['contents']
|
||||
item = get_renderer_key(contents, "videoPrimaryInfoRenderer")
|
||||
details = datad['videoDetails']
|
||||
try:
|
||||
isUpcoming = details['isUpcoming']
|
||||
views = "Scheduled video"
|
||||
except:
|
||||
isUpcoming = False
|
||||
|
||||
|
||||
if not isUpcoming:
|
||||
views = details['viewCount']
|
||||
|
||||
if isUpcoming:
|
||||
premieres = item['dateText']['simpleText']
|
||||
else:
|
||||
premieres = False
|
||||
|
||||
ydl = YoutubeDL()
|
||||
try:
|
||||
data = ydl.extract_info(details['videoId'], False)
|
||||
while not data['formats']:
|
||||
data = ydl.extract_info(details['videoId'], False)
|
||||
|
||||
## Get audio
|
||||
audio_urls = []
|
||||
for f in data['formats']:
|
||||
for fid in _formats:
|
||||
if f['format_id'] == fid:
|
||||
try:
|
||||
if 'audio' in _formats[fid]['format_note']:
|
||||
aurl = f['url']
|
||||
fnote = _formats[fid]['format_note']
|
||||
bitrate = _formats[fid]['audio_bitrate']
|
||||
audio_inf = {
|
||||
"url":aurl,
|
||||
"id":fnote,
|
||||
"btr": bitrate
|
||||
}
|
||||
audio_urls.append(audio_inf)
|
||||
except:
|
||||
continue
|
||||
## Get video
|
||||
if not details['isLiveContent']:
|
||||
url = data['formats'][-1]['url']
|
||||
else:
|
||||
url = data['formats'][-1]['url']
|
||||
except:
|
||||
url = "#"
|
||||
try:
|
||||
if isUpcoming:
|
||||
audioURL = False
|
||||
else:
|
||||
## Get audio
|
||||
audio_urls = []
|
||||
for f in data['formats']:
|
||||
for fid in _formats:
|
||||
if f['format_id'] == fid:
|
||||
try:
|
||||
if 'audio' in _formats[fid]['format_note']:
|
||||
aurl = f['url']
|
||||
fnote = _formats[fid]['format_note']
|
||||
bitrate = _formats[fid]['audio_bitrate']
|
||||
audio_inf = {
|
||||
"url":aurl,
|
||||
"id":fnote,
|
||||
"btr": bitrate
|
||||
}
|
||||
audio_urls.append(audio_inf)
|
||||
except:
|
||||
continue
|
||||
|
||||
# Check if is Livestream
|
||||
if details.get('isLive') and details['lengthSeconds'] == '0':
|
||||
isLive = True
|
||||
else:
|
||||
isLive = False
|
||||
|
||||
# Check if is a Scheduled video
|
||||
if details.get('isUpcoming'):
|
||||
isUpcoming = True
|
||||
views = "Scheduled video"
|
||||
premieres = item['dateText']['simpleText']
|
||||
audioURL = False
|
||||
else:
|
||||
isUpcoming = False
|
||||
premieres = False
|
||||
views = details['viewCount']
|
||||
if not isLive:
|
||||
audioURL = audio_urls[-1]
|
||||
else:
|
||||
audioURL = "#"
|
||||
|
||||
try:
|
||||
primaryInfo = {
|
||||
"id": details['videoId'],
|
||||
"title": details['title'],
|
||||
@ -180,20 +181,17 @@ def get_video_primary_info(datad, datai):
|
||||
"rating": details['averageRating'],
|
||||
"author": details['author'],
|
||||
"isPrivate": details['isPrivate'],
|
||||
"isLive": details['isLiveContent'],
|
||||
"isLive": isLive,
|
||||
"isUpcoming": isUpcoming,
|
||||
"allowRatings": details['allowRatings'],
|
||||
"url":url,
|
||||
"allowRatings": details['allowRatings'],
|
||||
"urls":data['formats'],
|
||||
"thumbnail": details['thumbnail']['thumbnails'][0]['url'],
|
||||
"audio": audioURL,
|
||||
"premieres": premieres
|
||||
}
|
||||
except:
|
||||
# If error take only most common items
|
||||
if isUpcoming:
|
||||
audioURL = False
|
||||
else:
|
||||
audioURL = audio_urls[-1]
|
||||
primaryInfo = {
|
||||
"id": details['videoId'],
|
||||
"title": details['title'],
|
||||
@ -204,10 +202,10 @@ def get_video_primary_info(datad, datai):
|
||||
"rating": details['averageRating'],
|
||||
"author": details['author'],
|
||||
"isPrivate":False,
|
||||
"isLive":details['isLiveContent'],
|
||||
"isLive":isLive,
|
||||
"isUpcoming":isUpcoming,
|
||||
"allowRatings":True,
|
||||
"url":url,
|
||||
"urls":data['formats'],
|
||||
"thumbnail": details['thumbnail']['thumbnails'][0]['url'],
|
||||
"audio": audioURL,
|
||||
"premieres": premieres
|
||||
|
Reference in New Issue
Block a user