-
-
Notifications
You must be signed in to change notification settings - Fork 6k
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
[ie/niconico] correctly check if the user has access to the video #9338
[ie/niconico] correctly check if the user has access to the video #9338
Conversation
> Can't we just check if api_data["media"] exists or not? Of course, I agree. Videos for Premium users do not work with this check. If the user gets no format, they do not have access to that video.
What do you think about trying to extract the video's availability, moving up the formats extraction code, and only raising for login if no formats are found? e.g.: diff --git a/yt_dlp/extractor/niconico.py b/yt_dlp/extractor/niconico.py
index 05a1a3ddb..e78d2503b 100644
--- a/yt_dlp/extractor/niconico.py
+++ b/yt_dlp/extractor/niconico.py
@@ -478,15 +478,17 @@ def _real_extract(self, url):
raise
raise ExtractorError(clean_html(error_msg), expected=True)
- club_joined = traverse_obj(api_data, ('channel', 'viewer', 'follow', 'isFollowed', {bool}))
- if club_joined is None:
- fail_msg = self._html_search_regex(
- r'<p[^>]+\bclass="fail-message"[^>]*>(?P<msg>.+?)</p>',
- webpage, 'fail message', default=None, group='msg')
- if fail_msg:
- self.raise_login_required(clean_html(fail_msg), metadata_available=True)
- elif not club_joined:
- self.raise_login_required('This video is for members only', metadata_available=True)
+ availability = self._availability(**traverse_obj(api_data, ('payment', 'video', {
+ 'needs_premium': ('isPremium', {bool}),
+ 'needs_subscription': ('watchableUserType', {lambda x: x and x != 'all'}),
+ })))
+ formats = [*self._yield_dmc_formats(api_data, video_id),
+ *self._yield_dms_formats(api_data, video_id)]
+ if not formats:
+ if availability == 'premium_only':
+ self.raise_login_required('This video requires premium', metadata_available=True)
+ elif availability == 'subscriber_only':
+ self.raise_login_required('This video is for members only', metadata_available=True)
# Start extracting information
tags = None
@@ -512,8 +514,8 @@ def get_video_info(*items, get_first=True, **kwargs):
'id': video_id,
'_api_data': api_data,
'title': get_video_info(('originalTitle', 'title')) or self._og_search_title(webpage, default=None),
- 'formats': [*self._yield_dmc_formats(api_data, video_id),
- *self._yield_dms_formats(api_data, video_id)],
+ 'formats': formats,
+ 'availability': availability,
'thumbnails': [{
'id': key,
'url': url, I based this logic on what @fireattack posted here, but it may need some correcting by someone who has a better understanding of the site than I do. Apparently there is PPV content as well? Is that the same as fanclub-only content? If it's not the same, then we don't currently have an appropriate availability = self._availability(**traverse_obj(api_data, ('payment', 'video', {
'needs_purchase': ('watchableUserType', {lambda x: x == 'purchaser'}), # TODO: add 'needs_purchase' param
'needs_premium': ('isPremium', {bool}),
'needs_subscription': ('watchableUserType', {lambda x: x and x != 'all'}),
})))
formats = [*self._yield_dmc_formats(api_data, video_id),
*self._yield_dms_formats(api_data, video_id)]
if not formats:
if availability == 'ppv_only': # TODO: add 'ppv_only' value
self.raise_login_required('This video requires purchase', metadata_available=True)
elif availability == 'premium_only':
self.raise_login_required('This video requires premium', metadata_available=True)
elif availability == 'subscriber_only':
self.raise_login_required('This video is for members only', metadata_available=True) |
yt-dlp_master(2024/03/01) + #9338 patch
yt-dlp_master(2024/03/01) + bashonly patch
|
Co-authored-by: bashonly <88596187+bashonly@users.noreply.github.com>
See 303b35d . I tested Niconico with Japan IP. For users:
For the extracted data:
In addition:
Hence, things become easier:
CALL FOR HELPPlease test the code. Thank you in advance! |
Thanks for the hard work, @pzhlkj6612. What would happen if someone visit any Japan-IP-only content without a Japan IP? |
@fireattack do you have a region-locked example URL? I could test |
@fireattack , thanks for your comment.
I forgot it! Tested it just now:
See so43309069 - 戦国妖狐 世直し姉弟編 #3「永禄七年」 アニメ/動画 - ニコニコ動画 . So, where to put the code about geo-restriction? |
Authored by: bashonly
Added a geo-restriction check, and this LGTM |
Authored by: bashonly
Authored by: bashonly
Hi @bashonly ,
If geo-restriction applied, no metadata available since the Or maybe I mis-understand what metadata is? |
i was still able to extract metadata (title, etc) for videos from which i was geo-blocked |
OK, i tested and got partial info: {
"id": "so43309069",
"_api_data": {},
"title": "戦国妖狐 世直し姉弟編 #3「永禄七年」",
"formats": [],
"thumbnails": [],
"tags": [],
"duration": 1419.0,
"webpage_url": "https://www.nicovideo.jp/watch/so43309069",
"webpage_url_basename": "so43309069",
"webpage_url_domain": "nicovideo.jp",
"extractor": "niconico",
"extractor_key": "Niconico",
"display_id": "so43309069",
"fulltitle": "戦国妖狐 世直し姉弟編 #3「永禄七年」",
"duration_string": "23:39",
it's better than no metadata! 🚀 |
Closes yt-dlp#9351 Authored by: pzhlkj6612
IMPORTANT: PRs without the template will be CLOSED
Description of your pull request and other information
This PR is a quick fix about a failed modification in #9282 .
Of course, I agree.
Videos for Premium users do not work with this check. If the user gets no format, they do not have access to that video.
Credits
Thanks to @betsu0 for the detailed feedback. Thanks to @fireattack for the professional analysis.
Template
Before submitting a pull request make sure you have:
In order to be accepted and merged into yt-dlp each piece of code must be in public domain or released under Unlicense. Check all of the following options that apply:
What is the purpose of your pull request?