Improve video extractor

This commit is contained in:
pluja 2020-10-05 15:12:02 +02:00
parent 5d510101ab
commit ebe1b10c92
3 changed files with 79 additions and 57 deletions

View File

@ -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>")

View File

@ -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 %}

View File

@ -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