mirror of
https://github.com/l1ving/youtube-dl
synced 2025-03-11 08:07:15 +08:00
commit
844a0c2285
6
.github/ISSUE_TEMPLATE/1_broken_site.md
vendored
6
.github/ISSUE_TEMPLATE/1_broken_site.md
vendored
@ -18,7 +18,7 @@ title: ''
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
||||||
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.02. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.12. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
||||||
- Make sure that all provided video/audio/playlist URLs (if any) are alive and playable in a browser.
|
- Make sure that all provided video/audio/playlist URLs (if any) are alive and playable in a browser.
|
||||||
- Make sure that all URLs and arguments with special characters are properly quoted or escaped as explained in http://yt-dl.org/escape.
|
- Make sure that all URLs and arguments with special characters are properly quoted or escaped as explained in http://yt-dl.org/escape.
|
||||||
- Search the bugtracker for similar issues: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
- Search the bugtracker for similar issues: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
||||||
@ -26,7 +26,7 @@ Carefully read and work through this check list in order to prevent the most com
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] I'm reporting a broken site support
|
- [ ] I'm reporting a broken site support
|
||||||
- [ ] I've verified that I'm running youtube-dl version **2019.07.02**
|
- [ ] I've verified that I'm running youtube-dl version **2019.07.12**
|
||||||
- [ ] I've checked that all provided URLs are alive and playable in a browser
|
- [ ] I've checked that all provided URLs are alive and playable in a browser
|
||||||
- [ ] I've checked that all URLs and arguments with special characters are properly quoted or escaped
|
- [ ] I've checked that all URLs and arguments with special characters are properly quoted or escaped
|
||||||
- [ ] I've searched the bugtracker for similar issues including closed ones
|
- [ ] I've searched the bugtracker for similar issues including closed ones
|
||||||
@ -41,7 +41,7 @@ Add the `-v` flag to your command line you run youtube-dl with (`youtube-dl -v <
|
|||||||
[debug] User config: []
|
[debug] User config: []
|
||||||
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
||||||
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
||||||
[debug] youtube-dl version 2019.07.02
|
[debug] youtube-dl version 2019.07.12
|
||||||
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
||||||
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
||||||
[debug] Proxy map: {}
|
[debug] Proxy map: {}
|
||||||
|
@ -19,7 +19,7 @@ labels: 'site-support-request'
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
||||||
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.02. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.12. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
||||||
- Make sure that all provided video/audio/playlist URLs (if any) are alive and playable in a browser.
|
- Make sure that all provided video/audio/playlist URLs (if any) are alive and playable in a browser.
|
||||||
- Make sure that site you are requesting is not dedicated to copyright infringement, see https://yt-dl.org/copyright-infringement. youtube-dl does not support such sites. In order for site support request to be accepted all provided example URLs should not violate any copyrights.
|
- Make sure that site you are requesting is not dedicated to copyright infringement, see https://yt-dl.org/copyright-infringement. youtube-dl does not support such sites. In order for site support request to be accepted all provided example URLs should not violate any copyrights.
|
||||||
- Search the bugtracker for similar site support requests: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
- Search the bugtracker for similar site support requests: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
||||||
@ -27,7 +27,7 @@ Carefully read and work through this check list in order to prevent the most com
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] I'm reporting a new site support request
|
- [ ] I'm reporting a new site support request
|
||||||
- [ ] I've verified that I'm running youtube-dl version **2019.07.02**
|
- [ ] I've verified that I'm running youtube-dl version **2019.07.12**
|
||||||
- [ ] I've checked that all provided URLs are alive and playable in a browser
|
- [ ] I've checked that all provided URLs are alive and playable in a browser
|
||||||
- [ ] I've checked that none of provided URLs violate any copyrights
|
- [ ] I've checked that none of provided URLs violate any copyrights
|
||||||
- [ ] I've searched the bugtracker for similar site support requests including closed ones
|
- [ ] I've searched the bugtracker for similar site support requests including closed ones
|
||||||
|
@ -18,13 +18,13 @@ title: ''
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
||||||
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.02. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.12. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
||||||
- Search the bugtracker for similar site feature requests: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
- Search the bugtracker for similar site feature requests: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
||||||
- Finally, put x into all relevant boxes (like this [x])
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] I'm reporting a site feature request
|
- [ ] I'm reporting a site feature request
|
||||||
- [ ] I've verified that I'm running youtube-dl version **2019.07.02**
|
- [ ] I've verified that I'm running youtube-dl version **2019.07.12**
|
||||||
- [ ] I've searched the bugtracker for similar site feature requests including closed ones
|
- [ ] I've searched the bugtracker for similar site feature requests including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
6
.github/ISSUE_TEMPLATE/4_bug_report.md
vendored
6
.github/ISSUE_TEMPLATE/4_bug_report.md
vendored
@ -18,7 +18,7 @@ title: ''
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
||||||
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.02. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.12. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
||||||
- Make sure that all provided video/audio/playlist URLs (if any) are alive and playable in a browser.
|
- Make sure that all provided video/audio/playlist URLs (if any) are alive and playable in a browser.
|
||||||
- Make sure that all URLs and arguments with special characters are properly quoted or escaped as explained in http://yt-dl.org/escape.
|
- Make sure that all URLs and arguments with special characters are properly quoted or escaped as explained in http://yt-dl.org/escape.
|
||||||
- Search the bugtracker for similar issues: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
- Search the bugtracker for similar issues: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
||||||
@ -27,7 +27,7 @@ Carefully read and work through this check list in order to prevent the most com
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] I'm reporting a broken site support issue
|
- [ ] I'm reporting a broken site support issue
|
||||||
- [ ] I've verified that I'm running youtube-dl version **2019.07.02**
|
- [ ] I've verified that I'm running youtube-dl version **2019.07.12**
|
||||||
- [ ] I've checked that all provided URLs are alive and playable in a browser
|
- [ ] I've checked that all provided URLs are alive and playable in a browser
|
||||||
- [ ] I've checked that all URLs and arguments with special characters are properly quoted or escaped
|
- [ ] I've checked that all URLs and arguments with special characters are properly quoted or escaped
|
||||||
- [ ] I've searched the bugtracker for similar bug reports including closed ones
|
- [ ] I've searched the bugtracker for similar bug reports including closed ones
|
||||||
@ -43,7 +43,7 @@ Add the `-v` flag to your command line you run youtube-dl with (`youtube-dl -v <
|
|||||||
[debug] User config: []
|
[debug] User config: []
|
||||||
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
||||||
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
||||||
[debug] youtube-dl version 2019.07.02
|
[debug] youtube-dl version 2019.07.12
|
||||||
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
||||||
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
||||||
[debug] Proxy map: {}
|
[debug] Proxy map: {}
|
||||||
|
4
.github/ISSUE_TEMPLATE/5_feature_request.md
vendored
4
.github/ISSUE_TEMPLATE/5_feature_request.md
vendored
@ -19,13 +19,13 @@ labels: 'request'
|
|||||||
|
|
||||||
<!--
|
<!--
|
||||||
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
||||||
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.02. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
- First of, make sure you are using the latest version of youtube-dl. Run `youtube-dl --version` and ensure your version is 2019.07.12. If it's not, see https://yt-dl.org/update on how to update. Issues with outdated version will be REJECTED.
|
||||||
- Search the bugtracker for similar feature requests: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
- Search the bugtracker for similar feature requests: http://yt-dl.org/search-issues. DO NOT post duplicates.
|
||||||
- Finally, put x into all relevant boxes (like this [x])
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
-->
|
-->
|
||||||
|
|
||||||
- [ ] I'm reporting a feature request
|
- [ ] I'm reporting a feature request
|
||||||
- [ ] I've verified that I'm running youtube-dl version **2019.07.02**
|
- [ ] I've verified that I'm running youtube-dl version **2019.07.12**
|
||||||
- [ ] I've searched the bugtracker for similar feature requests including closed ones
|
- [ ] I've searched the bugtracker for similar feature requests including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
26
ChangeLog
26
ChangeLog
@ -1,3 +1,29 @@
|
|||||||
|
version 2019.07.12
|
||||||
|
|
||||||
|
Core
|
||||||
|
+ [adobepass] Add support for AT&T U-verse (mso ATT) (#13938, #21016)
|
||||||
|
|
||||||
|
Extractors
|
||||||
|
+ [mgtv] Pass Referer HTTP header for format URLs (#21726)
|
||||||
|
+ [beeg] Add support for api/v6 v2 URLs without t argument (#21701)
|
||||||
|
* [voxmedia:volume] Improvevox embed extraction (#16846)
|
||||||
|
* [funnyordie] Move extraction to VoxMedia extractor (#16846)
|
||||||
|
* [gameinformer] Fix extraction (#8895, #15363, #17206)
|
||||||
|
* [funk] Fix extraction (#17915)
|
||||||
|
* [packtpub] Relax lesson URL regular expression (#21695)
|
||||||
|
* [packtpub] Fix extraction (#21268)
|
||||||
|
* [philharmoniedeparis] Relax URL regular expression (#21672)
|
||||||
|
* [peertube] Detect embed URLs in generic extraction (#21666)
|
||||||
|
* [mixer:vod] Relax URL regular expression (#21657, #21658)
|
||||||
|
+ [lecturio] Add support id based URLs (#21630)
|
||||||
|
+ [go] Add site info for disneynow (#21613)
|
||||||
|
* [ted] Restrict info regular expression (#21631)
|
||||||
|
* [twitch:vod] Actualize m3u8 URL (#21538, #21607)
|
||||||
|
* [vzaar] Fix videos with empty title (#21606)
|
||||||
|
* [tvland] Fix extraction (#21384)
|
||||||
|
* [arte] Clean extractor (#15583, #21614)
|
||||||
|
|
||||||
|
|
||||||
version 2019.07.02
|
version 2019.07.02
|
||||||
|
|
||||||
Core
|
Core
|
||||||
|
@ -58,16 +58,8 @@
|
|||||||
- **ARD:mediathek**
|
- **ARD:mediathek**
|
||||||
- **ARDBetaMediathek**
|
- **ARDBetaMediathek**
|
||||||
- **Arkena**
|
- **Arkena**
|
||||||
- **arte.tv**
|
|
||||||
- **arte.tv:+7**
|
- **arte.tv:+7**
|
||||||
- **arte.tv:cinema**
|
|
||||||
- **arte.tv:concert**
|
|
||||||
- **arte.tv:creative**
|
|
||||||
- **arte.tv:ddc**
|
|
||||||
- **arte.tv:embed**
|
- **arte.tv:embed**
|
||||||
- **arte.tv:future**
|
|
||||||
- **arte.tv:info**
|
|
||||||
- **arte.tv:magazine**
|
|
||||||
- **arte.tv:playlist**
|
- **arte.tv:playlist**
|
||||||
- **AsianCrush**
|
- **AsianCrush**
|
||||||
- **AsianCrushPlaylist**
|
- **AsianCrushPlaylist**
|
||||||
@ -313,9 +305,7 @@
|
|||||||
- **FrontendMastersCourse**
|
- **FrontendMastersCourse**
|
||||||
- **FrontendMastersLesson**
|
- **FrontendMastersLesson**
|
||||||
- **Funimation**
|
- **Funimation**
|
||||||
- **FunkChannel**
|
- **Funk**
|
||||||
- **FunkMix**
|
|
||||||
- **FunnyOrDie**
|
|
||||||
- **Fusion**
|
- **Fusion**
|
||||||
- **Fux**
|
- **Fux**
|
||||||
- **FXNetworks**
|
- **FXNetworks**
|
||||||
@ -896,7 +886,6 @@
|
|||||||
- **TF1**
|
- **TF1**
|
||||||
- **TFO**
|
- **TFO**
|
||||||
- **TheIntercept**
|
- **TheIntercept**
|
||||||
- **theoperaplatform**
|
|
||||||
- **ThePlatform**
|
- **ThePlatform**
|
||||||
- **ThePlatformFeed**
|
- **ThePlatformFeed**
|
||||||
- **TheScene**
|
- **TheScene**
|
||||||
|
@ -15,10 +15,13 @@ class AbcNewsVideoIE(AMPIE):
|
|||||||
IE_NAME = 'abcnews:video'
|
IE_NAME = 'abcnews:video'
|
||||||
_VALID_URL = r'''(?x)
|
_VALID_URL = r'''(?x)
|
||||||
https?://
|
https?://
|
||||||
|
(?:
|
||||||
abcnews\.go\.com/
|
abcnews\.go\.com/
|
||||||
(?:
|
(?:
|
||||||
[^/]+/video/(?P<display_id>[0-9a-z-]+)-|
|
[^/]+/video/(?P<display_id>[0-9a-z-]+)-|
|
||||||
video/embed\?.*?\bid=
|
video/embed\?.*?\bid=
|
||||||
|
)|
|
||||||
|
fivethirtyeight\.abcnews\.go\.com/video/embed/\d+/
|
||||||
)
|
)
|
||||||
(?P<id>\d+)
|
(?P<id>\d+)
|
||||||
'''
|
'''
|
||||||
|
@ -32,6 +32,10 @@ class BeegIE(InfoExtractor):
|
|||||||
# api/v6 v2
|
# api/v6 v2
|
||||||
'url': 'https://beeg.com/1941093077?t=911-1391',
|
'url': 'https://beeg.com/1941093077?t=911-1391',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
# api/v6 v2 w/o t
|
||||||
|
'url': 'https://beeg.com/1277207756',
|
||||||
|
'only_matching': True,
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://beeg.porn/video/5416503',
|
'url': 'https://beeg.porn/video/5416503',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
@ -49,14 +53,17 @@ class BeegIE(InfoExtractor):
|
|||||||
r'beeg_version\s*=\s*([\da-zA-Z_-]+)', webpage, 'beeg version',
|
r'beeg_version\s*=\s*([\da-zA-Z_-]+)', webpage, 'beeg version',
|
||||||
default='1546225636701')
|
default='1546225636701')
|
||||||
|
|
||||||
|
if len(video_id) >= 10:
|
||||||
|
query = {
|
||||||
|
'v': 2,
|
||||||
|
}
|
||||||
qs = compat_urlparse.parse_qs(compat_urlparse.urlparse(url).query)
|
qs = compat_urlparse.parse_qs(compat_urlparse.urlparse(url).query)
|
||||||
t = qs.get('t', [''])[0].split('-')
|
t = qs.get('t', [''])[0].split('-')
|
||||||
if len(t) > 1:
|
if len(t) > 1:
|
||||||
query = {
|
query.update({
|
||||||
'v': 2,
|
|
||||||
's': t[0],
|
's': t[0],
|
||||||
'e': t[1],
|
'e': t[1],
|
||||||
}
|
})
|
||||||
else:
|
else:
|
||||||
query = {'v': 1}
|
query = {'v': 1}
|
||||||
|
|
||||||
|
@ -216,17 +216,14 @@ class FiveThirtyEightIE(InfoExtractor):
|
|||||||
_TEST = {
|
_TEST = {
|
||||||
'url': 'http://fivethirtyeight.com/features/how-the-6-8-raiders-can-still-make-the-playoffs/',
|
'url': 'http://fivethirtyeight.com/features/how-the-6-8-raiders-can-still-make-the-playoffs/',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '21846851',
|
'id': '56032156',
|
||||||
'ext': 'mp4',
|
'ext': 'flv',
|
||||||
'title': 'FiveThirtyEight: The Raiders can still make the playoffs',
|
'title': 'FiveThirtyEight: The Raiders can still make the playoffs',
|
||||||
'description': 'Neil Paine breaks down the simplest scenario that will put the Raiders into the playoffs at 8-8.',
|
'description': 'Neil Paine breaks down the simplest scenario that will put the Raiders into the playoffs at 8-8.',
|
||||||
'timestamp': 1513960621,
|
|
||||||
'upload_date': '20171222',
|
|
||||||
},
|
},
|
||||||
'params': {
|
'params': {
|
||||||
'skip_download': True,
|
'skip_download': True,
|
||||||
},
|
},
|
||||||
'expected_warnings': ['Unable to download f4m manifest'],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
@ -234,9 +231,8 @@ class FiveThirtyEightIE(InfoExtractor):
|
|||||||
|
|
||||||
webpage = self._download_webpage(url, video_id)
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
|
||||||
video_id = self._search_regex(
|
embed_url = self._search_regex(
|
||||||
r'data-video-id=["\'](?P<id>\d+)',
|
r'<iframe[^>]+src=["\'](https?://fivethirtyeight\.abcnews\.go\.com/video/embed/\d+/\d+)',
|
||||||
webpage, 'video id', group='id')
|
webpage, 'embed url')
|
||||||
|
|
||||||
return self.url_result(
|
return self.url_result(embed_url, 'AbcNewsVideo')
|
||||||
'http://espn.go.com/video/clip?id=%s' % video_id, ESPNIE.ie_key())
|
|
||||||
|
@ -395,11 +395,7 @@ from .frontendmasters import (
|
|||||||
FrontendMastersCourseIE
|
FrontendMastersCourseIE
|
||||||
)
|
)
|
||||||
from .funimation import FunimationIE
|
from .funimation import FunimationIE
|
||||||
from .funk import (
|
from .funk import FunkIE
|
||||||
FunkMixIE,
|
|
||||||
FunkChannelIE,
|
|
||||||
)
|
|
||||||
from .funnyordie import FunnyOrDieIE
|
|
||||||
from .fusion import FusionIE
|
from .fusion import FusionIE
|
||||||
from .fxnetworks import FXNetworksIE
|
from .fxnetworks import FXNetworksIE
|
||||||
from .gaia import GaiaIE
|
from .gaia import GaiaIE
|
||||||
|
@ -9,7 +9,7 @@ from ..utils import int_or_none
|
|||||||
|
|
||||||
class FiveTVIE(InfoExtractor):
|
class FiveTVIE(InfoExtractor):
|
||||||
_VALID_URL = r'''(?x)
|
_VALID_URL = r'''(?x)
|
||||||
http://
|
https?://
|
||||||
(?:www\.)?5-tv\.ru/
|
(?:www\.)?5-tv\.ru/
|
||||||
(?:
|
(?:
|
||||||
(?:[^/]+/)+(?P<id>\d+)|
|
(?:[^/]+/)+(?P<id>\d+)|
|
||||||
@ -39,6 +39,7 @@ class FiveTVIE(InfoExtractor):
|
|||||||
'duration': 180,
|
'duration': 180,
|
||||||
},
|
},
|
||||||
}, {
|
}, {
|
||||||
|
# redirect to https://www.5-tv.ru/projects/1000095/izvestia-glavnoe/
|
||||||
'url': 'http://www.5-tv.ru/glavnoe/#itemDetails',
|
'url': 'http://www.5-tv.ru/glavnoe/#itemDetails',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': 'glavnoe',
|
'id': 'glavnoe',
|
||||||
@ -46,6 +47,7 @@ class FiveTVIE(InfoExtractor):
|
|||||||
'title': r're:^Итоги недели с \d+ по \d+ \w+ \d{4} года$',
|
'title': r're:^Итоги недели с \d+ по \d+ \w+ \d{4} года$',
|
||||||
'thumbnail': r're:^https?://.*\.jpg$',
|
'thumbnail': r're:^https?://.*\.jpg$',
|
||||||
},
|
},
|
||||||
|
'skip': 'redirect to «Известия. Главное» project page',
|
||||||
}, {
|
}, {
|
||||||
'url': 'http://www.5-tv.ru/glavnoe/broadcasts/508645/',
|
'url': 'http://www.5-tv.ru/glavnoe/broadcasts/508645/',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
@ -70,7 +72,7 @@ class FiveTVIE(InfoExtractor):
|
|||||||
webpage = self._download_webpage(url, video_id)
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
|
||||||
video_url = self._search_regex(
|
video_url = self._search_regex(
|
||||||
[r'<div[^>]+?class="flowplayer[^>]+?data-href="([^"]+)"',
|
[r'<div[^>]+?class="(?:flow)?player[^>]+?data-href="([^"]+)"',
|
||||||
r'<a[^>]+?href="([^"]+)"[^>]+?class="videoplayer"'],
|
r'<a[^>]+?href="([^"]+)"[^>]+?class="videoplayer"'],
|
||||||
webpage, 'video url')
|
webpage, 'video url')
|
||||||
|
|
||||||
|
@ -1,89 +1,21 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import itertools
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from .nexx import NexxIE
|
from .nexx import NexxIE
|
||||||
from ..compat import compat_str
|
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
int_or_none,
|
int_or_none,
|
||||||
try_get,
|
str_or_none,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class FunkBaseIE(InfoExtractor):
|
class FunkIE(InfoExtractor):
|
||||||
_HEADERS = {
|
_VALID_URL = r'https?://(?:www\.)?funk\.net/(?:channel|playlist)/[^/]+/(?P<display_id>[0-9a-z-]+)-(?P<id>\d+)'
|
||||||
'Accept': '*/*',
|
|
||||||
'Accept-Language': 'en-US,en;q=0.9,ru;q=0.8',
|
|
||||||
'authorization': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnROYW1lIjoid2ViYXBwLXYzMSIsInNjb3BlIjoic3RhdGljLWNvbnRlbnQtYXBpLGN1cmF0aW9uLWFwaSxuZXh4LWNvbnRlbnQtYXBpLXYzMSx3ZWJhcHAtYXBpIn0.mbuG9wS9Yf5q6PqgR4fiaRFIagiHk9JhwoKES7ksVX4',
|
|
||||||
}
|
|
||||||
_AUTH = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjbGllbnROYW1lIjoid2ViYXBwLXYzMSIsInNjb3BlIjoic3RhdGljLWNvbnRlbnQtYXBpLGN1cmF0aW9uLWFwaSxuZXh4LWNvbnRlbnQtYXBpLXYzMSx3ZWJhcHAtYXBpIn0.mbuG9wS9Yf5q6PqgR4fiaRFIagiHk9JhwoKES7ksVX4'
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _make_headers(referer):
|
|
||||||
headers = FunkBaseIE._HEADERS.copy()
|
|
||||||
headers['Referer'] = referer
|
|
||||||
return headers
|
|
||||||
|
|
||||||
def _make_url_result(self, video):
|
|
||||||
return {
|
|
||||||
'_type': 'url_transparent',
|
|
||||||
'url': 'nexx:741:%s' % video['sourceId'],
|
|
||||||
'ie_key': NexxIE.ie_key(),
|
|
||||||
'id': video['sourceId'],
|
|
||||||
'title': video.get('title'),
|
|
||||||
'description': video.get('description'),
|
|
||||||
'duration': int_or_none(video.get('duration')),
|
|
||||||
'season_number': int_or_none(video.get('seasonNr')),
|
|
||||||
'episode_number': int_or_none(video.get('episodeNr')),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class FunkMixIE(FunkBaseIE):
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?funk\.net/mix/(?P<id>[^/]+)/(?P<alias>[^/?#&]+)'
|
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.funk.net/mix/59d65d935f8b160001828b5b/die-realste-kifferdoku-aller-zeiten',
|
'url': 'https://www.funk.net/channel/ba-793/die-lustigsten-instrumente-aus-dem-internet-teil-2-1155821',
|
||||||
'md5': '8edf617c2f2b7c9847dfda313f199009',
|
'md5': '8dd9d9ab59b4aa4173b3197f2ea48e81',
|
||||||
'info_dict': {
|
|
||||||
'id': '123748',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': '"Die realste Kifferdoku aller Zeiten"',
|
|
||||||
'description': 'md5:c97160f5bafa8d47ec8e2e461012aa9d',
|
|
||||||
'timestamp': 1490274721,
|
|
||||||
'upload_date': '20170323',
|
|
||||||
},
|
|
||||||
}]
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
mobj = re.match(self._VALID_URL, url)
|
|
||||||
mix_id = mobj.group('id')
|
|
||||||
alias = mobj.group('alias')
|
|
||||||
|
|
||||||
lists = self._download_json(
|
|
||||||
'https://www.funk.net/api/v3.1/curation/curatedLists/',
|
|
||||||
mix_id, headers=self._make_headers(url), query={
|
|
||||||
'size': 100,
|
|
||||||
})['_embedded']['curatedListList']
|
|
||||||
|
|
||||||
metas = next(
|
|
||||||
l for l in lists
|
|
||||||
if mix_id in (l.get('entityId'), l.get('alias')))['videoMetas']
|
|
||||||
video = next(
|
|
||||||
meta['videoDataDelegate']
|
|
||||||
for meta in metas
|
|
||||||
if try_get(
|
|
||||||
meta, lambda x: x['videoDataDelegate']['alias'],
|
|
||||||
compat_str) == alias)
|
|
||||||
|
|
||||||
return self._make_url_result(video)
|
|
||||||
|
|
||||||
|
|
||||||
class FunkChannelIE(FunkBaseIE):
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?funk\.net/channel/(?P<id>[^/]+)/(?P<alias>[^/?#&]+)'
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'https://www.funk.net/channel/ba/die-lustigsten-instrumente-aus-dem-internet-teil-2',
|
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '1155821',
|
'id': '1155821',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
@ -92,83 +24,26 @@ class FunkChannelIE(FunkBaseIE):
|
|||||||
'timestamp': 1514507395,
|
'timestamp': 1514507395,
|
||||||
'upload_date': '20171229',
|
'upload_date': '20171229',
|
||||||
},
|
},
|
||||||
'params': {
|
|
||||||
'skip_download': True,
|
|
||||||
},
|
|
||||||
}, {
|
}, {
|
||||||
# only available via byIdList API
|
'url': 'https://www.funk.net/playlist/neuesteVideos/kameras-auf-dem-fusion-festival-1618699',
|
||||||
'url': 'https://www.funk.net/channel/informr/martin-sonneborn-erklaert-die-eu',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '205067',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': 'Martin Sonneborn erklärt die EU',
|
|
||||||
'description': 'md5:050f74626e4ed87edf4626d2024210c0',
|
|
||||||
'timestamp': 1494424042,
|
|
||||||
'upload_date': '20170510',
|
|
||||||
},
|
|
||||||
'params': {
|
|
||||||
'skip_download': True,
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
'url': 'https://www.funk.net/channel/59d5149841dca100012511e3/mein-erster-job-lovemilla-folge-1/lovemilla/',
|
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
mobj = re.match(self._VALID_URL, url)
|
display_id, nexx_id = re.match(self._VALID_URL, url).groups()
|
||||||
channel_id = mobj.group('id')
|
video = self._download_json(
|
||||||
alias = mobj.group('alias')
|
'https://www.funk.net/api/v4.0/videos/' + nexx_id, nexx_id)
|
||||||
|
return {
|
||||||
headers = self._make_headers(url)
|
'_type': 'url_transparent',
|
||||||
|
'url': 'nexx:741:' + nexx_id,
|
||||||
video = None
|
'ie_key': NexxIE.ie_key(),
|
||||||
|
'id': nexx_id,
|
||||||
# Id-based channels are currently broken on their side: webplayer
|
'title': video.get('title'),
|
||||||
# tries to process them via byChannelAlias endpoint and fails
|
'description': video.get('description'),
|
||||||
# predictably.
|
'duration': int_or_none(video.get('duration')),
|
||||||
for page_num in itertools.count():
|
'channel_id': str_or_none(video.get('channelId')),
|
||||||
by_channel_alias = self._download_json(
|
'display_id': display_id,
|
||||||
'https://www.funk.net/api/v3.1/webapp/videos/byChannelAlias/%s'
|
'tags': video.get('tags'),
|
||||||
% channel_id,
|
'thumbnail': video.get('imageUrlLandscape'),
|
||||||
'Downloading byChannelAlias JSON page %d' % (page_num + 1),
|
}
|
||||||
headers=headers, query={
|
|
||||||
'filterFsk': 'false',
|
|
||||||
'sort': 'creationDate,desc',
|
|
||||||
'size': 100,
|
|
||||||
'page': page_num,
|
|
||||||
}, fatal=False)
|
|
||||||
if not by_channel_alias:
|
|
||||||
break
|
|
||||||
video_list = try_get(
|
|
||||||
by_channel_alias, lambda x: x['_embedded']['videoList'], list)
|
|
||||||
if not video_list:
|
|
||||||
break
|
|
||||||
try:
|
|
||||||
video = next(r for r in video_list if r.get('alias') == alias)
|
|
||||||
break
|
|
||||||
except StopIteration:
|
|
||||||
pass
|
|
||||||
if not try_get(
|
|
||||||
by_channel_alias, lambda x: x['_links']['next']):
|
|
||||||
break
|
|
||||||
|
|
||||||
if not video:
|
|
||||||
by_id_list = self._download_json(
|
|
||||||
'https://www.funk.net/api/v3.0/content/videos/byIdList',
|
|
||||||
channel_id, 'Downloading byIdList JSON', headers=headers,
|
|
||||||
query={
|
|
||||||
'ids': alias,
|
|
||||||
}, fatal=False)
|
|
||||||
if by_id_list:
|
|
||||||
video = try_get(by_id_list, lambda x: x['result'][0], dict)
|
|
||||||
|
|
||||||
if not video:
|
|
||||||
results = self._download_json(
|
|
||||||
'https://www.funk.net/api/v3.0/content/videos/filter',
|
|
||||||
channel_id, 'Downloading filter JSON', headers=headers, query={
|
|
||||||
'channelId': channel_id,
|
|
||||||
'size': 100,
|
|
||||||
})['result']
|
|
||||||
video = next(r for r in results if r.get('alias') == alias)
|
|
||||||
|
|
||||||
return self._make_url_result(video)
|
|
||||||
|
@ -1,162 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from .common import InfoExtractor
|
|
||||||
from ..utils import (
|
|
||||||
ExtractorError,
|
|
||||||
float_or_none,
|
|
||||||
int_or_none,
|
|
||||||
unified_timestamp,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class FunnyOrDieIE(InfoExtractor):
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?funnyordie\.com/(?P<type>embed|articles|videos)/(?P<id>[0-9a-f]+)(?:$|[?#/])'
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'http://www.funnyordie.com/videos/0732f586d7/heart-shaped-box-literal-video-version',
|
|
||||||
'md5': 'bcd81e0c4f26189ee09be362ad6e6ba9',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '0732f586d7',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': 'Heart-Shaped Box: Literal Video Version',
|
|
||||||
'description': 'md5:ea09a01bc9a1c46d9ab696c01747c338',
|
|
||||||
'thumbnail': r're:^http:.*\.jpg$',
|
|
||||||
'uploader': 'DASjr',
|
|
||||||
'timestamp': 1317904928,
|
|
||||||
'upload_date': '20111006',
|
|
||||||
'duration': 318.3,
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
'url': 'http://www.funnyordie.com/embed/e402820827',
|
|
||||||
'info_dict': {
|
|
||||||
'id': 'e402820827',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': 'Please Use This Song (Jon Lajoie)',
|
|
||||||
'description': 'Please use this to sell something. www.jonlajoie.com',
|
|
||||||
'thumbnail': r're:^http:.*\.jpg$',
|
|
||||||
'timestamp': 1398988800,
|
|
||||||
'upload_date': '20140502',
|
|
||||||
},
|
|
||||||
'params': {
|
|
||||||
'skip_download': True,
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
'url': 'http://www.funnyordie.com/articles/ebf5e34fc8/10-hours-of-walking-in-nyc-as-a-man',
|
|
||||||
'only_matching': True,
|
|
||||||
}]
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
mobj = re.match(self._VALID_URL, url)
|
|
||||||
|
|
||||||
video_id = mobj.group('id')
|
|
||||||
webpage = self._download_webpage(url, video_id)
|
|
||||||
|
|
||||||
links = re.findall(r'<source src="([^"]+/v)[^"]+\.([^"]+)" type=\'video', webpage)
|
|
||||||
if not links:
|
|
||||||
raise ExtractorError('No media links available for %s' % video_id)
|
|
||||||
|
|
||||||
links.sort(key=lambda link: 1 if link[1] == 'mp4' else 0)
|
|
||||||
|
|
||||||
m3u8_url = self._search_regex(
|
|
||||||
r'<source[^>]+src=(["\'])(?P<url>.+?/master\.m3u8[^"\']*)\1',
|
|
||||||
webpage, 'm3u8 url', group='url')
|
|
||||||
|
|
||||||
formats = []
|
|
||||||
|
|
||||||
m3u8_formats = self._extract_m3u8_formats(
|
|
||||||
m3u8_url, video_id, 'mp4', 'm3u8_native',
|
|
||||||
m3u8_id='hls', fatal=False)
|
|
||||||
source_formats = list(filter(
|
|
||||||
lambda f: f.get('vcodec') != 'none', m3u8_formats))
|
|
||||||
|
|
||||||
bitrates = [int(bitrate) for bitrate in re.findall(r'[,/]v(\d+)(?=[,/])', m3u8_url)]
|
|
||||||
bitrates.sort()
|
|
||||||
|
|
||||||
if source_formats:
|
|
||||||
self._sort_formats(source_formats)
|
|
||||||
|
|
||||||
for bitrate, f in zip(bitrates, source_formats or [{}] * len(bitrates)):
|
|
||||||
for path, ext in links:
|
|
||||||
ff = f.copy()
|
|
||||||
if ff:
|
|
||||||
if ext != 'mp4':
|
|
||||||
ff = dict(
|
|
||||||
[(k, v) for k, v in ff.items()
|
|
||||||
if k in ('height', 'width', 'format_id')])
|
|
||||||
ff.update({
|
|
||||||
'format_id': ff['format_id'].replace('hls', ext),
|
|
||||||
'ext': ext,
|
|
||||||
'protocol': 'http',
|
|
||||||
})
|
|
||||||
else:
|
|
||||||
ff.update({
|
|
||||||
'format_id': '%s-%d' % (ext, bitrate),
|
|
||||||
'vbr': bitrate,
|
|
||||||
})
|
|
||||||
ff['url'] = self._proto_relative_url(
|
|
||||||
'%s%d.%s' % (path, bitrate, ext))
|
|
||||||
formats.append(ff)
|
|
||||||
self._check_formats(formats, video_id)
|
|
||||||
|
|
||||||
formats.extend(m3u8_formats)
|
|
||||||
self._sort_formats(
|
|
||||||
formats, field_preference=('height', 'width', 'tbr', 'format_id'))
|
|
||||||
|
|
||||||
subtitles = {}
|
|
||||||
for src, src_lang in re.findall(r'<track kind="captions" src="([^"]+)" srclang="([^"]+)"', webpage):
|
|
||||||
subtitles[src_lang] = [{
|
|
||||||
'ext': src.split('/')[-1],
|
|
||||||
'url': 'http://www.funnyordie.com%s' % src,
|
|
||||||
}]
|
|
||||||
|
|
||||||
timestamp = unified_timestamp(self._html_search_meta(
|
|
||||||
'uploadDate', webpage, 'timestamp', default=None))
|
|
||||||
|
|
||||||
uploader = self._html_search_regex(
|
|
||||||
r'<h\d[^>]+\bclass=["\']channel-preview-name[^>]+>(.+?)</h',
|
|
||||||
webpage, 'uploader', default=None)
|
|
||||||
|
|
||||||
title, description, thumbnail, duration = [None] * 4
|
|
||||||
|
|
||||||
medium = self._parse_json(
|
|
||||||
self._search_regex(
|
|
||||||
r'jsonMedium\s*=\s*({.+?});', webpage, 'JSON medium',
|
|
||||||
default='{}'),
|
|
||||||
video_id, fatal=False)
|
|
||||||
if medium:
|
|
||||||
title = medium.get('title')
|
|
||||||
duration = float_or_none(medium.get('duration'))
|
|
||||||
if not timestamp:
|
|
||||||
timestamp = unified_timestamp(medium.get('publishDate'))
|
|
||||||
|
|
||||||
post = self._parse_json(
|
|
||||||
self._search_regex(
|
|
||||||
r'fb_post\s*=\s*(\{.*?\});', webpage, 'post details',
|
|
||||||
default='{}'),
|
|
||||||
video_id, fatal=False)
|
|
||||||
if post:
|
|
||||||
if not title:
|
|
||||||
title = post.get('name')
|
|
||||||
description = post.get('description')
|
|
||||||
thumbnail = post.get('picture')
|
|
||||||
|
|
||||||
if not title:
|
|
||||||
title = self._og_search_title(webpage)
|
|
||||||
if not description:
|
|
||||||
description = self._og_search_description(webpage)
|
|
||||||
if not duration:
|
|
||||||
duration = int_or_none(self._html_search_meta(
|
|
||||||
('video:duration', 'duration'), webpage, 'duration', default=False))
|
|
||||||
|
|
||||||
return {
|
|
||||||
'id': video_id,
|
|
||||||
'title': title,
|
|
||||||
'description': description,
|
|
||||||
'thumbnail': thumbnail,
|
|
||||||
'uploader': uploader,
|
|
||||||
'timestamp': timestamp,
|
|
||||||
'duration': duration,
|
|
||||||
'formats': formats,
|
|
||||||
'subtitles': subtitles,
|
|
||||||
}
|
|
@ -1,12 +1,19 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from .brightcove import BrightcoveNewIE
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
|
from ..utils import (
|
||||||
|
clean_html,
|
||||||
|
get_element_by_class,
|
||||||
|
get_element_by_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class GameInformerIE(InfoExtractor):
|
class GameInformerIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.)?gameinformer\.com/(?:[^/]+/)*(?P<id>.+)\.aspx'
|
_VALID_URL = r'https?://(?:www\.)?gameinformer\.com/(?:[^/]+/)*(?P<id>[^.?&#]+)'
|
||||||
_TEST = {
|
_TESTS = [{
|
||||||
|
# normal Brightcove embed code extracted with BrightcoveNewIE._extract_url
|
||||||
'url': 'http://www.gameinformer.com/b/features/archive/2015/09/26/replay-animal-crossing.aspx',
|
'url': 'http://www.gameinformer.com/b/features/archive/2015/09/26/replay-animal-crossing.aspx',
|
||||||
'md5': '292f26da1ab4beb4c9099f1304d2b071',
|
'md5': '292f26da1ab4beb4c9099f1304d2b071',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
@ -18,16 +25,25 @@ class GameInformerIE(InfoExtractor):
|
|||||||
'upload_date': '20150928',
|
'upload_date': '20150928',
|
||||||
'uploader_id': '694940074001',
|
'uploader_id': '694940074001',
|
||||||
},
|
},
|
||||||
}
|
}, {
|
||||||
|
# Brightcove id inside unique element with field--name-field-brightcove-video-id class
|
||||||
|
'url': 'https://www.gameinformer.com/video-feature/new-gameplay-today/2019/07/09/new-gameplay-today-streets-of-rogue',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '6057111913001',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'New Gameplay Today – Streets Of Rogue',
|
||||||
|
'timestamp': 1562699001,
|
||||||
|
'upload_date': '20190709',
|
||||||
|
'uploader_id': '694940074001',
|
||||||
|
|
||||||
|
},
|
||||||
|
}]
|
||||||
BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/694940074001/default_default/index.html?videoId=%s'
|
BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/694940074001/default_default/index.html?videoId=%s'
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
display_id = self._match_id(url)
|
display_id = self._match_id(url)
|
||||||
webpage = self._download_webpage(
|
webpage = self._download_webpage(
|
||||||
url, display_id, headers=self.geo_verification_headers())
|
url, display_id, headers=self.geo_verification_headers())
|
||||||
brightcove_id = self._search_regex(
|
brightcove_id = clean_html(get_element_by_class('field--name-field-brightcove-video-id', webpage) or get_element_by_id('video-source-content', webpage))
|
||||||
[r'<[^>]+\bid=["\']bc_(\d+)', r"getVideo\('[^']+video_id=(\d+)"],
|
brightcove_url = self.BRIGHTCOVE_URL_TEMPLATE % brightcove_id if brightcove_id else BrightcoveNewIE._extract_url(self, webpage)
|
||||||
webpage, 'brightcove id')
|
return self.url_result(brightcove_url, 'BrightcoveNew', brightcove_id)
|
||||||
return self.url_result(
|
|
||||||
self.BRIGHTCOVE_URL_TEMPLATE % brightcove_id, 'BrightcoveNew',
|
|
||||||
brightcove_id)
|
|
||||||
|
@ -79,6 +79,9 @@ class MGTVIE(InfoExtractor):
|
|||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'tbr': tbr,
|
'tbr': tbr,
|
||||||
'protocol': 'm3u8_native',
|
'protocol': 'm3u8_native',
|
||||||
|
'http_headers': {
|
||||||
|
'Referer': url,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
self._sort_formats(formats)
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
@ -5,26 +5,27 @@ import re
|
|||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..compat import (
|
from ..compat import (
|
||||||
compat_str,
|
# compat_str,
|
||||||
compat_HTTPError,
|
compat_HTTPError,
|
||||||
)
|
)
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
clean_html,
|
clean_html,
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
remove_end,
|
# remove_end,
|
||||||
|
str_or_none,
|
||||||
strip_or_none,
|
strip_or_none,
|
||||||
unified_timestamp,
|
unified_timestamp,
|
||||||
urljoin,
|
# urljoin,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class PacktPubBaseIE(InfoExtractor):
|
class PacktPubBaseIE(InfoExtractor):
|
||||||
_PACKT_BASE = 'https://www.packtpub.com'
|
# _PACKT_BASE = 'https://www.packtpub.com'
|
||||||
_MAPT_REST = '%s/mapt-rest' % _PACKT_BASE
|
_STATIC_PRODUCTS_BASE = 'https://static.packt-cdn.com/products/'
|
||||||
|
|
||||||
|
|
||||||
class PacktPubIE(PacktPubBaseIE):
|
class PacktPubIE(PacktPubBaseIE):
|
||||||
_VALID_URL = r'https?://(?:(?:www\.)?packtpub\.com/mapt|subscription\.packtpub\.com)/video/[^/]+/(?P<course_id>\d+)/(?P<chapter_id>\d+)/(?P<id>\d+)'
|
_VALID_URL = r'https?://(?:(?:www\.)?packtpub\.com/mapt|subscription\.packtpub\.com)/video/[^/]+/(?P<course_id>\d+)/(?P<chapter_id>[^/]+)/(?P<id>[^/]+)(?:/(?P<display_id>[^/?&#]+))?'
|
||||||
|
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.packtpub.com/mapt/video/web-development/9781787122215/20528/20530/Project+Intro',
|
'url': 'https://www.packtpub.com/mapt/video/web-development/9781787122215/20528/20530/Project+Intro',
|
||||||
@ -40,6 +41,9 @@ class PacktPubIE(PacktPubBaseIE):
|
|||||||
}, {
|
}, {
|
||||||
'url': 'https://subscription.packtpub.com/video/web_development/9781787122215/20528/20530/project-intro',
|
'url': 'https://subscription.packtpub.com/video/web_development/9781787122215/20528/20530/project-intro',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
'url': 'https://subscription.packtpub.com/video/programming/9781838988906/p1/video1_1/business-card-project',
|
||||||
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
_NETRC_MACHINE = 'packtpub'
|
_NETRC_MACHINE = 'packtpub'
|
||||||
_TOKEN = None
|
_TOKEN = None
|
||||||
@ -50,9 +54,9 @@ class PacktPubIE(PacktPubBaseIE):
|
|||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self._TOKEN = self._download_json(
|
self._TOKEN = self._download_json(
|
||||||
self._MAPT_REST + '/users/tokens', None,
|
'https://services.packtpub.com/auth-v1/users/tokens', None,
|
||||||
'Downloading Authorization Token', data=json.dumps({
|
'Downloading Authorization Token', data=json.dumps({
|
||||||
'email': username,
|
'username': username,
|
||||||
'password': password,
|
'password': password,
|
||||||
}).encode())['data']['access']
|
}).encode())['data']['access']
|
||||||
except ExtractorError as e:
|
except ExtractorError as e:
|
||||||
@ -61,54 +65,40 @@ class PacktPubIE(PacktPubBaseIE):
|
|||||||
raise ExtractorError(message, expected=True)
|
raise ExtractorError(message, expected=True)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def _handle_error(self, response):
|
|
||||||
if response.get('status') != 'success':
|
|
||||||
raise ExtractorError(
|
|
||||||
'% said: %s' % (self.IE_NAME, response['message']),
|
|
||||||
expected=True)
|
|
||||||
|
|
||||||
def _download_json(self, *args, **kwargs):
|
|
||||||
response = super(PacktPubIE, self)._download_json(*args, **kwargs)
|
|
||||||
self._handle_error(response)
|
|
||||||
return response
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
mobj = re.match(self._VALID_URL, url)
|
course_id, chapter_id, video_id, display_id = re.match(self._VALID_URL, url).groups()
|
||||||
course_id, chapter_id, video_id = mobj.group(
|
|
||||||
'course_id', 'chapter_id', 'id')
|
|
||||||
|
|
||||||
headers = {}
|
headers = {}
|
||||||
if self._TOKEN:
|
if self._TOKEN:
|
||||||
headers['Authorization'] = 'Bearer ' + self._TOKEN
|
headers['Authorization'] = 'Bearer ' + self._TOKEN
|
||||||
video = self._download_json(
|
try:
|
||||||
'%s/users/me/products/%s/chapters/%s/sections/%s'
|
video_url = self._download_json(
|
||||||
% (self._MAPT_REST, course_id, chapter_id, video_id), video_id,
|
'https://services.packtpub.com/products-v1/products/%s/%s/%s' % (course_id, chapter_id, video_id), video_id,
|
||||||
'Downloading JSON video', headers=headers)['data']
|
'Downloading JSON video', headers=headers)['data']
|
||||||
|
except ExtractorError as e:
|
||||||
content = video.get('content')
|
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 400:
|
||||||
if not content:
|
|
||||||
self.raise_login_required('This video is locked')
|
self.raise_login_required('This video is locked')
|
||||||
|
raise
|
||||||
|
|
||||||
video_url = content['file']
|
# TODO: find a better way to avoid duplicating course requests
|
||||||
|
# metadata = self._download_json(
|
||||||
|
# '%s/products/%s/chapters/%s/sections/%s/metadata'
|
||||||
|
# % (self._MAPT_REST, course_id, chapter_id, video_id),
|
||||||
|
# video_id)['data']
|
||||||
|
|
||||||
metadata = self._download_json(
|
# title = metadata['pageTitle']
|
||||||
'%s/products/%s/chapters/%s/sections/%s/metadata'
|
# course_title = metadata.get('title')
|
||||||
% (self._MAPT_REST, course_id, chapter_id, video_id),
|
# if course_title:
|
||||||
video_id)['data']
|
# title = remove_end(title, ' - %s' % course_title)
|
||||||
|
# timestamp = unified_timestamp(metadata.get('publicationDate'))
|
||||||
title = metadata['pageTitle']
|
# thumbnail = urljoin(self._PACKT_BASE, metadata.get('filepath'))
|
||||||
course_title = metadata.get('title')
|
|
||||||
if course_title:
|
|
||||||
title = remove_end(title, ' - %s' % course_title)
|
|
||||||
timestamp = unified_timestamp(metadata.get('publicationDate'))
|
|
||||||
thumbnail = urljoin(self._PACKT_BASE, metadata.get('filepath'))
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'id': video_id,
|
'id': video_id,
|
||||||
'url': video_url,
|
'url': video_url,
|
||||||
'title': title,
|
'title': display_id or video_id, # title,
|
||||||
'thumbnail': thumbnail,
|
# 'thumbnail': thumbnail,
|
||||||
'timestamp': timestamp,
|
# 'timestamp': timestamp,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -119,6 +109,7 @@ class PacktPubCourseIE(PacktPubBaseIE):
|
|||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '9781787122215',
|
'id': '9781787122215',
|
||||||
'title': 'Learn Nodejs by building 12 projects [Video]',
|
'title': 'Learn Nodejs by building 12 projects [Video]',
|
||||||
|
'description': 'md5:489da8d953f416e51927b60a1c7db0aa',
|
||||||
},
|
},
|
||||||
'playlist_count': 90,
|
'playlist_count': 90,
|
||||||
}, {
|
}, {
|
||||||
@ -136,35 +127,38 @@ class PacktPubCourseIE(PacktPubBaseIE):
|
|||||||
url, course_id = mobj.group('url', 'id')
|
url, course_id = mobj.group('url', 'id')
|
||||||
|
|
||||||
course = self._download_json(
|
course = self._download_json(
|
||||||
'%s/products/%s/metadata' % (self._MAPT_REST, course_id),
|
self._STATIC_PRODUCTS_BASE + '%s/toc' % course_id, course_id)
|
||||||
course_id)['data']
|
metadata = self._download_json(
|
||||||
|
self._STATIC_PRODUCTS_BASE + '%s/summary' % course_id,
|
||||||
|
course_id, fatal=False) or {}
|
||||||
|
|
||||||
entries = []
|
entries = []
|
||||||
for chapter_num, chapter in enumerate(course['tableOfContents'], 1):
|
for chapter_num, chapter in enumerate(course['chapters'], 1):
|
||||||
if chapter.get('type') != 'chapter':
|
chapter_id = str_or_none(chapter.get('id'))
|
||||||
continue
|
sections = chapter.get('sections')
|
||||||
children = chapter.get('children')
|
if not chapter_id or not isinstance(sections, list):
|
||||||
if not isinstance(children, list):
|
|
||||||
continue
|
continue
|
||||||
chapter_info = {
|
chapter_info = {
|
||||||
'chapter': chapter.get('title'),
|
'chapter': chapter.get('title'),
|
||||||
'chapter_number': chapter_num,
|
'chapter_number': chapter_num,
|
||||||
'chapter_id': chapter.get('id'),
|
'chapter_id': chapter_id,
|
||||||
}
|
}
|
||||||
for section in children:
|
for section in sections:
|
||||||
if section.get('type') != 'section':
|
section_id = str_or_none(section.get('id'))
|
||||||
continue
|
if not section_id or section.get('contentType') != 'video':
|
||||||
section_url = section.get('seoUrl')
|
|
||||||
if not isinstance(section_url, compat_str):
|
|
||||||
continue
|
continue
|
||||||
entry = {
|
entry = {
|
||||||
'_type': 'url_transparent',
|
'_type': 'url_transparent',
|
||||||
'url': urljoin(url + '/', section_url),
|
'url': '/'.join([url, chapter_id, section_id]),
|
||||||
'title': strip_or_none(section.get('title')),
|
'title': strip_or_none(section.get('title')),
|
||||||
'description': clean_html(section.get('summary')),
|
'description': clean_html(section.get('summary')),
|
||||||
|
'thumbnail': metadata.get('coverImage'),
|
||||||
|
'timestamp': unified_timestamp(metadata.get('publicationDate')),
|
||||||
'ie_key': PacktPubIE.ie_key(),
|
'ie_key': PacktPubIE.ie_key(),
|
||||||
}
|
}
|
||||||
entry.update(chapter_info)
|
entry.update(chapter_info)
|
||||||
entries.append(entry)
|
entries.append(entry)
|
||||||
|
|
||||||
return self.playlist_result(entries, course_id, course.get('title'))
|
return self.playlist_result(
|
||||||
|
entries, course_id, metadata.get('title'),
|
||||||
|
clean_html(metadata.get('about')))
|
||||||
|
@ -4,7 +4,10 @@ from __future__ import unicode_literals
|
|||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from .once import OnceIE
|
from .once import OnceIE
|
||||||
from ..compat import compat_urllib_parse_unquote
|
from ..compat import compat_urllib_parse_unquote
|
||||||
from ..utils import ExtractorError
|
from ..utils import (
|
||||||
|
ExtractorError,
|
||||||
|
int_or_none,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class VoxMediaVolumeIE(OnceIE):
|
class VoxMediaVolumeIE(OnceIE):
|
||||||
@ -13,18 +16,43 @@ class VoxMediaVolumeIE(OnceIE):
|
|||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
video_id = self._match_id(url)
|
video_id = self._match_id(url)
|
||||||
webpage = self._download_webpage(url, video_id)
|
webpage = self._download_webpage(url, video_id)
|
||||||
video_data = self._parse_json(self._search_regex(
|
|
||||||
r'Volume\.createVideo\(({.+})\s*,\s*{.*}\s*,\s*\[.*\]\s*,\s*{.*}\);', webpage, 'video data'), video_id)
|
setup = self._parse_json(self._search_regex(
|
||||||
for provider_video_type in ('ooyala', 'youtube', 'brightcove'):
|
r'setup\s*=\s*({.+});', webpage, 'setup'), video_id)
|
||||||
provider_video_id = video_data.get('%s_id' % provider_video_type)
|
video_data = setup.get('video') or {}
|
||||||
if not provider_video_id:
|
|
||||||
continue
|
|
||||||
info = {
|
info = {
|
||||||
'id': video_id,
|
'id': video_id,
|
||||||
'title': video_data.get('title_short'),
|
'title': video_data.get('title_short'),
|
||||||
'description': video_data.get('description_long') or video_data.get('description_short'),
|
'description': video_data.get('description_long') or video_data.get('description_short'),
|
||||||
'thumbnail': video_data.get('brightcove_thumbnail')
|
'thumbnail': video_data.get('brightcove_thumbnail')
|
||||||
}
|
}
|
||||||
|
asset = setup.get('asset') or setup.get('params') or {}
|
||||||
|
|
||||||
|
formats = []
|
||||||
|
hls_url = asset.get('hls_url')
|
||||||
|
if hls_url:
|
||||||
|
formats.extend(self._extract_m3u8_formats(
|
||||||
|
hls_url, video_id, 'mp4', 'm3u8_native', m3u8_id='hls', fatal=False))
|
||||||
|
mp4_url = asset.get('mp4_url')
|
||||||
|
if mp4_url:
|
||||||
|
tbr = self._search_regex(r'-(\d+)k\.', mp4_url, 'bitrate', default=None)
|
||||||
|
format_id = 'http'
|
||||||
|
if tbr:
|
||||||
|
format_id += '-' + tbr
|
||||||
|
formats.append({
|
||||||
|
'format_id': format_id,
|
||||||
|
'url': mp4_url,
|
||||||
|
'tbr': int_or_none(tbr),
|
||||||
|
})
|
||||||
|
if formats:
|
||||||
|
self._sort_formats(formats)
|
||||||
|
info['formats'] = formats
|
||||||
|
return info
|
||||||
|
|
||||||
|
for provider_video_type in ('ooyala', 'youtube', 'brightcove'):
|
||||||
|
provider_video_id = video_data.get('%s_id' % provider_video_type)
|
||||||
|
if not provider_video_id:
|
||||||
|
continue
|
||||||
if provider_video_type == 'brightcove':
|
if provider_video_type == 'brightcove':
|
||||||
info['formats'] = self._extract_once_formats(provider_video_id)
|
info['formats'] = self._extract_once_formats(provider_video_id)
|
||||||
self._sort_formats(info['formats'])
|
self._sort_formats(info['formats'])
|
||||||
@ -39,46 +67,49 @@ class VoxMediaVolumeIE(OnceIE):
|
|||||||
|
|
||||||
|
|
||||||
class VoxMediaIE(InfoExtractor):
|
class VoxMediaIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.)?(?:(?:theverge|vox|sbnation|eater|polygon|curbed|racked)\.com|recode\.net)/(?:[^/]+/)*(?P<id>[^/?]+)'
|
_VALID_URL = r'https?://(?:www\.)?(?:(?:theverge|vox|sbnation|eater|polygon|curbed|racked|funnyordie)\.com|recode\.net)/(?:[^/]+/)*(?P<id>[^/?]+)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
|
# Volume embed, Youtube
|
||||||
'url': 'http://www.theverge.com/2014/6/27/5849272/material-world-how-google-discovered-what-software-is-made-of',
|
'url': 'http://www.theverge.com/2014/6/27/5849272/material-world-how-google-discovered-what-software-is-made-of',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '11eXZobjrG8DCSTgrNjVinU-YmmdYjhe',
|
'id': 'j4mLW6x17VM',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'title': 'Google\'s new material design direction',
|
'title': 'Material world: how Google discovered what software is made of',
|
||||||
'description': 'md5:2f44f74c4d14a1f800ea73e1c6832ad2',
|
'description': 'md5:dfc17e7715e3b542d66e33a109861382',
|
||||||
|
'upload_date': '20190710',
|
||||||
|
'uploader_id': 'TheVerge',
|
||||||
|
'uploader': 'The Verge',
|
||||||
},
|
},
|
||||||
'params': {
|
'add_ie': ['Youtube'],
|
||||||
# m3u8 download
|
|
||||||
'skip_download': True,
|
|
||||||
},
|
|
||||||
'add_ie': ['Ooyala'],
|
|
||||||
}, {
|
}, {
|
||||||
# data-ooyala-id
|
# Volume embed, Youtube
|
||||||
'url': 'http://www.theverge.com/2014/10/21/7025853/google-nexus-6-hands-on-photos-video-android-phablet',
|
'url': 'http://www.theverge.com/2014/10/21/7025853/google-nexus-6-hands-on-photos-video-android-phablet',
|
||||||
'md5': 'd744484ff127884cd2ba09e3fa604e4b',
|
'md5': '4c8f4a0937752b437c3ebc0ed24802b5',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': 'RkZXU4cTphOCPDMZg5oEounJyoFI0g-B',
|
'id': 'Gy8Md3Eky38',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'title': 'The Nexus 6: hands-on with Google\'s phablet',
|
'title': 'The Nexus 6: hands-on with Google\'s phablet',
|
||||||
'description': 'md5:87a51fe95ff8cea8b5bdb9ac7ae6a6af',
|
'description': 'md5:d9f0216e5fb932dd2033d6db37ac3f1d',
|
||||||
|
'uploader_id': 'TheVerge',
|
||||||
|
'upload_date': '20141021',
|
||||||
|
'uploader': 'The Verge',
|
||||||
},
|
},
|
||||||
'add_ie': ['Ooyala'],
|
'add_ie': ['Youtube'],
|
||||||
'skip': 'Video Not Found',
|
'skip': 'similar to the previous test',
|
||||||
}, {
|
}, {
|
||||||
# volume embed
|
# Volume embed, Youtube
|
||||||
'url': 'http://www.vox.com/2016/3/31/11336640/mississippi-lgbt-religious-freedom-bill',
|
'url': 'http://www.vox.com/2016/3/31/11336640/mississippi-lgbt-religious-freedom-bill',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': 'wydzk3dDpmRz7PQoXRsTIX6XTkPjYL0b',
|
'id': 'YCjDnX-Xzhg',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'title': 'The new frontier of LGBTQ civil rights, explained',
|
'title': "Mississippi's laws are so bad that its anti-LGBTQ law isn't needed to allow discrimination",
|
||||||
'description': 'md5:0dc58e94a465cbe91d02950f770eb93f',
|
'description': 'md5:fc1317922057de31cd74bce91eb1c66c',
|
||||||
|
'uploader_id': 'voxdotcom',
|
||||||
|
'upload_date': '20150915',
|
||||||
|
'uploader': 'Vox',
|
||||||
},
|
},
|
||||||
'params': {
|
'add_ie': ['Youtube'],
|
||||||
# m3u8 download
|
'skip': 'similar to the previous test',
|
||||||
'skip_download': True,
|
|
||||||
},
|
|
||||||
'add_ie': ['Ooyala'],
|
|
||||||
}, {
|
}, {
|
||||||
# youtube embed
|
# youtube embed
|
||||||
'url': 'http://www.vox.com/2016/3/24/11291692/robot-dance',
|
'url': 'http://www.vox.com/2016/3/24/11291692/robot-dance',
|
||||||
@ -93,6 +124,7 @@ class VoxMediaIE(InfoExtractor):
|
|||||||
'uploader': 'Vox',
|
'uploader': 'Vox',
|
||||||
},
|
},
|
||||||
'add_ie': ['Youtube'],
|
'add_ie': ['Youtube'],
|
||||||
|
'skip': 'Page no longer contain videos',
|
||||||
}, {
|
}, {
|
||||||
# SBN.VideoLinkset.entryGroup multiple ooyala embeds
|
# SBN.VideoLinkset.entryGroup multiple ooyala embeds
|
||||||
'url': 'http://www.sbnation.com/college-football-recruiting/2015/2/3/7970291/national-signing-day-rationalizations-itll-be-ok-itll-be-ok',
|
'url': 'http://www.sbnation.com/college-football-recruiting/2015/2/3/7970291/national-signing-day-rationalizations-itll-be-ok-itll-be-ok',
|
||||||
@ -118,10 +150,11 @@ class VoxMediaIE(InfoExtractor):
|
|||||||
'description': 'md5:e02d56b026d51aa32c010676765a690d',
|
'description': 'md5:e02d56b026d51aa32c010676765a690d',
|
||||||
},
|
},
|
||||||
}],
|
}],
|
||||||
|
'skip': 'Page no longer contain videos',
|
||||||
}, {
|
}, {
|
||||||
# volume embed, Brightcove Once
|
# volume embed, Brightcove Once
|
||||||
'url': 'https://www.recode.net/2014/6/17/11628066/post-post-pc-ceo-the-full-code-conference-video-of-microsofts-satya',
|
'url': 'https://www.recode.net/2014/6/17/11628066/post-post-pc-ceo-the-full-code-conference-video-of-microsofts-satya',
|
||||||
'md5': '01571a896281f77dc06e084138987ea2',
|
'md5': '2dbc77b8b0bff1894c2fce16eded637d',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '1231c973d',
|
'id': '1231c973d',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
|
@ -27,6 +27,7 @@ from ..compat import (
|
|||||||
compat_str,
|
compat_str,
|
||||||
)
|
)
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
|
bool_or_none,
|
||||||
clean_html,
|
clean_html,
|
||||||
dict_get,
|
dict_get,
|
||||||
error_to_compat_str,
|
error_to_compat_str,
|
||||||
@ -116,6 +117,8 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
|
|||||||
'f.req': json.dumps(f_req),
|
'f.req': json.dumps(f_req),
|
||||||
'flowName': 'GlifWebSignIn',
|
'flowName': 'GlifWebSignIn',
|
||||||
'flowEntry': 'ServiceLogin',
|
'flowEntry': 'ServiceLogin',
|
||||||
|
# TODO: reverse actual botguard identifier generation algo
|
||||||
|
'bgRequest': '["identifier",""]',
|
||||||
})
|
})
|
||||||
return self._download_json(
|
return self._download_json(
|
||||||
url, None, note=note, errnote=errnote,
|
url, None, note=note, errnote=errnote,
|
||||||
@ -1888,6 +1891,11 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
if view_count is None and video_details:
|
if view_count is None and video_details:
|
||||||
view_count = int_or_none(video_details.get('viewCount'))
|
view_count = int_or_none(video_details.get('viewCount'))
|
||||||
|
|
||||||
|
if is_live is None:
|
||||||
|
is_live = bool_or_none(dict_get(
|
||||||
|
video_details, ('isLive', 'isLiveContent'),
|
||||||
|
skip_false_values=False))
|
||||||
|
|
||||||
# Check for "rental" videos
|
# Check for "rental" videos
|
||||||
if 'ypc_video_rental_bar_text' in video_info and 'author' not in video_info:
|
if 'ypc_video_rental_bar_text' in video_info and 'author' not in video_info:
|
||||||
raise ExtractorError('"rental" videos not supported. See https://github.com/ytdl-org/youtube-dl/issues/359 for more information.', expected=True)
|
raise ExtractorError('"rental" videos not supported. See https://github.com/ytdl-org/youtube-dl/issues/359 for more information.', expected=True)
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
__version__ = '2019.07.02'
|
__version__ = '2019.07.12'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user