Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
XianxinMao
Yt Dlp
提交
c888ffb9
Y
Yt Dlp
项目概览
XianxinMao
/
Yt Dlp
11 个月 前同步成功
通知
27
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Y
Yt Dlp
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
c888ffb9
编写于
7月 14, 2021
作者:
C
coletdjnz
提交者:
GitHub
7月 14, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[youtube] Use android client as default and add age-gate bypass for it (#492)
Authored by: colethedj
上级
97524332
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
36 addition
and
21 deletion
+36
-21
yt_dlp/extractor/youtube.py
yt_dlp/extractor/youtube.py
+36
-21
未找到文件。
yt_dlp/extractor/youtube.py
浏览文件 @
c888ffb9
...
...
@@ -2249,14 +2249,24 @@ def _generate_player_context(sts=None):
}
@
staticmethod
def
_get_video_info_params
(
video_id
):
return
{
def
_get_video_info_params
(
video_id
,
client
=
'TVHTML5'
):
GVI_CLIENTS
=
{
'ANDROID'
:
{
'c'
:
'ANDROID'
,
'cver'
:
'16.20'
,
},
'TVHTML5'
:
{
'c'
:
'TVHTML5'
,
'cver'
:
'6.20180913'
,
}
}
query
=
{
'video_id'
:
video_id
,
'eurl'
:
'https://youtube.googleapis.com/v/'
+
video_id
,
'html5'
:
'1'
,
'c'
:
'TVHTML5'
,
'cver'
:
'6.20180913'
,
'html5'
:
'1'
}
query
.
update
(
GVI_CLIENTS
.
get
(
client
))
return
query
def
_real_extract
(
self
,
url
):
url
,
smuggled_data
=
unsmuggle_url
(
url
,
{})
...
...
@@ -2278,8 +2288,8 @@ def _real_extract(self, url):
player_client
=
self
.
_configuration_arg
(
'player_client'
,
[
''
])[
0
]
if
player_client
not
in
(
'web'
,
'android'
,
''
):
self
.
report_warning
(
f
'Invalid player_client
{
player_client
}
given. Falling back to
WEB
'
)
force_mobile_client
=
player_client
==
'android
'
self
.
report_warning
(
f
'Invalid player_client
{
player_client
}
given. Falling back to
android client.
'
)
force_mobile_client
=
player_client
!=
'web
'
player_skip
=
self
.
_configuration_arg
(
'player_skip'
)
def
get_text
(
x
):
...
...
@@ -2308,7 +2318,7 @@ def get_text(x):
# Android client already has signature descrambled
# See: https://github.com/TeamNewPipe/NewPipeExtractor/issues/562
if
not
sts
:
self
.
report_warning
(
'Falling back to
mobile
remix client for player API.'
)
self
.
report_warning
(
'Falling back to
android
remix client for player API.'
)
ytm_client
=
'ANDROID_MUSIC'
ytm_cfg
=
{}
...
...
@@ -2322,7 +2332,7 @@ def get_text(x):
item_id
=
video_id
,
ep
=
'player'
,
query
=
ytm_query
,
ytcfg
=
ytm_cfg
,
headers
=
ytm_headers
,
fatal
=
False
,
default_client
=
ytm_client
,
note
=
'Downloading %sremix player API JSON'
%
(
'
mobile
'
if
force_mobile_client
else
''
))
note
=
'Downloading %sremix player API JSON'
%
(
'
android
'
if
force_mobile_client
else
''
))
ytm_streaming_data
=
try_get
(
ytm_player_response
,
lambda
x
:
x
[
'streamingData'
],
dict
)
or
{}
player_response
=
None
...
...
@@ -2340,7 +2350,7 @@ def get_text(x):
# Android client already has signature descrambled
# See: https://github.com/TeamNewPipe/NewPipeExtractor/issues/562
if
not
sts
:
self
.
report_warning
(
'Falling back to
mobile
client for player API.'
)
self
.
report_warning
(
'Falling back to
android
client for player API.'
)
yt_client
=
'ANDROID'
ytpcfg
=
{}
ytp_headers
=
self
.
_generate_api_headers
(
ytpcfg
,
identity_token
,
syncid
,
yt_client
)
...
...
@@ -2351,19 +2361,24 @@ def get_text(x):
item_id
=
video_id
,
ep
=
'player'
,
query
=
yt_query
,
ytcfg
=
ytpcfg
,
headers
=
ytp_headers
,
fatal
=
False
,
default_client
=
yt_client
,
note
=
'Downloading %splayer API JSON'
%
(
'
mobile
'
if
force_mobile_client
else
''
)
)
note
=
'Downloading %splayer API JSON'
%
(
'
android
'
if
force_mobile_client
else
''
)
)
or
player_response
# Age-gate workarounds
playability_status
=
player_response
.
get
(
'playabilityStatus'
)
or
{}
if
playability_status
.
get
(
'reason'
)
in
self
.
_AGE_GATE_REASONS
:
pr
=
self
.
_parse_json
(
try_get
(
compat_parse_qs
(
self
.
_download_webpage
(
base_url
+
'get_video_info'
,
video_id
,
'Refetching age-gated info webpage'
,
'unable to download video info webpage'
,
query
=
self
.
_get_video_info_params
(
video_id
),
fatal
=
False
)),
lambda
x
:
x
[
'player_response'
][
0
],
compat_str
)
or
'{}'
,
video_id
)
gvi_clients
=
(
'ANDROID'
,
'TVHTML5'
)
if
force_mobile_client
else
(
'TVHTML5'
,
'ANDROID'
)
for
gvi_client
in
gvi_clients
:
pr
=
self
.
_parse_json
(
try_get
(
compat_parse_qs
(
self
.
_download_webpage
(
base_url
+
'get_video_info'
,
video_id
,
'Refetching age-gated %s info webpage'
%
gvi_client
.
lower
(),
'unable to download video info webpage'
,
fatal
=
False
,
query
=
self
.
_get_video_info_params
(
video_id
,
client
=
gvi_client
))),
lambda
x
:
x
[
'player_response'
][
0
],
compat_str
)
or
'{}'
,
video_id
)
if
pr
:
break
if
not
pr
:
self
.
report_warning
(
'Falling back to embedded-only age-gate workaround.'
)
embed_webpage
=
None
...
...
@@ -2386,7 +2401,7 @@ def get_text(x):
# See: https://github.com/TeamNewPipe/NewPipeExtractor/issues/562
if
not
sts
:
self
.
report_warning
(
'Falling back to
mobile
embedded client for player API (note: some formats may be missing).'
)
'Falling back to
android
embedded client for player API (note: some formats may be missing).'
)
yt_client
=
'ANDROID_EMBEDDED_PLAYER'
ytcfg_age
=
{}
...
...
@@ -2398,7 +2413,7 @@ def get_text(x):
item_id
=
video_id
,
ep
=
'player'
,
query
=
yt_age_query
,
ytcfg
=
ytcfg_age
,
headers
=
ytage_headers
,
fatal
=
False
,
default_client
=
yt_client
,
note
=
'Downloading %sage-gated player API JSON'
%
(
'
mobile
'
if
force_mobile_client
else
''
)
note
=
'Downloading %sage-gated player API JSON'
%
(
'
android
'
if
force_mobile_client
else
''
)
)
or
{}
if
pr
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录