Add support for livestreams and scheduled videos on /watch
This commit is contained in:
parent
2a3668a645
commit
745b816864
@ -321,8 +321,13 @@ def watch():
|
||||
id = request.args.get('v', None)
|
||||
info = ytvids.get_video_info(id)
|
||||
hostName = urllib.parse.urlparse(info['video']['url']).netloc
|
||||
|
||||
# Use nginx
|
||||
url = info['video']['url'].replace(hostName, config['serverName'])+"&hostname="+hostName
|
||||
try:
|
||||
url = info['video']['url'].replace(hostName, config['serverName'])+"&hostname="+hostName
|
||||
except:
|
||||
url = "#"
|
||||
|
||||
video={
|
||||
'title':info['video']['title'],
|
||||
'description':Markup(markupString(info['video']['description'])),
|
||||
|
BIN
app/static/img/live.png
Normal file
BIN
app/static/img/live.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
BIN
app/static/img/scheduled.png
Normal file
BIN
app/static/img/scheduled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
@ -4,20 +4,32 @@
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<div class="ui text container">
|
||||
<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] }'
|
||||
width="1080"
|
||||
controls
|
||||
buffered
|
||||
preload="none">
|
||||
{% if config.nginxVideoStream %}
|
||||
<source src="{{video.nginxUrl}}" type="video/mp4">
|
||||
{% else %}
|
||||
<source src="{{url_for('stream', url=video.videoUrl.replace('/', 'YotterSlash'))}}" type="video/mp4">
|
||||
{% endif %}
|
||||
</video>
|
||||
{% if video.nginxUrl == "#" and video.isLive %}
|
||||
<div class="ui center aligned text container">
|
||||
<img alt="Empty feed image" class="ui image" src="{{ url_for('static',filename='img/live.png') }}">
|
||||
</div>
|
||||
{% elif video.isUpcoming %}
|
||||
<div class="ui center aligned text container">
|
||||
<div class="ui row">
|
||||
<img alt="Empty feed image" class="ui image" src="{{ url_for('static',filename='img/scheduled.png') }}">
|
||||
</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] }'
|
||||
width="1080"
|
||||
controls
|
||||
buffered
|
||||
preload="none">
|
||||
{% if config.nginxVideoStream %}
|
||||
<source src="{{video.nginxUrl}}" type="video/mp4">
|
||||
{% else %}
|
||||
<source src="{{url_for('stream', url=video.videoUrl.replace('/', 'YotterSlash'))}}" type="video/mp4">
|
||||
{% endif %}
|
||||
</video>
|
||||
</div>
|
||||
{%endif%}
|
||||
|
||||
<div class="ui segments">
|
||||
<div class="ui segment">
|
||||
|
0
youtube_data/channels.py
Normal file
0
youtube_data/channels.py
Normal file
@ -1,59 +0,0 @@
|
||||
import requests
|
||||
import urllib.parse
|
||||
import json
|
||||
from bs4 import BeautifulSoup as bs
|
||||
|
||||
nested_renderer_dispatch = {
|
||||
'singleColumnBrowseResultsRenderer',
|
||||
'twoColumnBrowseResultsRenderer', # Channel renderer
|
||||
'twoColumnSearchResultsRenderer',
|
||||
}
|
||||
|
||||
# these renderers contain a list of renderers inside them
|
||||
nested_renderer_list_dispatch = {
|
||||
'sectionListRenderer',
|
||||
'itemSectionRenderer',
|
||||
'gridRenderer',
|
||||
'playlistVideoListRenderer',
|
||||
'singleColumnWatchNextResults',
|
||||
}
|
||||
|
||||
_item_types = {
|
||||
'movieRenderer',
|
||||
'didYouMeanRenderer',
|
||||
'showingResultsForRenderer',
|
||||
|
||||
'videoRenderer',
|
||||
'compactVideoRenderer',
|
||||
'compactAutoplayRenderer',
|
||||
'videoWithContextRenderer',
|
||||
'gridVideoRenderer',
|
||||
'playlistVideoRenderer',
|
||||
|
||||
'playlistRenderer',
|
||||
'compactPlaylistRenderer',
|
||||
'gridPlaylistRenderer',
|
||||
|
||||
'radioRenderer',
|
||||
'compactRadioRenderer',
|
||||
'gridRadioRenderer',
|
||||
|
||||
'showRenderer',
|
||||
'compactShowRenderer',
|
||||
'gridShowRenderer',
|
||||
|
||||
|
||||
'channelRenderer',
|
||||
'compactChannelRenderer',
|
||||
'gridChannelRenderer',
|
||||
}
|
||||
|
||||
|
||||
def getRenderers(data):
|
||||
renderers = []
|
||||
for renderer in nested_renderer_dispatch:
|
||||
renderers.append(data['contents'][renderer])
|
||||
return renderers
|
||||
|
||||
def getRenderedItems(renderer):
|
||||
'''Given a renderer, return its items'''
|
@ -17,19 +17,28 @@ def get_video_primary_info(datad, datai):
|
||||
details = datad['videoDetails']
|
||||
try:
|
||||
isUpcoming = details['isUpcoming']
|
||||
views = "Scheduled video"
|
||||
except:
|
||||
isUpcoming = False
|
||||
|
||||
if not isUpcoming:
|
||||
views = details['viewCount']
|
||||
|
||||
ydl = YoutubeDL()
|
||||
data = ydl.extract_info(details['videoId'], False)
|
||||
if not details['isLiveContent']:
|
||||
url = data['formats'][-1]['url']
|
||||
try:
|
||||
data = ydl.extract_info(details['videoId'], False)
|
||||
if not details['isLiveContent']:
|
||||
url = data['formats'][-1]['url']
|
||||
else:
|
||||
url = data['formats'][-1]['url']
|
||||
except:
|
||||
url = "#"
|
||||
try:
|
||||
primaryInfo = {
|
||||
"id": details['videoId'],
|
||||
"title": details['title'],
|
||||
"description": details['shortDescription'],
|
||||
"views": details['viewCount'],
|
||||
"views": views,
|
||||
"duration": details['lengthSeconds'],
|
||||
"date": item['dateText']['simpleText'],
|
||||
"rating": details['averageRating'],
|
||||
@ -53,9 +62,10 @@ def get_video_primary_info(datad, datai):
|
||||
"rating": details['averageRating'],
|
||||
"author": details['author'],
|
||||
"isPrivate":False,
|
||||
"isLive":False,
|
||||
"isUpcoming":False,
|
||||
"isLive":details['isLiveContent'],
|
||||
"isUpcoming":isUpcoming,
|
||||
"allowRatings":True,
|
||||
"url":url,
|
||||
"thumbnail": details['thumbnail']['thumbnails'][0]['url']
|
||||
}
|
||||
return primaryInfo
|
||||
|
Reference in New Issue
Block a user