Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add endcard #139

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions youtube/templates/watch.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@
"external-player-controls v-checkbox"
"v-direct-link v-direct-link"
"v-download v-download"
"v-endcard v-endcard"
"v-description v-description"
"v-music-list v-music-list"
"v-more-info v-more-info";
Expand Down Expand Up @@ -217,6 +218,13 @@
.video-info > .download-dropdown{
grid-area: v-download;
}
.video-info > .endcard-dropdown{
margin-top: 2px;
grid-area: v-endcard;
}
.video-info > .endcard-dropdown .item-box {
width: 100%;
}
.video-info > .description{
background-color:var(--interface-color);
margin-top:8px;
Expand Down Expand Up @@ -343,7 +351,7 @@
width: 120px !important;
}

.download-dropdown-content{
.dropdown-content {
background-color: var(--interface-color);
padding: 10px;
list-style: none;
Expand Down Expand Up @@ -428,6 +436,7 @@
"external-player-controls v-checkbox"
"v-direct-link v-direct-link"
"v-download v-download"
"v-endcard v-endcard"
"v-description v-description"
"v-music-list v-music-list"
"v-more-info v-more-info";
Expand Down Expand Up @@ -532,7 +541,7 @@ <h2 class="title">{{ title }}</h2>

<details class="download-dropdown">
<summary class="download-dropdown-label">Download</summary>
<ul class="download-dropdown-content">
<ul class="dropdown-content">
{% for format in download_formats %}
<li class="download-format">
<a class="download-link" href="{{ format['url'] }}">
Expand All @@ -559,6 +568,17 @@ <h2 class="title">{{ title }}</h2>
</ul>
</details>

{% if endcard %}
<details class="endcard-dropdown">
<summary>Endcard</summary>
<div class="dropdown-content">
{% for e in endcard %}
{{ common_elements.item(e) }}
<!-- {{ e }} -->
{% endfor %}
</div>
</details>
{% endif %}
Comment on lines +571 to +581
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add the video at the top of the related videos similar to the layout in YouTube's "Watch Next" feature instead of adding another button to the interface?


<span class="description">{{ common_elements.text_runs(description)|escape|urlize|timestamps|safe }}</span>
<div class="music-list">
Expand Down
1 change: 1 addition & 0 deletions youtube/watch.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ def get_watch_page(video_id=None):
invidious_reload_button = info['invidious_reload_button'],
video_url = util.URL_ORIGIN + '/watch?v=' + video_id,
video_id = video_id,
endcard = info['endcard'],

js_data = {
'video_id': info['id'],
Expand Down
9 changes: 9 additions & 0 deletions youtube/yt_data_extract/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,3 +570,12 @@ def extract_items(response, item_types=_item_types,
ctoken = new_ctoken

return items, ctoken

def dbg_assert(val, msg):
import os
if val: return

if os.getenv('YT_EXTR_DBG'):
raise AssertionError(msg)
else:
print(f"W: {msg}")
Comment on lines +573 to +581
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove, don't want to add an ad-hoc debugging framework just for logging unknown ctypes. Especially not one that uses os environment variables instead of the in-built settings. Can think about adding better debugging message handling in youtube-local in the future but not like this

30 changes: 29 additions & 1 deletion youtube/yt_data_extract/watch_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
extract_str, extract_formatted_text, extract_int, extract_approx_int,
extract_date, check_missing_keys, extract_item_info, extract_items,
extract_response, concat_or_none, liberal_dict_update,
conservative_dict_update)
conservative_dict_update, dbg_assert)

import json
import urllib.parse
Expand Down Expand Up @@ -752,6 +752,27 @@ def extract_watch_info_from_html(watch_html):
def captions_available(info):
return bool(info['_captions_base_url'])

def parse_endcard(card):
"""
parses a single endcard into a format that's easier to handle.
from: https://git.gir.st/subscriptionfeed.git/blob/737a2f6f:/app/common/innertube.py#l301
"""
card = card.get('endscreenElementRenderer', card) #only sometimes nested
ctype = card['style'].lower()
if ctype == "video":
if not 'endpoint' in card: return None # title == "This video is unavailable."
video_id = card['endpoint']['watchEndpoint']['videoId']
return {'type': ctype,
'video_id': video_id,
'title': extract_str(card['title']),
'approx_view_count': extract_str(card['metadata']),
'thumbnail': f"/https://i.ytimg.com/vi/{video_id}/default.jpg",
'duration': extract_str(card["thumbnailOverlays"][0]["thumbnailOverlayTimeStatusRenderer"]["text"])
# XXX: no channel name
}
Comment on lines +755 to +772
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code needs to use the deep_get function. Never extract information from json like this: card['endpoint']['watchEndpoint']['videoId'], that will cause the entire code to fail when YouTube changes their json.

Also some lines need to be split up onto multiple lines to not exceed 79 character line limit. And use ', not ", for strings. See https://github.com/user234683/youtube-local/blob/master/HACKING.md for coding guidelines

else:
dbg_assert(False, f"unknown ctype: {ctype}")


def get_caption_url(info, language, format, automatic=False, translation_language=None):
'''Gets the url for captions with the given language and format. If automatic is True, get the automatic captions for that language. If translation_language is given, translate the captions from `language` to `translation_language`. If automatic is true and translation_language is given, the automatic captions will be translated.'''
Expand Down Expand Up @@ -780,6 +801,13 @@ def update_with_age_restricted_info(info, player_response):
info['playability_error'] = ERROR_PREFIX + 'Failed to parse json response'
return

info['endcard'] = []
for e in deep_get(player_response, "endscreen", "endscreenRenderer", "elements", default=[]):
e = parse_endcard(e["endscreenElementRenderer"])
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use get function

if not e: continue
info['endcard'].append(e)
print(info['endcard'][-1])

_extract_formats(info, player_response)
_extract_playability_error(info, player_response, error_prefix=ERROR_PREFIX)

Expand Down