mirror of
https://codeberg.org/polarisfm/youtube-dl
synced 2024-11-24 01:14:32 +01:00
commit
80af001a69
61
.github/ISSUE_TEMPLATE.md
vendored
61
.github/ISSUE_TEMPLATE.md
vendored
@ -1,61 +0,0 @@
|
|||||||
## Please follow the guide below
|
|
||||||
|
|
||||||
- You will be asked some questions and requested to provide some information, please read them **carefully** and answer honestly
|
|
||||||
- Put an `x` into all the boxes [ ] relevant to your *issue* (like this: `[x]`)
|
|
||||||
- Use the *Preview* tab to see what your issue will actually look like
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2019.04.24*. If it's not, read [this FAQ entry](https://github.com/ytdl-org/youtube-dl/blob/master/README.md#how-do-i-update-youtube-dl) and update. Issues with outdated version will be rejected.
|
|
||||||
- [ ] I've **verified** and **I assure** that I'm running youtube-dl **2019.04.24**
|
|
||||||
|
|
||||||
### Before submitting an *issue* make sure you have:
|
|
||||||
- [ ] At least skimmed through the [README](https://github.com/ytdl-org/youtube-dl/blob/master/README.md), **most notably** the [FAQ](https://github.com/ytdl-org/youtube-dl#faq) and [BUGS](https://github.com/ytdl-org/youtube-dl#bugs) sections
|
|
||||||
- [ ] [Searched](https://github.com/ytdl-org/youtube-dl/search?type=Issues) the bugtracker for similar issues including closed ones
|
|
||||||
- [ ] Checked that provided video/audio/playlist URLs (if any) are alive and playable in a browser
|
|
||||||
|
|
||||||
### What is the purpose of your *issue*?
|
|
||||||
- [ ] Bug report (encountered problems with youtube-dl)
|
|
||||||
- [ ] Site support request (request for adding support for a new site)
|
|
||||||
- [ ] Feature request (request for a new functionality)
|
|
||||||
- [ ] Question
|
|
||||||
- [ ] Other
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### The following sections concretize particular purposed issues, you can erase any section (the contents between triple ---) not applicable to your *issue*
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### If the purpose of this *issue* is a *bug report*, *site support request* or you are not completely sure provide the full verbose output as follows:
|
|
||||||
|
|
||||||
Add the `-v` flag to **your command line** you run youtube-dl with (`youtube-dl -v <your command line>`), copy the **whole** output and insert it here. It should look similar to one below (replace it with **your** log inserted between triple ```):
|
|
||||||
|
|
||||||
```
|
|
||||||
[debug] System config: []
|
|
||||||
[debug] User config: []
|
|
||||||
[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] youtube-dl version 2019.04.24
|
|
||||||
[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] Proxy map: {}
|
|
||||||
...
|
|
||||||
<end of log>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### If the purpose of this *issue* is a *site support request* please provide all kinds of example URLs support for which should be included (replace following example URLs by **yours**):
|
|
||||||
- Single video: https://www.youtube.com/watch?v=BaW_jenozKc
|
|
||||||
- Single video: https://youtu.be/BaW_jenozKc
|
|
||||||
- Playlist: https://www.youtube.com/playlist?list=PL4lCao7KL_QFVb7Iudeipvc2BCavECqzc
|
|
||||||
|
|
||||||
Note that **youtube-dl does not support sites dedicated to [copyright infringement](https://github.com/ytdl-org/youtube-dl#can-you-add-support-for-this-anime-video-site-or-site-which-shows-current-movies-for-free)**. In order for site support request to be accepted all provided example URLs should not violate any copyrights.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Description of your *issue*, suggested solution and other information
|
|
||||||
|
|
||||||
Explanation of your *issue* in arbitrary form goes here. Please make sure the [description is worded well enough to be understood](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient). Provide as much context and examples as possible.
|
|
||||||
If work on your *issue* requires account credentials please provide them or explain how one can obtain them.
|
|
63
.github/ISSUE_TEMPLATE/1_broken_site.md
vendored
Normal file
63
.github/ISSUE_TEMPLATE/1_broken_site.md
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
name: Broken site support
|
||||||
|
about: Report broken or misfunctioning site
|
||||||
|
title: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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.04.30. 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 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.
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a broken site support
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **2019.04.30**
|
||||||
|
- [ ] 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 searched the bugtracker for similar issues including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Verbose log
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide the complete verbose output of youtube-dl that clearly demonstrates the problem.
|
||||||
|
Add the `-v` flag to your command line you run youtube-dl with (`youtube-dl -v <your command line>`), copy the WHOLE output and insert it below. It should look similar to this:
|
||||||
|
[debug] System config: []
|
||||||
|
[debug] User config: []
|
||||||
|
[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] youtube-dl version 2019.04.30
|
||||||
|
[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] Proxy map: {}
|
||||||
|
<more lines>
|
||||||
|
-->
|
||||||
|
|
||||||
|
```
|
||||||
|
PASTE VERBOSE LOG HERE
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide an explanation of your issue in an arbitrary form. Provide any additional information, suggested solution and as much context and examples as possible.
|
||||||
|
If work on your issue requires account credentials please provide them or explain how one can obtain them.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
54
.github/ISSUE_TEMPLATE/2_site_support_request.md
vendored
Normal file
54
.github/ISSUE_TEMPLATE/2_site_support_request.md
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
name: Site support request
|
||||||
|
about: Request support for a new site
|
||||||
|
title: ''
|
||||||
|
labels: 'site-support-request'
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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.04.30. 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 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.
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a new site support request
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **2019.04.30**
|
||||||
|
- [ ] 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 searched the bugtracker for similar site support requests including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Example URLs
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide all kinds of example URLs support for which should be included. Replace following example URLs by yours.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- Single video: https://www.youtube.com/watch?v=BaW_jenozKc
|
||||||
|
- Single video: https://youtu.be/BaW_jenozKc
|
||||||
|
- Playlist: https://www.youtube.com/playlist?list=PL4lCao7KL_QFVb7Iudeipvc2BCavECqzc
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide any additional information.
|
||||||
|
If work on your issue requires account credentials please provide them or explain how one can obtain them.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
37
.github/ISSUE_TEMPLATE/3_site_feature_request.md
vendored
Normal file
37
.github/ISSUE_TEMPLATE/3_site_feature_request.md
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: Site feature request
|
||||||
|
about: Request a new functionality for a site
|
||||||
|
title: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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.04.30. 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.
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a site feature request
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **2019.04.30**
|
||||||
|
- [ ] I've searched the bugtracker for similar site feature requests including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide an explanation of your site feature request in an arbitrary form. Please make sure the description is worded well enough to be understood, see https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient. Provide any additional information, suggested solution and as much context and examples as possible.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
65
.github/ISSUE_TEMPLATE/4_bug_report.md
vendored
Normal file
65
.github/ISSUE_TEMPLATE/4_bug_report.md
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Report a bug unrelated to any particular site or extractor
|
||||||
|
title: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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.04.30. 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 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.
|
||||||
|
- Read bugs section in FAQ: http://yt-dl.org/reporting
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a broken site support issue
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **2019.04.30**
|
||||||
|
- [ ] 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 searched the bugtracker for similar bug reports including closed ones
|
||||||
|
- [ ] I've read bugs section in FAQ
|
||||||
|
|
||||||
|
|
||||||
|
## Verbose log
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide the complete verbose output of youtube-dl that clearly demonstrates the problem.
|
||||||
|
Add the `-v` flag to your command line you run youtube-dl with (`youtube-dl -v <your command line>`), copy the WHOLE output and insert it below. It should look similar to this:
|
||||||
|
[debug] System config: []
|
||||||
|
[debug] User config: []
|
||||||
|
[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] youtube-dl version 2019.04.30
|
||||||
|
[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] Proxy map: {}
|
||||||
|
<more lines>
|
||||||
|
-->
|
||||||
|
|
||||||
|
```
|
||||||
|
PASTE VERBOSE LOG HERE
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide an explanation of your issue in an arbitrary form. Please make sure the description is worded well enough to be understood, see https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient. Provide any additional information, suggested solution and as much context and examples as possible.
|
||||||
|
If work on your issue requires account credentials please provide them or explain how one can obtain them.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
38
.github/ISSUE_TEMPLATE/5_feature_request.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/5_feature_request.md
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Request a new functionality unrelated to any particular site or extractor
|
||||||
|
title: ''
|
||||||
|
labels: 'request'
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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.04.30. 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.
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a feature request
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **2019.04.30**
|
||||||
|
- [ ] I've searched the bugtracker for similar feature requests including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide an explanation of your issue in an arbitrary form. Please make sure the description is worded well enough to be understood, see https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient. Provide any additional information, suggested solution and as much context and examples as possible.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
38
.github/ISSUE_TEMPLATE/6_question.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE/6_question.md
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Ask question
|
||||||
|
about: Ask youtube-dl related question
|
||||||
|
title: ''
|
||||||
|
labels: 'question'
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Carefully read and work through this check list in order to prevent the most common mistakes and misuse of youtube-dl:
|
||||||
|
- Look through the README (http://yt-dl.org/readme) and FAQ (http://yt-dl.org/faq) for similar questions
|
||||||
|
- Search the bugtracker for similar questions: http://yt-dl.org/search-issues
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm asking a question
|
||||||
|
- [ ] I've looked through the README and FAQ for similar questions
|
||||||
|
- [ ] I've searched the bugtracker for similar questions including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Question
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Ask your question in an arbitrary form. Please make sure it's worded well enough to be understood, see https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE QUESTION HERE
|
61
.github/ISSUE_TEMPLATE_tmpl.md
vendored
61
.github/ISSUE_TEMPLATE_tmpl.md
vendored
@ -1,61 +0,0 @@
|
|||||||
## Please follow the guide below
|
|
||||||
|
|
||||||
- You will be asked some questions and requested to provide some information, please read them **carefully** and answer honestly
|
|
||||||
- Put an `x` into all the boxes [ ] relevant to your *issue* (like this: `[x]`)
|
|
||||||
- Use the *Preview* tab to see what your issue will actually look like
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *%(version)s*. If it's not, read [this FAQ entry](https://github.com/ytdl-org/youtube-dl/blob/master/README.md#how-do-i-update-youtube-dl) and update. Issues with outdated version will be rejected.
|
|
||||||
- [ ] I've **verified** and **I assure** that I'm running youtube-dl **%(version)s**
|
|
||||||
|
|
||||||
### Before submitting an *issue* make sure you have:
|
|
||||||
- [ ] At least skimmed through the [README](https://github.com/ytdl-org/youtube-dl/blob/master/README.md), **most notably** the [FAQ](https://github.com/ytdl-org/youtube-dl#faq) and [BUGS](https://github.com/ytdl-org/youtube-dl#bugs) sections
|
|
||||||
- [ ] [Searched](https://github.com/ytdl-org/youtube-dl/search?type=Issues) the bugtracker for similar issues including closed ones
|
|
||||||
- [ ] Checked that provided video/audio/playlist URLs (if any) are alive and playable in a browser
|
|
||||||
|
|
||||||
### What is the purpose of your *issue*?
|
|
||||||
- [ ] Bug report (encountered problems with youtube-dl)
|
|
||||||
- [ ] Site support request (request for adding support for a new site)
|
|
||||||
- [ ] Feature request (request for a new functionality)
|
|
||||||
- [ ] Question
|
|
||||||
- [ ] Other
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### The following sections concretize particular purposed issues, you can erase any section (the contents between triple ---) not applicable to your *issue*
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### If the purpose of this *issue* is a *bug report*, *site support request* or you are not completely sure provide the full verbose output as follows:
|
|
||||||
|
|
||||||
Add the `-v` flag to **your command line** you run youtube-dl with (`youtube-dl -v <your command line>`), copy the **whole** output and insert it here. It should look similar to one below (replace it with **your** log inserted between triple ```):
|
|
||||||
|
|
||||||
```
|
|
||||||
[debug] System config: []
|
|
||||||
[debug] User config: []
|
|
||||||
[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] youtube-dl version %(version)s
|
|
||||||
[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] Proxy map: {}
|
|
||||||
...
|
|
||||||
<end of log>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### If the purpose of this *issue* is a *site support request* please provide all kinds of example URLs support for which should be included (replace following example URLs by **yours**):
|
|
||||||
- Single video: https://www.youtube.com/watch?v=BaW_jenozKc
|
|
||||||
- Single video: https://youtu.be/BaW_jenozKc
|
|
||||||
- Playlist: https://www.youtube.com/playlist?list=PL4lCao7KL_QFVb7Iudeipvc2BCavECqzc
|
|
||||||
|
|
||||||
Note that **youtube-dl does not support sites dedicated to [copyright infringement](https://github.com/ytdl-org/youtube-dl#can-you-add-support-for-this-anime-video-site-or-site-which-shows-current-movies-for-free)**. In order for site support request to be accepted all provided example URLs should not violate any copyrights.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Description of your *issue*, suggested solution and other information
|
|
||||||
|
|
||||||
Explanation of your *issue* in arbitrary form goes here. Please make sure the [description is worded well enough to be understood](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient). Provide as much context and examples as possible.
|
|
||||||
If work on your *issue* requires account credentials please provide them or explain how one can obtain them.
|
|
63
.github/ISSUE_TEMPLATE_tmpl/1_broken_site.md
vendored
Normal file
63
.github/ISSUE_TEMPLATE_tmpl/1_broken_site.md
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
name: Broken site support
|
||||||
|
about: Report broken or misfunctioning site
|
||||||
|
title: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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 %(version)s. 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 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.
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a broken site support
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **%(version)s**
|
||||||
|
- [ ] 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 searched the bugtracker for similar issues including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Verbose log
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide the complete verbose output of youtube-dl that clearly demonstrates the problem.
|
||||||
|
Add the `-v` flag to your command line you run youtube-dl with (`youtube-dl -v <your command line>`), copy the WHOLE output and insert it below. It should look similar to this:
|
||||||
|
[debug] System config: []
|
||||||
|
[debug] User config: []
|
||||||
|
[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] youtube-dl version %(version)s
|
||||||
|
[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] Proxy map: {}
|
||||||
|
<more lines>
|
||||||
|
-->
|
||||||
|
|
||||||
|
```
|
||||||
|
PASTE VERBOSE LOG HERE
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide an explanation of your issue in an arbitrary form. Provide any additional information, suggested solution and as much context and examples as possible.
|
||||||
|
If work on your issue requires account credentials please provide them or explain how one can obtain them.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
54
.github/ISSUE_TEMPLATE_tmpl/2_site_support_request.md
vendored
Normal file
54
.github/ISSUE_TEMPLATE_tmpl/2_site_support_request.md
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
name: Site support request
|
||||||
|
about: Request support for a new site
|
||||||
|
title: ''
|
||||||
|
labels: 'site-support-request'
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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 %(version)s. 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 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.
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a new site support request
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **%(version)s**
|
||||||
|
- [ ] 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 searched the bugtracker for similar site support requests including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Example URLs
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide all kinds of example URLs support for which should be included. Replace following example URLs by yours.
|
||||||
|
-->
|
||||||
|
|
||||||
|
- Single video: https://www.youtube.com/watch?v=BaW_jenozKc
|
||||||
|
- Single video: https://youtu.be/BaW_jenozKc
|
||||||
|
- Playlist: https://www.youtube.com/playlist?list=PL4lCao7KL_QFVb7Iudeipvc2BCavECqzc
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide any additional information.
|
||||||
|
If work on your issue requires account credentials please provide them or explain how one can obtain them.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
37
.github/ISSUE_TEMPLATE_tmpl/3_site_feature_request.md
vendored
Normal file
37
.github/ISSUE_TEMPLATE_tmpl/3_site_feature_request.md
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: Site feature request
|
||||||
|
about: Request a new functionality for a site
|
||||||
|
title: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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 %(version)s. 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.
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a site feature request
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **%(version)s**
|
||||||
|
- [ ] I've searched the bugtracker for similar site feature requests including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide an explanation of your site feature request in an arbitrary form. Please make sure the description is worded well enough to be understood, see https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient. Provide any additional information, suggested solution and as much context and examples as possible.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
65
.github/ISSUE_TEMPLATE_tmpl/4_bug_report.md
vendored
Normal file
65
.github/ISSUE_TEMPLATE_tmpl/4_bug_report.md
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Report a bug unrelated to any particular site or extractor
|
||||||
|
title: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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 %(version)s. 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 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.
|
||||||
|
- Read bugs section in FAQ: http://yt-dl.org/reporting
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a broken site support issue
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **%(version)s**
|
||||||
|
- [ ] 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 searched the bugtracker for similar bug reports including closed ones
|
||||||
|
- [ ] I've read bugs section in FAQ
|
||||||
|
|
||||||
|
|
||||||
|
## Verbose log
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide the complete verbose output of youtube-dl that clearly demonstrates the problem.
|
||||||
|
Add the `-v` flag to your command line you run youtube-dl with (`youtube-dl -v <your command line>`), copy the WHOLE output and insert it below. It should look similar to this:
|
||||||
|
[debug] System config: []
|
||||||
|
[debug] User config: []
|
||||||
|
[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] youtube-dl version %(version)s
|
||||||
|
[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] Proxy map: {}
|
||||||
|
<more lines>
|
||||||
|
-->
|
||||||
|
|
||||||
|
```
|
||||||
|
PASTE VERBOSE LOG HERE
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide an explanation of your issue in an arbitrary form. Please make sure the description is worded well enough to be understood, see https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient. Provide any additional information, suggested solution and as much context and examples as possible.
|
||||||
|
If work on your issue requires account credentials please provide them or explain how one can obtain them.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
38
.github/ISSUE_TEMPLATE_tmpl/5_feature_request.md
vendored
Normal file
38
.github/ISSUE_TEMPLATE_tmpl/5_feature_request.md
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Request a new functionality unrelated to any particular site or extractor
|
||||||
|
title: ''
|
||||||
|
labels: 'request'
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
WARNING!
|
||||||
|
IGNORING THE FOLLOWING TEMPLATE WILL RESULT IN ISSUE CLOSED AS INCOMPLETE
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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 %(version)s. 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.
|
||||||
|
- Finally, put x into all relevant boxes (like this [x])
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ ] I'm reporting a feature request
|
||||||
|
- [ ] I've verified that I'm running youtube-dl version **%(version)s**
|
||||||
|
- [ ] I've searched the bugtracker for similar feature requests including closed ones
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Provide an explanation of your issue in an arbitrary form. Please make sure the description is worded well enough to be understood, see https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient. Provide any additional information, suggested solution and as much context and examples as possible.
|
||||||
|
-->
|
||||||
|
|
||||||
|
WRITE DESCRIPTION HERE
|
21
ChangeLog
21
ChangeLog
@ -1,3 +1,24 @@
|
|||||||
|
version 2019.04.30
|
||||||
|
|
||||||
|
Extractors
|
||||||
|
* [openload] Use real Chrome versions (#20902)
|
||||||
|
- [youtube] Remove info el for get_video_info request
|
||||||
|
* [youtube] Improve extraction robustness
|
||||||
|
- [dramafever] Remove extractor (#20868)
|
||||||
|
* [adn] Fix subtitle extraction (#12724)
|
||||||
|
+ [ccc] Extract creator (#20355)
|
||||||
|
+ [ccc:playlist] Add support for media.ccc.de playlists (#14601, #20355)
|
||||||
|
+ [sverigesradio] Add support for sverigesradio.se (#18635)
|
||||||
|
+ [cinemax] Add support for cinemax.com
|
||||||
|
* [sixplay] Try extracting non-DRM protected manifests (#20849)
|
||||||
|
+ [youtube] Extract Youtube Music Auto-generated metadata (#20599, #20742)
|
||||||
|
- [wrzuta] Remove extractor (#20684, #20801)
|
||||||
|
* [twitch] Prefer source format (#20850)
|
||||||
|
+ [twitcasting] Add support for private videos (#20843)
|
||||||
|
* [reddit] Validate thumbnail URL (#20030)
|
||||||
|
* [yandexmusic] Fix track URL extraction (#20820)
|
||||||
|
|
||||||
|
|
||||||
version 2019.04.24
|
version 2019.04.24
|
||||||
|
|
||||||
Extractors
|
Extractors
|
||||||
|
10
Makefile
10
Makefile
@ -1,7 +1,7 @@
|
|||||||
all: youtube-dl README.md CONTRIBUTING.md README.txt youtube-dl.1 youtube-dl.bash-completion youtube-dl.zsh youtube-dl.fish supportedsites
|
all: youtube-dl README.md CONTRIBUTING.md README.txt youtube-dl.1 youtube-dl.bash-completion youtube-dl.zsh youtube-dl.fish supportedsites
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf youtube-dl.1.temp.md youtube-dl.1 youtube-dl.bash-completion README.txt MANIFEST build/ dist/ .coverage cover/ youtube-dl.tar.gz youtube-dl.zsh youtube-dl.fish youtube_dl/extractor/lazy_extractors.py *.dump *.part* *.ytdl *.info.json *.mp4 *.m4a *.flv *.mp3 *.avi *.mkv *.webm *.3gp *.wav *.ape *.swf *.jpg *.png CONTRIBUTING.md.tmp ISSUE_TEMPLATE.md.tmp youtube-dl youtube-dl.exe
|
rm -rf youtube-dl.1.temp.md youtube-dl.1 youtube-dl.bash-completion README.txt MANIFEST build/ dist/ .coverage cover/ youtube-dl.tar.gz youtube-dl.zsh youtube-dl.fish youtube_dl/extractor/lazy_extractors.py *.dump *.part* *.ytdl *.info.json *.mp4 *.m4a *.flv *.mp3 *.avi *.mkv *.webm *.3gp *.wav *.ape *.swf *.jpg *.png CONTRIBUTING.md.tmp youtube-dl youtube-dl.exe
|
||||||
find . -name "*.pyc" -delete
|
find . -name "*.pyc" -delete
|
||||||
find . -name "*.class" -delete
|
find . -name "*.class" -delete
|
||||||
|
|
||||||
@ -78,8 +78,12 @@ README.md: youtube_dl/*.py youtube_dl/*/*.py
|
|||||||
CONTRIBUTING.md: README.md
|
CONTRIBUTING.md: README.md
|
||||||
$(PYTHON) devscripts/make_contributing.py README.md CONTRIBUTING.md
|
$(PYTHON) devscripts/make_contributing.py README.md CONTRIBUTING.md
|
||||||
|
|
||||||
.github/ISSUE_TEMPLATE.md: devscripts/make_issue_template.py .github/ISSUE_TEMPLATE_tmpl.md youtube_dl/version.py
|
issuetemplates: devscripts/make_issue_template.py .github/ISSUE_TEMPLATE_tmpl/1_broken_site.md .github/ISSUE_TEMPLATE_tmpl/2_site_support_request.md .github/ISSUE_TEMPLATE_tmpl/3_site_feature_request.md .github/ISSUE_TEMPLATE_tmpl/4_bug_report.md .github/ISSUE_TEMPLATE_tmpl/5_feature_request.md youtube_dl/version.py
|
||||||
$(PYTHON) devscripts/make_issue_template.py .github/ISSUE_TEMPLATE_tmpl.md .github/ISSUE_TEMPLATE.md
|
$(PYTHON) devscripts/make_issue_template.py .github/ISSUE_TEMPLATE_tmpl/1_broken_site.md .github/ISSUE_TEMPLATE/1_broken_site.md
|
||||||
|
$(PYTHON) devscripts/make_issue_template.py .github/ISSUE_TEMPLATE_tmpl/2_site_support_request.md .github/ISSUE_TEMPLATE/2_site_support_request.md
|
||||||
|
$(PYTHON) devscripts/make_issue_template.py .github/ISSUE_TEMPLATE_tmpl/3_site_feature_request.md .github/ISSUE_TEMPLATE/3_site_feature_request.md
|
||||||
|
$(PYTHON) devscripts/make_issue_template.py .github/ISSUE_TEMPLATE_tmpl/4_bug_report.md .github/ISSUE_TEMPLATE/4_bug_report.md
|
||||||
|
$(PYTHON) devscripts/make_issue_template.py .github/ISSUE_TEMPLATE_tmpl/5_feature_request.md .github/ISSUE_TEMPLATE/5_feature_request.md
|
||||||
|
|
||||||
supportedsites:
|
supportedsites:
|
||||||
$(PYTHON) devscripts/make_supportedsites.py docs/supportedsites.md
|
$(PYTHON) devscripts/make_supportedsites.py docs/supportedsites.md
|
||||||
|
@ -78,8 +78,8 @@ sed -i "s/__version__ = '.*'/__version__ = '$version'/" youtube_dl/version.py
|
|||||||
sed -i "s/<unreleased>/$version/" ChangeLog
|
sed -i "s/<unreleased>/$version/" ChangeLog
|
||||||
|
|
||||||
/bin/echo -e "\n### Committing documentation, templates and youtube_dl/version.py..."
|
/bin/echo -e "\n### Committing documentation, templates and youtube_dl/version.py..."
|
||||||
make README.md CONTRIBUTING.md .github/ISSUE_TEMPLATE.md supportedsites
|
make README.md CONTRIBUTING.md issuetemplates supportedsites
|
||||||
git add README.md CONTRIBUTING.md .github/ISSUE_TEMPLATE.md docs/supportedsites.md youtube_dl/version.py ChangeLog
|
git add README.md CONTRIBUTING.md .github/ISSUE_TEMPLATE/1_broken_site.md .github/ISSUE_TEMPLATE/2_site_support_request.md .github/ISSUE_TEMPLATE/3_site_feature_request.md .github/ISSUE_TEMPLATE/4_bug_report.md .github/ISSUE_TEMPLATE/5_feature_request.md .github/ISSUE_TEMPLATE/6_question.md docs/supportedsites.md youtube_dl/version.py ChangeLog
|
||||||
git commit $gpg_sign_commits -m "release $version"
|
git commit $gpg_sign_commits -m "release $version"
|
||||||
|
|
||||||
/bin/echo -e "\n### Now tagging, signing and pushing..."
|
/bin/echo -e "\n### Now tagging, signing and pushing..."
|
||||||
|
@ -164,6 +164,7 @@
|
|||||||
- **chirbit**
|
- **chirbit**
|
||||||
- **chirbit:profile**
|
- **chirbit:profile**
|
||||||
- **Cinchcast**
|
- **Cinchcast**
|
||||||
|
- **Cinemax**
|
||||||
- **CiscoLiveSearch**
|
- **CiscoLiveSearch**
|
||||||
- **CiscoLiveSession**
|
- **CiscoLiveSession**
|
||||||
- **CJSW**
|
- **CJSW**
|
||||||
@ -237,8 +238,6 @@
|
|||||||
- **DouyuTV**: 斗鱼
|
- **DouyuTV**: 斗鱼
|
||||||
- **DPlay**
|
- **DPlay**
|
||||||
- **DPlayIt**
|
- **DPlayIt**
|
||||||
- **dramafever**
|
|
||||||
- **dramafever:series**
|
|
||||||
- **DRBonanza**
|
- **DRBonanza**
|
||||||
- **Dropbox**
|
- **Dropbox**
|
||||||
- **DrTuber**
|
- **DrTuber**
|
||||||
@ -488,6 +487,7 @@
|
|||||||
- **MatchTV**
|
- **MatchTV**
|
||||||
- **MDR**: MDR.DE and KiKA
|
- **MDR**: MDR.DE and KiKA
|
||||||
- **media.ccc.de**
|
- **media.ccc.de**
|
||||||
|
- **media.ccc.de:lists**
|
||||||
- **Medialaan**
|
- **Medialaan**
|
||||||
- **Mediaset**
|
- **Mediaset**
|
||||||
- **Mediasite**
|
- **Mediasite**
|
||||||
@ -857,6 +857,8 @@
|
|||||||
- **StretchInternet**
|
- **StretchInternet**
|
||||||
- **stv:player**
|
- **stv:player**
|
||||||
- **SunPorno**
|
- **SunPorno**
|
||||||
|
- **sverigesradio:episode**
|
||||||
|
- **sverigesradio:publication**
|
||||||
- **SVT**
|
- **SVT**
|
||||||
- **SVTPage**
|
- **SVTPage**
|
||||||
- **SVTPlay**: SVT Play and Öppet arkiv
|
- **SVTPlay**: SVT Play and Öppet arkiv
|
||||||
@ -1102,8 +1104,6 @@
|
|||||||
- **Wistia**
|
- **Wistia**
|
||||||
- **wnl**: npo.nl, ntr.nl, omroepwnl.nl, zapp.nl and npo3.nl
|
- **wnl**: npo.nl, ntr.nl, omroepwnl.nl, zapp.nl and npo3.nl
|
||||||
- **WorldStarHipHop**
|
- **WorldStarHipHop**
|
||||||
- **wrzuta.pl**
|
|
||||||
- **wrzuta.pl:playlist**
|
|
||||||
- **WSJ**: Wall Street Journal
|
- **WSJ**: Wall Street Journal
|
||||||
- **WSJArticle**
|
- **WSJArticle**
|
||||||
- **WWE**
|
- **WWE**
|
||||||
|
@ -65,14 +65,15 @@ class ADNIE(InfoExtractor):
|
|||||||
if subtitle_location:
|
if subtitle_location:
|
||||||
enc_subtitles = self._download_webpage(
|
enc_subtitles = self._download_webpage(
|
||||||
urljoin(self._BASE_URL, subtitle_location),
|
urljoin(self._BASE_URL, subtitle_location),
|
||||||
video_id, 'Downloading subtitles data', fatal=False)
|
video_id, 'Downloading subtitles data', fatal=False,
|
||||||
|
headers={'Origin': 'https://animedigitalnetwork.fr'})
|
||||||
if not enc_subtitles:
|
if not enc_subtitles:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# http://animedigitalnetwork.fr/components/com_vodvideo/videojs/adn-vjs.min.js
|
# http://animedigitalnetwork.fr/components/com_vodvideo/videojs/adn-vjs.min.js
|
||||||
dec_subtitles = intlist_to_bytes(aes_cbc_decrypt(
|
dec_subtitles = intlist_to_bytes(aes_cbc_decrypt(
|
||||||
bytes_to_intlist(compat_b64decode(enc_subtitles[24:])),
|
bytes_to_intlist(compat_b64decode(enc_subtitles[24:])),
|
||||||
bytes_to_intlist(binascii.unhexlify(self._K + '4421de0a5f0814ba')),
|
bytes_to_intlist(binascii.unhexlify(self._K + '4b8ef13ec1872730')),
|
||||||
bytes_to_intlist(compat_b64decode(enc_subtitles[:24]))
|
bytes_to_intlist(compat_b64decode(enc_subtitles[:24]))
|
||||||
))
|
))
|
||||||
subtitles_json = self._parse_json(
|
subtitles_json = self._parse_json(
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
|
# coding: utf-8
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
int_or_none,
|
int_or_none,
|
||||||
parse_iso8601,
|
parse_iso8601,
|
||||||
|
try_get,
|
||||||
|
url_or_none,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -18,11 +21,13 @@ class CCCIE(InfoExtractor):
|
|||||||
'id': '1839',
|
'id': '1839',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'title': 'Introduction to Processor Design',
|
'title': 'Introduction to Processor Design',
|
||||||
|
'creator': 'byterazor',
|
||||||
'description': 'md5:df55f6d073d4ceae55aae6f2fd98a0ac',
|
'description': 'md5:df55f6d073d4ceae55aae6f2fd98a0ac',
|
||||||
'thumbnail': r're:^https?://.*\.jpg$',
|
'thumbnail': r're:^https?://.*\.jpg$',
|
||||||
'upload_date': '20131228',
|
'upload_date': '20131228',
|
||||||
'timestamp': 1388188800,
|
'timestamp': 1388188800,
|
||||||
'duration': 3710,
|
'duration': 3710,
|
||||||
|
'tags': list,
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
'url': 'https://media.ccc.de/v/32c3-7368-shopshifting#download',
|
'url': 'https://media.ccc.de/v/32c3-7368-shopshifting#download',
|
||||||
@ -68,6 +73,7 @@ class CCCIE(InfoExtractor):
|
|||||||
'id': event_id,
|
'id': event_id,
|
||||||
'display_id': display_id,
|
'display_id': display_id,
|
||||||
'title': event_data['title'],
|
'title': event_data['title'],
|
||||||
|
'creator': try_get(event_data, lambda x: ', '.join(x['persons'])),
|
||||||
'description': event_data.get('description'),
|
'description': event_data.get('description'),
|
||||||
'thumbnail': event_data.get('thumb_url'),
|
'thumbnail': event_data.get('thumb_url'),
|
||||||
'timestamp': parse_iso8601(event_data.get('date')),
|
'timestamp': parse_iso8601(event_data.get('date')),
|
||||||
@ -75,3 +81,31 @@ class CCCIE(InfoExtractor):
|
|||||||
'tags': event_data.get('tags'),
|
'tags': event_data.get('tags'),
|
||||||
'formats': formats,
|
'formats': formats,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CCCPlaylistIE(InfoExtractor):
|
||||||
|
IE_NAME = 'media.ccc.de:lists'
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?media\.ccc\.de/c/(?P<id>[^/?#&]+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://media.ccc.de/c/30c3',
|
||||||
|
'info_dict': {
|
||||||
|
'title': '30C3',
|
||||||
|
'id': '30c3',
|
||||||
|
},
|
||||||
|
'playlist_count': 135,
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
playlist_id = self._match_id(url).lower()
|
||||||
|
|
||||||
|
conf = self._download_json(
|
||||||
|
'https://media.ccc.de/public/conferences/' + playlist_id,
|
||||||
|
playlist_id)
|
||||||
|
|
||||||
|
entries = []
|
||||||
|
for e in conf['events']:
|
||||||
|
event_url = url_or_none(e.get('frontend_link'))
|
||||||
|
if event_url:
|
||||||
|
entries.append(self.url_result(event_url, ie=CCCIE.ie_key()))
|
||||||
|
|
||||||
|
return self.playlist_result(entries, playlist_id, conf.get('title'))
|
||||||
|
29
youtube_dl/extractor/cinemax.py
Normal file
29
youtube_dl/extractor/cinemax.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from .hbo import HBOBaseIE
|
||||||
|
|
||||||
|
|
||||||
|
class CinemaxIE(HBOBaseIE):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?cinemax\.com/(?P<path>[^/]+/video/[0-9a-z-]+-(?P<id>\d+))'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://www.cinemax.com/warrior/video/s1-ep-1-recap-20126903',
|
||||||
|
'md5': '82e0734bba8aa7ef526c9dd00cf35a05',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '20126903',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'S1 Ep 1: Recap',
|
||||||
|
},
|
||||||
|
'expected_warnings': ['Unknown MIME type application/mp4 in DASH manifest'],
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.cinemax.com/warrior/video/s1-ep-1-recap-20126903.embed',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
path, video_id = re.match(self._VALID_URL, url).groups()
|
||||||
|
info = self._extract_info('https://www.cinemax.com/%s.xml' % path, video_id)
|
||||||
|
info['id'] = video_id
|
||||||
|
return info
|
@ -1,266 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import itertools
|
|
||||||
import json
|
|
||||||
|
|
||||||
from .common import InfoExtractor
|
|
||||||
from ..compat import (
|
|
||||||
compat_HTTPError,
|
|
||||||
compat_urlparse,
|
|
||||||
)
|
|
||||||
from ..utils import (
|
|
||||||
clean_html,
|
|
||||||
ExtractorError,
|
|
||||||
int_or_none,
|
|
||||||
parse_age_limit,
|
|
||||||
parse_duration,
|
|
||||||
unified_timestamp,
|
|
||||||
url_or_none,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DramaFeverBaseIE(InfoExtractor):
|
|
||||||
_NETRC_MACHINE = 'dramafever'
|
|
||||||
|
|
||||||
_CONSUMER_SECRET = 'DA59dtVXYLxajktV'
|
|
||||||
|
|
||||||
_consumer_secret = None
|
|
||||||
|
|
||||||
def _get_consumer_secret(self):
|
|
||||||
mainjs = self._download_webpage(
|
|
||||||
'http://www.dramafever.com/static/51afe95/df2014/scripts/main.js',
|
|
||||||
None, 'Downloading main.js', fatal=False)
|
|
||||||
if not mainjs:
|
|
||||||
return self._CONSUMER_SECRET
|
|
||||||
return self._search_regex(
|
|
||||||
r"var\s+cs\s*=\s*'([^']+)'", mainjs,
|
|
||||||
'consumer secret', default=self._CONSUMER_SECRET)
|
|
||||||
|
|
||||||
def _real_initialize(self):
|
|
||||||
self._consumer_secret = self._get_consumer_secret()
|
|
||||||
self._login()
|
|
||||||
|
|
||||||
def _login(self):
|
|
||||||
username, password = self._get_login_info()
|
|
||||||
if username is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
login_form = {
|
|
||||||
'username': username,
|
|
||||||
'password': password,
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = self._download_json(
|
|
||||||
'https://www.dramafever.com/api/users/login', None, 'Logging in',
|
|
||||||
data=json.dumps(login_form).encode('utf-8'), headers={
|
|
||||||
'x-consumer-key': self._consumer_secret,
|
|
||||||
})
|
|
||||||
except ExtractorError as e:
|
|
||||||
if isinstance(e.cause, compat_HTTPError) and e.cause.code in (403, 404):
|
|
||||||
response = self._parse_json(
|
|
||||||
e.cause.read().decode('utf-8'), None)
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
|
|
||||||
# Successful login
|
|
||||||
if response.get('result') or response.get('guid') or response.get('user_guid'):
|
|
||||||
return
|
|
||||||
|
|
||||||
errors = response.get('errors')
|
|
||||||
if errors and isinstance(errors, list):
|
|
||||||
error = errors[0]
|
|
||||||
message = error.get('message') or error['reason']
|
|
||||||
raise ExtractorError('Unable to login: %s' % message, expected=True)
|
|
||||||
raise ExtractorError('Unable to log in')
|
|
||||||
|
|
||||||
|
|
||||||
class DramaFeverIE(DramaFeverBaseIE):
|
|
||||||
IE_NAME = 'dramafever'
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?dramafever\.com/(?:[^/]+/)?drama/(?P<id>[0-9]+/[0-9]+)(?:/|$)'
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'https://www.dramafever.com/drama/4274/1/Heirs/',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '4274.1',
|
|
||||||
'ext': 'wvm',
|
|
||||||
'title': 'Heirs - Episode 1',
|
|
||||||
'description': 'md5:362a24ba18209f6276e032a651c50bc2',
|
|
||||||
'thumbnail': r're:^https?://.*\.jpg',
|
|
||||||
'duration': 3783,
|
|
||||||
'timestamp': 1381354993,
|
|
||||||
'upload_date': '20131009',
|
|
||||||
'series': 'Heirs',
|
|
||||||
'season_number': 1,
|
|
||||||
'episode': 'Episode 1',
|
|
||||||
'episode_number': 1,
|
|
||||||
},
|
|
||||||
'params': {
|
|
||||||
# m3u8 download
|
|
||||||
'skip_download': True,
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
'url': 'http://www.dramafever.com/drama/4826/4/Mnet_Asian_Music_Awards_2015/?ap=1',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '4826.4',
|
|
||||||
'ext': 'flv',
|
|
||||||
'title': 'Mnet Asian Music Awards 2015',
|
|
||||||
'description': 'md5:3ff2ee8fedaef86e076791c909cf2e91',
|
|
||||||
'episode': 'Mnet Asian Music Awards 2015 - Part 3',
|
|
||||||
'episode_number': 4,
|
|
||||||
'thumbnail': r're:^https?://.*\.jpg',
|
|
||||||
'timestamp': 1450213200,
|
|
||||||
'upload_date': '20151215',
|
|
||||||
'duration': 5359,
|
|
||||||
},
|
|
||||||
'params': {
|
|
||||||
# m3u8 download
|
|
||||||
'skip_download': True,
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
'url': 'https://www.dramafever.com/zh-cn/drama/4972/15/Doctor_Romantic/',
|
|
||||||
'only_matching': True,
|
|
||||||
}]
|
|
||||||
|
|
||||||
def _call_api(self, path, video_id, note, fatal=False):
|
|
||||||
return self._download_json(
|
|
||||||
'https://www.dramafever.com/api/5/' + path,
|
|
||||||
video_id, note=note, headers={
|
|
||||||
'x-consumer-key': self._consumer_secret,
|
|
||||||
}, fatal=fatal)
|
|
||||||
|
|
||||||
def _get_subtitles(self, video_id):
|
|
||||||
subtitles = {}
|
|
||||||
subs = self._call_api(
|
|
||||||
'video/%s/subtitles/webvtt/' % video_id, video_id,
|
|
||||||
'Downloading subtitles JSON', fatal=False)
|
|
||||||
if not subs or not isinstance(subs, list):
|
|
||||||
return subtitles
|
|
||||||
for sub in subs:
|
|
||||||
if not isinstance(sub, dict):
|
|
||||||
continue
|
|
||||||
sub_url = url_or_none(sub.get('url'))
|
|
||||||
if not sub_url:
|
|
||||||
continue
|
|
||||||
subtitles.setdefault(
|
|
||||||
sub.get('code') or sub.get('language') or 'en', []).append({
|
|
||||||
'url': sub_url
|
|
||||||
})
|
|
||||||
return subtitles
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
video_id = self._match_id(url).replace('/', '.')
|
|
||||||
|
|
||||||
series_id, episode_number = video_id.split('.')
|
|
||||||
|
|
||||||
video = self._call_api(
|
|
||||||
'series/%s/episodes/%s/' % (series_id, episode_number), video_id,
|
|
||||||
'Downloading video JSON')
|
|
||||||
|
|
||||||
formats = []
|
|
||||||
download_assets = video.get('download_assets')
|
|
||||||
if download_assets and isinstance(download_assets, dict):
|
|
||||||
for format_id, format_dict in download_assets.items():
|
|
||||||
if not isinstance(format_dict, dict):
|
|
||||||
continue
|
|
||||||
format_url = url_or_none(format_dict.get('url'))
|
|
||||||
if not format_url:
|
|
||||||
continue
|
|
||||||
formats.append({
|
|
||||||
'url': format_url,
|
|
||||||
'format_id': format_id,
|
|
||||||
'filesize': int_or_none(video.get('filesize')),
|
|
||||||
})
|
|
||||||
|
|
||||||
stream = self._call_api(
|
|
||||||
'video/%s/stream/' % video_id, video_id, 'Downloading stream JSON',
|
|
||||||
fatal=False)
|
|
||||||
if stream:
|
|
||||||
stream_url = stream.get('stream_url')
|
|
||||||
if stream_url:
|
|
||||||
formats.extend(self._extract_m3u8_formats(
|
|
||||||
stream_url, video_id, 'mp4', entry_protocol='m3u8_native',
|
|
||||||
m3u8_id='hls', fatal=False))
|
|
||||||
self._sort_formats(formats)
|
|
||||||
|
|
||||||
title = video.get('title') or 'Episode %s' % episode_number
|
|
||||||
description = video.get('description')
|
|
||||||
thumbnail = video.get('thumbnail')
|
|
||||||
timestamp = unified_timestamp(video.get('release_date'))
|
|
||||||
duration = parse_duration(video.get('duration'))
|
|
||||||
age_limit = parse_age_limit(video.get('tv_rating'))
|
|
||||||
series = video.get('series_title')
|
|
||||||
season_number = int_or_none(video.get('season'))
|
|
||||||
|
|
||||||
if series:
|
|
||||||
title = '%s - %s' % (series, title)
|
|
||||||
|
|
||||||
subtitles = self.extract_subtitles(video_id)
|
|
||||||
|
|
||||||
return {
|
|
||||||
'id': video_id,
|
|
||||||
'title': title,
|
|
||||||
'description': description,
|
|
||||||
'thumbnail': thumbnail,
|
|
||||||
'duration': duration,
|
|
||||||
'timestamp': timestamp,
|
|
||||||
'age_limit': age_limit,
|
|
||||||
'series': series,
|
|
||||||
'season_number': season_number,
|
|
||||||
'episode_number': int_or_none(episode_number),
|
|
||||||
'formats': formats,
|
|
||||||
'subtitles': subtitles,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class DramaFeverSeriesIE(DramaFeverBaseIE):
|
|
||||||
IE_NAME = 'dramafever:series'
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?dramafever\.com/(?:[^/]+/)?drama/(?P<id>[0-9]+)(?:/(?:(?!\d+(?:/|$)).+)?)?$'
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'http://www.dramafever.com/drama/4512/Cooking_with_Shin/',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '4512',
|
|
||||||
'title': 'Cooking with Shin',
|
|
||||||
'description': 'md5:84a3f26e3cdc3fb7f500211b3593b5c1',
|
|
||||||
},
|
|
||||||
'playlist_count': 4,
|
|
||||||
}, {
|
|
||||||
'url': 'http://www.dramafever.com/drama/124/IRIS/',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '124',
|
|
||||||
'title': 'IRIS',
|
|
||||||
'description': 'md5:b3a30e587cf20c59bd1c01ec0ee1b862',
|
|
||||||
},
|
|
||||||
'playlist_count': 20,
|
|
||||||
}]
|
|
||||||
|
|
||||||
_PAGE_SIZE = 60 # max is 60 (see http://api.drama9.com/#get--api-4-episode-series-)
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
series_id = self._match_id(url)
|
|
||||||
|
|
||||||
series = self._download_json(
|
|
||||||
'http://www.dramafever.com/api/4/series/query/?cs=%s&series_id=%s'
|
|
||||||
% (self._consumer_secret, series_id),
|
|
||||||
series_id, 'Downloading series JSON')['series'][series_id]
|
|
||||||
|
|
||||||
title = clean_html(series['name'])
|
|
||||||
description = clean_html(series.get('description') or series.get('description_short'))
|
|
||||||
|
|
||||||
entries = []
|
|
||||||
for page_num in itertools.count(1):
|
|
||||||
episodes = self._download_json(
|
|
||||||
'http://www.dramafever.com/api/4/episode/series/?cs=%s&series_id=%s&page_size=%d&page_number=%d'
|
|
||||||
% (self._consumer_secret, series_id, self._PAGE_SIZE, page_num),
|
|
||||||
series_id, 'Downloading episodes JSON page #%d' % page_num)
|
|
||||||
for episode in episodes.get('value', []):
|
|
||||||
episode_url = episode.get('episode_url')
|
|
||||||
if not episode_url:
|
|
||||||
continue
|
|
||||||
entries.append(self.url_result(
|
|
||||||
compat_urlparse.urljoin(url, episode_url),
|
|
||||||
'DramaFever', episode.get('guid')))
|
|
||||||
if page_num == episodes['num_pages']:
|
|
||||||
break
|
|
||||||
|
|
||||||
return self.playlist_result(entries, series_id, title, description)
|
|
@ -177,7 +177,10 @@ from .cbsnews import (
|
|||||||
CBSNewsLiveVideoIE,
|
CBSNewsLiveVideoIE,
|
||||||
)
|
)
|
||||||
from .cbssports import CBSSportsIE
|
from .cbssports import CBSSportsIE
|
||||||
from .ccc import CCCIE
|
from .ccc import (
|
||||||
|
CCCIE,
|
||||||
|
CCCPlaylistIE,
|
||||||
|
)
|
||||||
from .ccma import CCMAIE
|
from .ccma import CCMAIE
|
||||||
from .cctv import CCTVIE
|
from .cctv import CCTVIE
|
||||||
from .cda import CDAIE
|
from .cda import CDAIE
|
||||||
@ -194,6 +197,7 @@ from .chirbit import (
|
|||||||
ChirbitProfileIE,
|
ChirbitProfileIE,
|
||||||
)
|
)
|
||||||
from .cinchcast import CinchcastIE
|
from .cinchcast import CinchcastIE
|
||||||
|
from .cinemax import CinemaxIE
|
||||||
from .ciscolive import (
|
from .ciscolive import (
|
||||||
CiscoLiveSessionIE,
|
CiscoLiveSessionIE,
|
||||||
CiscoLiveSearchIE,
|
CiscoLiveSearchIE,
|
||||||
@ -283,10 +287,6 @@ from .dplay import (
|
|||||||
DPlayIE,
|
DPlayIE,
|
||||||
DPlayItIE,
|
DPlayItIE,
|
||||||
)
|
)
|
||||||
from .dramafever import (
|
|
||||||
DramaFeverIE,
|
|
||||||
DramaFeverSeriesIE,
|
|
||||||
)
|
|
||||||
from .dreisat import DreiSatIE
|
from .dreisat import DreiSatIE
|
||||||
from .drbonanza import DRBonanzaIE
|
from .drbonanza import DRBonanzaIE
|
||||||
from .drtuber import DrTuberIE
|
from .drtuber import DrTuberIE
|
||||||
@ -1037,7 +1037,10 @@ from .skynewsarabia import (
|
|||||||
SkyNewsArabiaIE,
|
SkyNewsArabiaIE,
|
||||||
SkyNewsArabiaArticleIE,
|
SkyNewsArabiaArticleIE,
|
||||||
)
|
)
|
||||||
from .skysports import SkySportsIE
|
from .sky import (
|
||||||
|
SkyNewsIE,
|
||||||
|
SkySportsIE,
|
||||||
|
)
|
||||||
from .slideshare import SlideshareIE
|
from .slideshare import SlideshareIE
|
||||||
from .slideslive import SlidesLiveIE
|
from .slideslive import SlidesLiveIE
|
||||||
from .slutload import SlutloadIE
|
from .slutload import SlutloadIE
|
||||||
@ -1101,6 +1104,10 @@ from .streetvoice import StreetVoiceIE
|
|||||||
from .stretchinternet import StretchInternetIE
|
from .stretchinternet import StretchInternetIE
|
||||||
from .stv import STVPlayerIE
|
from .stv import STVPlayerIE
|
||||||
from .sunporno import SunPornoIE
|
from .sunporno import SunPornoIE
|
||||||
|
from .sverigesradio import (
|
||||||
|
SverigesRadioEpisodeIE,
|
||||||
|
SverigesRadioPublicationIE,
|
||||||
|
)
|
||||||
from .svt import (
|
from .svt import (
|
||||||
SVTIE,
|
SVTIE,
|
||||||
SVTPageIE,
|
SVTPageIE,
|
||||||
@ -1422,10 +1429,6 @@ from .weiqitv import WeiqiTVIE
|
|||||||
from .wimp import WimpIE
|
from .wimp import WimpIE
|
||||||
from .wistia import WistiaIE
|
from .wistia import WistiaIE
|
||||||
from .worldstarhiphop import WorldStarHipHopIE
|
from .worldstarhiphop import WorldStarHipHopIE
|
||||||
from .wrzuta import (
|
|
||||||
WrzutaIE,
|
|
||||||
WrzutaPlaylistIE,
|
|
||||||
)
|
|
||||||
from .wsj import (
|
from .wsj import (
|
||||||
WSJIE,
|
WSJIE,
|
||||||
WSJArticleIE,
|
WSJArticleIE,
|
||||||
|
@ -22,8 +22,6 @@ from ..utils import (
|
|||||||
|
|
||||||
|
|
||||||
class FourTubeBaseIE(InfoExtractor):
|
class FourTubeBaseIE(InfoExtractor):
|
||||||
_TKN_HOST = 'tkn.kodicdn.com'
|
|
||||||
|
|
||||||
def _extract_formats(self, url, video_id, media_id, sources):
|
def _extract_formats(self, url, video_id, media_id, sources):
|
||||||
token_url = 'https://%s/%s/desktop/%s' % (
|
token_url = 'https://%s/%s/desktop/%s' % (
|
||||||
self._TKN_HOST, media_id, '+'.join(sources))
|
self._TKN_HOST, media_id, '+'.join(sources))
|
||||||
@ -120,6 +118,7 @@ class FourTubeIE(FourTubeBaseIE):
|
|||||||
IE_NAME = '4tube'
|
IE_NAME = '4tube'
|
||||||
_VALID_URL = r'https?://(?:(?P<kind>www|m)\.)?4tube\.com/(?:videos|embed)/(?P<id>\d+)(?:/(?P<display_id>[^/?#&]+))?'
|
_VALID_URL = r'https?://(?:(?P<kind>www|m)\.)?4tube\.com/(?:videos|embed)/(?P<id>\d+)(?:/(?P<display_id>[^/?#&]+))?'
|
||||||
_URL_TEMPLATE = 'https://www.4tube.com/videos/%s/video'
|
_URL_TEMPLATE = 'https://www.4tube.com/videos/%s/video'
|
||||||
|
_TKN_HOST = 'token.4tube.com'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'http://www.4tube.com/videos/209733/hot-babe-holly-michaels-gets-her-ass-stuffed-by-black',
|
'url': 'http://www.4tube.com/videos/209733/hot-babe-holly-michaels-gets-her-ass-stuffed-by-black',
|
||||||
'md5': '6516c8ac63b03de06bc8eac14362db4f',
|
'md5': '6516c8ac63b03de06bc8eac14362db4f',
|
||||||
@ -149,6 +148,7 @@ class FourTubeIE(FourTubeBaseIE):
|
|||||||
class FuxIE(FourTubeBaseIE):
|
class FuxIE(FourTubeBaseIE):
|
||||||
_VALID_URL = r'https?://(?:(?P<kind>www|m)\.)?fux\.com/(?:video|embed)/(?P<id>\d+)(?:/(?P<display_id>[^/?#&]+))?'
|
_VALID_URL = r'https?://(?:(?P<kind>www|m)\.)?fux\.com/(?:video|embed)/(?P<id>\d+)(?:/(?P<display_id>[^/?#&]+))?'
|
||||||
_URL_TEMPLATE = 'https://www.fux.com/video/%s/video'
|
_URL_TEMPLATE = 'https://www.fux.com/video/%s/video'
|
||||||
|
_TKN_HOST = 'token.fux.com'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.fux.com/video/195359/awesome-fucking-kitchen-ends-cum-swallow',
|
'url': 'https://www.fux.com/video/195359/awesome-fucking-kitchen-ends-cum-swallow',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
@ -280,6 +280,7 @@ class PornTubeIE(FourTubeBaseIE):
|
|||||||
class PornerBrosIE(FourTubeBaseIE):
|
class PornerBrosIE(FourTubeBaseIE):
|
||||||
_VALID_URL = r'https?://(?:(?P<kind>www|m)\.)?pornerbros\.com/(?:videos/(?P<display_id>[^/]+)_|embed/)(?P<id>\d+)'
|
_VALID_URL = r'https?://(?:(?P<kind>www|m)\.)?pornerbros\.com/(?:videos/(?P<display_id>[^/]+)_|embed/)(?P<id>\d+)'
|
||||||
_URL_TEMPLATE = 'https://www.pornerbros.com/videos/video_%s'
|
_URL_TEMPLATE = 'https://www.pornerbros.com/videos/video_%s'
|
||||||
|
_TKN_HOST = 'token.pornerbros.com'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.pornerbros.com/videos/skinny-brunette-takes-big-cock-down-her-anal-hole_181369',
|
'url': 'https://www.pornerbros.com/videos/skinny-brunette-takes-big-cock-down-her-anal-hole_181369',
|
||||||
'md5': '6516c8ac63b03de06bc8eac14362db4f',
|
'md5': '6516c8ac63b03de06bc8eac14362db4f',
|
||||||
|
@ -66,7 +66,7 @@ class FOXIE(AdobePassIE):
|
|||||||
'https://api2.fox.com/v2.0/' + path,
|
'https://api2.fox.com/v2.0/' + path,
|
||||||
video_id, data=data, headers=headers)
|
video_id, data=data, headers=headers)
|
||||||
except ExtractorError as e:
|
except ExtractorError as e:
|
||||||
if isinstance(e.cause, compat_HTTPError) and e.cause.status == 403:
|
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:
|
||||||
entitlement_issues = self._parse_json(
|
entitlement_issues = self._parse_json(
|
||||||
e.cause.read().decode(), video_id)['entitlementIssues']
|
e.cause.read().decode(), video_id)['entitlementIssues']
|
||||||
for e in entitlement_issues:
|
for e in entitlement_issues:
|
||||||
@ -100,7 +100,7 @@ class FOXIE(AdobePassIE):
|
|||||||
try:
|
try:
|
||||||
m3u8_url = self._download_json(release_url, video_id)['playURL']
|
m3u8_url = self._download_json(release_url, video_id)['playURL']
|
||||||
except ExtractorError as e:
|
except ExtractorError as e:
|
||||||
if isinstance(e.cause, compat_HTTPError) and e.cause.status == 403:
|
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:
|
||||||
error = self._parse_json(e.cause.read().decode(), video_id)
|
error = self._parse_json(e.cause.read().decode(), video_id)
|
||||||
if error.get('exception') == 'GeoLocationBlocked':
|
if error.get('exception') == 'GeoLocationBlocked':
|
||||||
self.raise_geo_restricted(countries=['US'])
|
self.raise_geo_restricted(countries=['US'])
|
||||||
|
@ -371,12 +371,13 @@ class FranceTVInfoIE(FranceTVBaseInfoExtractor):
|
|||||||
self.url_result(dailymotion_url, DailymotionIE.ie_key())
|
self.url_result(dailymotion_url, DailymotionIE.ie_key())
|
||||||
for dailymotion_url in dailymotion_urls])
|
for dailymotion_url in dailymotion_urls])
|
||||||
|
|
||||||
video_id, catalogue = self._search_regex(
|
video_id = self._search_regex(
|
||||||
(r'id-video=([^@]+@[^"]+)',
|
(r'player\.load[^;]+src:\s*["\']([^"\']+)',
|
||||||
|
r'id-video=([^@]+@[^"]+)',
|
||||||
r'<a[^>]+href="(?:https?:)?//videos\.francetv\.fr/video/([^@]+@[^"]+)"'),
|
r'<a[^>]+href="(?:https?:)?//videos\.francetv\.fr/video/([^@]+@[^"]+)"'),
|
||||||
webpage, 'video id').split('@')
|
webpage, 'video id')
|
||||||
|
|
||||||
return self._make_url_result(video_id, catalogue)
|
return self._make_url_result(video_id)
|
||||||
|
|
||||||
|
|
||||||
class FranceTVInfoSportIE(FranceTVBaseInfoExtractor):
|
class FranceTVInfoSportIE(FranceTVBaseInfoExtractor):
|
||||||
|
@ -13,19 +13,7 @@ from ..utils import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class HBOIE(InfoExtractor):
|
class HBOBaseIE(InfoExtractor):
|
||||||
IE_NAME = 'hbo'
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?hbo\.com/(?:video|embed)(?:/[^/]+)*/(?P<id>[^/?#]+)'
|
|
||||||
_TEST = {
|
|
||||||
'url': 'https://www.hbo.com/video/game-of-thrones/seasons/season-8/videos/trailer',
|
|
||||||
'md5': '8126210656f433c452a21367f9ad85b3',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '22113301',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': 'Game of Thrones - Trailer',
|
|
||||||
},
|
|
||||||
'expected_warnings': ['Unknown MIME type application/mp4 in DASH manifest'],
|
|
||||||
}
|
|
||||||
_FORMATS_INFO = {
|
_FORMATS_INFO = {
|
||||||
'pro7': {
|
'pro7': {
|
||||||
'width': 1280,
|
'width': 1280,
|
||||||
@ -65,12 +53,8 @@ class HBOIE(InfoExtractor):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _extract_info(self, url, display_id):
|
||||||
display_id = self._match_id(url)
|
video_data = self._download_xml(url, display_id)
|
||||||
webpage = self._download_webpage(url, display_id)
|
|
||||||
location_path = self._parse_json(self._html_search_regex(
|
|
||||||
r'data-state="({.+?})"', webpage, 'state'), display_id)['video']['locationUrl']
|
|
||||||
video_data = self._download_xml(urljoin(url, location_path), display_id)
|
|
||||||
video_id = xpath_text(video_data, 'id', fatal=True)
|
video_id = xpath_text(video_data, 'id', fatal=True)
|
||||||
episode_title = title = xpath_text(video_data, 'title', fatal=True)
|
episode_title = title = xpath_text(video_data, 'title', fatal=True)
|
||||||
series = xpath_text(video_data, 'program')
|
series = xpath_text(video_data, 'program')
|
||||||
@ -167,3 +151,25 @@ class HBOIE(InfoExtractor):
|
|||||||
'thumbnails': thumbnails,
|
'thumbnails': thumbnails,
|
||||||
'subtitles': subtitles,
|
'subtitles': subtitles,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class HBOIE(HBOBaseIE):
|
||||||
|
IE_NAME = 'hbo'
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?hbo\.com/(?:video|embed)(?:/[^/]+)*/(?P<id>[^/?#]+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'https://www.hbo.com/video/game-of-thrones/seasons/season-8/videos/trailer',
|
||||||
|
'md5': '8126210656f433c452a21367f9ad85b3',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '22113301',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Game of Thrones - Trailer',
|
||||||
|
},
|
||||||
|
'expected_warnings': ['Unknown MIME type application/mp4 in DASH manifest'],
|
||||||
|
}
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
display_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, display_id)
|
||||||
|
location_path = self._parse_json(self._html_search_regex(
|
||||||
|
r'data-state="({.+?})"', webpage, 'state'), display_id)['video']['locationUrl']
|
||||||
|
return self._extract_info(urljoin(url, location_path), display_id)
|
||||||
|
@ -4,40 +4,59 @@ from __future__ import unicode_literals
|
|||||||
import hashlib
|
import hashlib
|
||||||
import hmac
|
import hmac
|
||||||
import time
|
import time
|
||||||
|
import uuid
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..compat import compat_HTTPError
|
from ..compat import (
|
||||||
|
compat_HTTPError,
|
||||||
|
compat_str,
|
||||||
|
)
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
determine_ext,
|
determine_ext,
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
int_or_none,
|
int_or_none,
|
||||||
|
str_or_none,
|
||||||
try_get,
|
try_get,
|
||||||
|
url_or_none,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class HotStarBaseIE(InfoExtractor):
|
class HotStarBaseIE(InfoExtractor):
|
||||||
_AKAMAI_ENCRYPTION_KEY = b'\x05\xfc\x1a\x01\xca\xc9\x4b\xc4\x12\xfc\x53\x12\x07\x75\xf9\xee'
|
_AKAMAI_ENCRYPTION_KEY = b'\x05\xfc\x1a\x01\xca\xc9\x4b\xc4\x12\xfc\x53\x12\x07\x75\xf9\xee'
|
||||||
|
|
||||||
def _call_api(self, path, video_id, query_name='contentId'):
|
def _call_api_impl(self, path, video_id, query):
|
||||||
st = int(time.time())
|
st = int(time.time())
|
||||||
exp = st + 6000
|
exp = st + 6000
|
||||||
auth = 'st=%d~exp=%d~acl=/*' % (st, exp)
|
auth = 'st=%d~exp=%d~acl=/*' % (st, exp)
|
||||||
auth += '~hmac=' + hmac.new(self._AKAMAI_ENCRYPTION_KEY, auth.encode(), hashlib.sha256).hexdigest()
|
auth += '~hmac=' + hmac.new(self._AKAMAI_ENCRYPTION_KEY, auth.encode(), hashlib.sha256).hexdigest()
|
||||||
response = self._download_json(
|
response = self._download_json(
|
||||||
'https://api.hotstar.com/' + path,
|
'https://api.hotstar.com/' + path, video_id, headers={
|
||||||
video_id, headers={
|
|
||||||
'hotstarauth': auth,
|
'hotstarauth': auth,
|
||||||
'x-country-code': 'IN',
|
'x-country-code': 'IN',
|
||||||
'x-platform-code': 'JIO',
|
'x-platform-code': 'JIO',
|
||||||
}, query={
|
}, query=query)
|
||||||
query_name: video_id,
|
|
||||||
'tas': 10000,
|
|
||||||
})
|
|
||||||
if response['statusCode'] != 'OK':
|
if response['statusCode'] != 'OK':
|
||||||
raise ExtractorError(
|
raise ExtractorError(
|
||||||
response['body']['message'], expected=True)
|
response['body']['message'], expected=True)
|
||||||
return response['body']['results']
|
return response['body']['results']
|
||||||
|
|
||||||
|
def _call_api(self, path, video_id, query_name='contentId'):
|
||||||
|
return self._call_api_impl(path, video_id, {
|
||||||
|
query_name: video_id,
|
||||||
|
'tas': 10000,
|
||||||
|
})
|
||||||
|
|
||||||
|
def _call_api_v2(self, path, video_id):
|
||||||
|
return self._call_api_impl(
|
||||||
|
'%s/in/contents/%s' % (path, video_id), video_id, {
|
||||||
|
'desiredConfig': 'encryption:plain;ladder:phone,tv;package:hls,dash',
|
||||||
|
'client': 'mweb',
|
||||||
|
'clientVersion': '6.18.0',
|
||||||
|
'deviceId': compat_str(uuid.uuid4()),
|
||||||
|
'osName': 'Windows',
|
||||||
|
'osVersion': '10',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class HotStarIE(HotStarBaseIE):
|
class HotStarIE(HotStarBaseIE):
|
||||||
IE_NAME = 'hotstar'
|
IE_NAME = 'hotstar'
|
||||||
@ -68,6 +87,10 @@ class HotStarIE(HotStarBaseIE):
|
|||||||
}, {
|
}, {
|
||||||
'url': 'http://www.hotstar.com/1000000515',
|
'url': 'http://www.hotstar.com/1000000515',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
# only available via api v2
|
||||||
|
'url': 'https://www.hotstar.com/tv/ek-bhram-sarvagun-sampanna/s-2116/janhvi-targets-suman/1000234847',
|
||||||
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
_GEO_BYPASS = False
|
_GEO_BYPASS = False
|
||||||
|
|
||||||
@ -95,26 +118,40 @@ class HotStarIE(HotStarBaseIE):
|
|||||||
raise ExtractorError('This video is DRM protected.', expected=True)
|
raise ExtractorError('This video is DRM protected.', expected=True)
|
||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
format_data = self._call_api('h/v1/play', video_id)['item']
|
geo_restricted = False
|
||||||
format_url = format_data['playbackUrl']
|
playback_sets = self._call_api_v2('h/v2/play', video_id)['playBackSets']
|
||||||
ext = determine_ext(format_url)
|
for playback_set in playback_sets:
|
||||||
if ext == 'm3u8':
|
if not isinstance(playback_set, dict):
|
||||||
|
continue
|
||||||
|
format_url = url_or_none(playback_set.get('playbackUrl'))
|
||||||
|
if not format_url:
|
||||||
|
continue
|
||||||
|
tags = str_or_none(playback_set.get('tagsCombination')) or ''
|
||||||
|
if tags and 'encryption:plain' not in tags:
|
||||||
|
continue
|
||||||
|
ext = determine_ext(format_url)
|
||||||
try:
|
try:
|
||||||
formats.extend(self._extract_m3u8_formats(
|
if 'package:hls' in tags or ext == 'm3u8':
|
||||||
format_url, video_id, 'mp4', m3u8_id='hls'))
|
formats.extend(self._extract_m3u8_formats(
|
||||||
|
format_url, video_id, 'mp4', m3u8_id='hls'))
|
||||||
|
elif 'package:dash' in tags or ext == 'mpd':
|
||||||
|
formats.extend(self._extract_mpd_formats(
|
||||||
|
format_url, video_id, mpd_id='dash'))
|
||||||
|
elif ext == 'f4m':
|
||||||
|
# produce broken files
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
formats.append({
|
||||||
|
'url': format_url,
|
||||||
|
'width': int_or_none(playback_set.get('width')),
|
||||||
|
'height': int_or_none(playback_set.get('height')),
|
||||||
|
})
|
||||||
except ExtractorError as e:
|
except ExtractorError as e:
|
||||||
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:
|
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 403:
|
||||||
self.raise_geo_restricted(countries=['IN'])
|
geo_restricted = True
|
||||||
raise
|
continue
|
||||||
elif ext == 'f4m':
|
if not formats and geo_restricted:
|
||||||
# produce broken files
|
self.raise_geo_restricted(countries=['IN'])
|
||||||
pass
|
|
||||||
else:
|
|
||||||
formats.append({
|
|
||||||
'url': format_url,
|
|
||||||
'width': int_or_none(format_data.get('width')),
|
|
||||||
'height': int_or_none(format_data.get('height')),
|
|
||||||
})
|
|
||||||
self._sort_formats(formats)
|
self._sort_formats(formats)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,7 @@ from ..utils import (
|
|||||||
|
|
||||||
|
|
||||||
class RedBullTVIE(InfoExtractor):
|
class RedBullTVIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.)?redbull(?:\.tv|\.com/(?:[^/]+/)?tv)/video/(?P<id>AP-\w+)'
|
_VALID_URL = r'https?://(?:www\.)?redbull(?:\.tv|\.com(?:/[^/]+)?(?:/tv)?)(?:/events/[^/]+)?/(?:videos?|live)/(?P<id>AP-\w+)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
# film
|
# film
|
||||||
'url': 'https://www.redbull.tv/video/AP-1Q6XCDTAN1W11',
|
'url': 'https://www.redbull.tv/video/AP-1Q6XCDTAN1W11',
|
||||||
@ -38,6 +38,12 @@ class RedBullTVIE(InfoExtractor):
|
|||||||
}, {
|
}, {
|
||||||
'url': 'https://www.redbull.com/int-en/tv/video/AP-1UWHCAR9S1W11/rob-meets-sam-gaze?playlist=playlists::3f81040a-2f31-4832-8e2e-545b1d39d173',
|
'url': 'https://www.redbull.com/int-en/tv/video/AP-1UWHCAR9S1W11/rob-meets-sam-gaze?playlist=playlists::3f81040a-2f31-4832-8e2e-545b1d39d173',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.redbull.com/us-en/videos/AP-1YM9QCYE52111',
|
||||||
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.redbull.com/us-en/events/AP-1XV2K61Q51W11/live/AP-1XUJ86FDH1W11',
|
||||||
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
|
@ -7,6 +7,7 @@ from ..utils import (
|
|||||||
ExtractorError,
|
ExtractorError,
|
||||||
int_or_none,
|
int_or_none,
|
||||||
float_or_none,
|
float_or_none,
|
||||||
|
url_or_none,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ class RedditRIE(InfoExtractor):
|
|||||||
'_type': 'url_transparent',
|
'_type': 'url_transparent',
|
||||||
'url': video_url,
|
'url': video_url,
|
||||||
'title': data.get('title'),
|
'title': data.get('title'),
|
||||||
'thumbnail': data.get('thumbnail'),
|
'thumbnail': url_or_none(data.get('thumbnail')),
|
||||||
'timestamp': float_or_none(data.get('created_utc')),
|
'timestamp': float_or_none(data.get('created_utc')),
|
||||||
'uploader': data.get('author'),
|
'uploader': data.get('author'),
|
||||||
'like_count': int_or_none(data.get('ups')),
|
'like_count': int_or_none(data.get('ups')),
|
||||||
|
@ -65,7 +65,7 @@ class SixPlayIE(InfoExtractor):
|
|||||||
for asset in assets:
|
for asset in assets:
|
||||||
asset_url = asset.get('full_physical_path')
|
asset_url = asset.get('full_physical_path')
|
||||||
protocol = asset.get('protocol')
|
protocol = asset.get('protocol')
|
||||||
if not asset_url or protocol == 'primetime' or asset.get('type') == 'usp_hlsfp_h264' or asset_url in urls:
|
if not asset_url or ((protocol == 'primetime' or asset.get('type') == 'usp_hlsfp_h264') and not ('_drmnp.ism/' in asset_url or '_unpnp.ism/' in asset_url)) or asset_url in urls:
|
||||||
continue
|
continue
|
||||||
urls.append(asset_url)
|
urls.append(asset_url)
|
||||||
container = asset.get('video_container')
|
container = asset.get('video_container')
|
||||||
@ -82,6 +82,7 @@ class SixPlayIE(InfoExtractor):
|
|||||||
if not urlh:
|
if not urlh:
|
||||||
continue
|
continue
|
||||||
asset_url = urlh.geturl()
|
asset_url = urlh.geturl()
|
||||||
|
asset_url = asset_url.replace('_drmnp.ism/', '_unpnp.ism/')
|
||||||
for i in range(3, 0, -1):
|
for i in range(3, 0, -1):
|
||||||
asset_url = asset_url = asset_url.replace('_sd1/', '_sd%d/' % i)
|
asset_url = asset_url = asset_url.replace('_sd1/', '_sd%d/' % i)
|
||||||
m3u8_formats = self._extract_m3u8_formats(
|
m3u8_formats = self._extract_m3u8_formats(
|
||||||
|
@ -10,34 +10,25 @@ from ..utils import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class SkySportsIE(InfoExtractor):
|
class SkyBaseIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.)?skysports\.com/watch/video/(?P<id>[0-9]+)'
|
|
||||||
_TEST = {
|
|
||||||
'url': 'http://www.skysports.com/watch/video/10328419/bale-its-our-time-to-shine',
|
|
||||||
'md5': '77d59166cddc8d3cb7b13e35eaf0f5ec',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '10328419',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': 'Bale: It\'s our time to shine',
|
|
||||||
'description': 'md5:e88bda94ae15f7720c5cb467e777bb6d',
|
|
||||||
},
|
|
||||||
'add_ie': ['Ooyala'],
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = extract_attributes(self._search_regex(
|
video_data = extract_attributes(self._search_regex(
|
||||||
r'(<div.+?class="sdc-article-video__media-ooyala"[^>]+>)', webpage, 'video data'))
|
r'(<div.+?class="[^"]*sdc-article-video__media-ooyala[^"]*"[^>]+>)',
|
||||||
|
webpage, 'video data'))
|
||||||
|
|
||||||
video_url = 'ooyala:%s' % video_data['data-video-id']
|
video_url = 'ooyala:%s' % video_data['data-video-id']
|
||||||
if video_data.get('data-token-required') == 'true':
|
if video_data.get('data-token-required') == 'true':
|
||||||
token_fetch_options = self._parse_json(video_data.get('data-token-fetch-options', '{}'), video_id, fatal=False) or {}
|
token_fetch_options = self._parse_json(video_data.get(
|
||||||
|
'data-token-fetch-options', '{}'), video_id, fatal=False) or {}
|
||||||
token_fetch_url = token_fetch_options.get('url')
|
token_fetch_url = token_fetch_options.get('url')
|
||||||
if token_fetch_url:
|
if token_fetch_url:
|
||||||
embed_token = self._download_webpage(urljoin(url, token_fetch_url), video_id, fatal=False)
|
embed_token = self._download_webpage(urljoin(
|
||||||
|
url, token_fetch_url), video_id, fatal=False)
|
||||||
if embed_token:
|
if embed_token:
|
||||||
video_url = smuggle_url(video_url, {'embed_token': embed_token.strip('"')})
|
video_url = smuggle_url(
|
||||||
|
video_url, {'embed_token': embed_token.strip('"')})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'_type': 'url_transparent',
|
'_type': 'url_transparent',
|
||||||
@ -47,3 +38,33 @@ class SkySportsIE(InfoExtractor):
|
|||||||
'description': strip_or_none(self._og_search_description(webpage)),
|
'description': strip_or_none(self._og_search_description(webpage)),
|
||||||
'ie_key': 'Ooyala',
|
'ie_key': 'Ooyala',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SkySportsIE(SkyBaseIE):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?skysports\.com/watch/video/(?P<id>[0-9]+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'http://www.skysports.com/watch/video/10328419/bale-its-our-time-to-shine',
|
||||||
|
'md5': '77d59166cddc8d3cb7b13e35eaf0f5ec',
|
||||||
|
'info_dict': {
|
||||||
|
'id': 'o3eWJnNDE6l7kfNO8BOoBlRxXRQ4ANNQ',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Bale: It\'s our time to shine',
|
||||||
|
'description': 'md5:e88bda94ae15f7720c5cb467e777bb6d',
|
||||||
|
},
|
||||||
|
'add_ie': ['Ooyala'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SkyNewsIE(SkyBaseIE):
|
||||||
|
_VALID_URL = r'https?://news\.sky\.com/video/[0-9a-z-]+-(?P<id>[0-9]+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'https://news.sky.com/video/russian-plane-inspected-after-deadly-fire-11712962',
|
||||||
|
'md5': 'd6327e581473cea9976a3236ded370cd',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '1ua21xaDE6lCtZDmbYfl8kwsKLooJbNM',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Russian plane inspected after deadly fire',
|
||||||
|
'description': 'The Russian Investigative Committee has released video of the wreckage of a passenger plane which caught fire near Moscow.',
|
||||||
|
},
|
||||||
|
'add_ie': ['Ooyala'],
|
||||||
|
}
|
115
youtube_dl/extractor/sverigesradio.py
Normal file
115
youtube_dl/extractor/sverigesradio.py
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..utils import (
|
||||||
|
determine_ext,
|
||||||
|
int_or_none,
|
||||||
|
str_or_none,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SverigesRadioBaseIE(InfoExtractor):
|
||||||
|
_BASE_URL = 'https://sverigesradio.se/sida/playerajax/'
|
||||||
|
_QUALITIES = ['low', 'medium', 'high']
|
||||||
|
_EXT_TO_CODEC_MAP = {
|
||||||
|
'mp3': 'mp3',
|
||||||
|
'm4a': 'aac',
|
||||||
|
}
|
||||||
|
_CODING_FORMAT_TO_ABR_MAP = {
|
||||||
|
5: 128,
|
||||||
|
11: 192,
|
||||||
|
12: 32,
|
||||||
|
13: 96,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
audio_id = self._match_id(url)
|
||||||
|
query = {
|
||||||
|
'id': audio_id,
|
||||||
|
'type': self._AUDIO_TYPE,
|
||||||
|
}
|
||||||
|
|
||||||
|
item = self._download_json(
|
||||||
|
self._BASE_URL + 'audiometadata', audio_id,
|
||||||
|
'Downloading audio JSON metadata', query=query)['items'][0]
|
||||||
|
title = item['subtitle']
|
||||||
|
|
||||||
|
query['format'] = 'iis'
|
||||||
|
urls = []
|
||||||
|
formats = []
|
||||||
|
for quality in self._QUALITIES:
|
||||||
|
query['quality'] = quality
|
||||||
|
audio_url_data = self._download_json(
|
||||||
|
self._BASE_URL + 'getaudiourl', audio_id,
|
||||||
|
'Downloading %s format JSON metadata' % quality,
|
||||||
|
fatal=False, query=query) or {}
|
||||||
|
audio_url = audio_url_data.get('audioUrl')
|
||||||
|
if not audio_url or audio_url in urls:
|
||||||
|
continue
|
||||||
|
urls.append(audio_url)
|
||||||
|
ext = determine_ext(audio_url)
|
||||||
|
coding_format = audio_url_data.get('codingFormat')
|
||||||
|
abr = int_or_none(self._search_regex(
|
||||||
|
r'_a(\d+)\.m4a', audio_url, 'audio bitrate',
|
||||||
|
default=None)) or self._CODING_FORMAT_TO_ABR_MAP.get(coding_format)
|
||||||
|
formats.append({
|
||||||
|
'abr': abr,
|
||||||
|
'acodec': self._EXT_TO_CODEC_MAP.get(ext),
|
||||||
|
'ext': ext,
|
||||||
|
'format_id': str_or_none(coding_format),
|
||||||
|
'vcodec': 'none',
|
||||||
|
'url': audio_url,
|
||||||
|
})
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': audio_id,
|
||||||
|
'title': title,
|
||||||
|
'formats': formats,
|
||||||
|
'series': item.get('title'),
|
||||||
|
'duration': int_or_none(item.get('duration')),
|
||||||
|
'thumbnail': item.get('displayimageurl'),
|
||||||
|
'description': item.get('description'),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SverigesRadioPublicationIE(SverigesRadioBaseIE):
|
||||||
|
IE_NAME = 'sverigesradio:publication'
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?sverigesradio\.se/sida/(?:artikel|gruppsida)\.aspx\?.*?\bartikel=(?P<id>[0-9]+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://sverigesradio.se/sida/artikel.aspx?programid=83&artikel=7038546',
|
||||||
|
'md5': '6a4917e1923fccb080e5a206a5afa542',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '7038546',
|
||||||
|
'ext': 'm4a',
|
||||||
|
'duration': 132,
|
||||||
|
'series': 'Nyheter (Ekot)',
|
||||||
|
'title': 'Esa Teittinen: Sanningen har inte kommit fram',
|
||||||
|
'description': 'md5:daf7ce66a8f0a53d5465a5984d3839df',
|
||||||
|
'thumbnail': r're:^https?://.*\.jpg',
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
'url': 'https://sverigesradio.se/sida/gruppsida.aspx?programid=3304&grupp=6247&artikel=7146887',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
_AUDIO_TYPE = 'publication'
|
||||||
|
|
||||||
|
|
||||||
|
class SverigesRadioEpisodeIE(SverigesRadioBaseIE):
|
||||||
|
IE_NAME = 'sverigesradio:episode'
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?sverigesradio\.se/(?:sida/)?avsnitt/(?P<id>[0-9]+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'https://sverigesradio.se/avsnitt/1140922?programid=1300',
|
||||||
|
'md5': '20dc4d8db24228f846be390b0c59a07c',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '1140922',
|
||||||
|
'ext': 'mp3',
|
||||||
|
'duration': 3307,
|
||||||
|
'series': 'Konflikt',
|
||||||
|
'title': 'Metoo och valen',
|
||||||
|
'description': 'md5:fcb5c1f667f00badcc702b196f10a27e',
|
||||||
|
'thumbnail': r're:^https?://.*\.jpg',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_AUDIO_TYPE = 'episode'
|
@ -2,19 +2,20 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
|
from ..utils import urlencode_postdata
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
class TwitCastingIE(InfoExtractor):
|
class TwitCastingIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:[^/]+\.)?twitcasting\.tv/(?P<uploader_id>[^/]+)/movie/(?P<id>\d+)'
|
_VALID_URL = r'https?://(?:[^/]+\.)?twitcasting\.tv/(?P<uploader_id>[^/]+)/movie/(?P<id>\d+)'
|
||||||
_TEST = {
|
_TESTS = [{
|
||||||
'url': 'https://twitcasting.tv/ivetesangalo/movie/2357609',
|
'url': 'https://twitcasting.tv/ivetesangalo/movie/2357609',
|
||||||
'md5': '745243cad58c4681dc752490f7540d7f',
|
'md5': '745243cad58c4681dc752490f7540d7f',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '2357609',
|
'id': '2357609',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'title': 'Recorded Live #2357609',
|
'title': 'Live #2357609',
|
||||||
'uploader_id': 'ivetesangalo',
|
'uploader_id': 'ivetesangalo',
|
||||||
'description': "Moi! I'm live on TwitCasting from my iPhone.",
|
'description': "Moi! I'm live on TwitCasting from my iPhone.",
|
||||||
'thumbnail': r're:^https?://.*\.jpg$',
|
'thumbnail': r're:^https?://.*\.jpg$',
|
||||||
@ -22,14 +23,34 @@ class TwitCastingIE(InfoExtractor):
|
|||||||
'params': {
|
'params': {
|
||||||
'skip_download': True,
|
'skip_download': True,
|
||||||
},
|
},
|
||||||
}
|
}, {
|
||||||
|
'url': 'https://twitcasting.tv/mttbernardini/movie/3689740',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '3689740',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Live playing something #3689740',
|
||||||
|
'uploader_id': 'mttbernardini',
|
||||||
|
'description': "I'm live on TwitCasting from my iPad. password: abc (Santa Marinella/Lazio, Italia)",
|
||||||
|
'thumbnail': r're:^https?://.*\.jpg$',
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
'videopassword': 'abc',
|
||||||
|
},
|
||||||
|
}]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
mobj = re.match(self._VALID_URL, url)
|
mobj = re.match(self._VALID_URL, url)
|
||||||
video_id = mobj.group('id')
|
video_id = mobj.group('id')
|
||||||
uploader_id = mobj.group('uploader_id')
|
uploader_id = mobj.group('uploader_id')
|
||||||
|
|
||||||
webpage = self._download_webpage(url, video_id)
|
video_password = self._downloader.params.get('videopassword')
|
||||||
|
request_data = None
|
||||||
|
if video_password:
|
||||||
|
request_data = urlencode_postdata({
|
||||||
|
'password': video_password,
|
||||||
|
})
|
||||||
|
webpage = self._download_webpage(url, video_id, data=request_data)
|
||||||
|
|
||||||
title = self._html_search_regex(
|
title = self._html_search_regex(
|
||||||
r'(?s)<[^>]+id=["\']movietitle[^>]+>(.+?)</',
|
r'(?s)<[^>]+id=["\']movietitle[^>]+>(.+?)</',
|
||||||
|
@ -134,12 +134,12 @@ class TwitchBaseIE(InfoExtractor):
|
|||||||
def _prefer_source(self, formats):
|
def _prefer_source(self, formats):
|
||||||
try:
|
try:
|
||||||
source = next(f for f in formats if f['format_id'] == 'Source')
|
source = next(f for f in formats if f['format_id'] == 'Source')
|
||||||
source['preference'] = 10
|
source['quality'] = 10
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
for f in formats:
|
for f in formats:
|
||||||
if '/chunked/' in f['url']:
|
if '/chunked/' in f['url']:
|
||||||
f.update({
|
f.update({
|
||||||
'source_preference': 10,
|
'quality': 10,
|
||||||
'format_note': 'Source',
|
'format_note': 'Source',
|
||||||
})
|
})
|
||||||
self._sort_formats(formats)
|
self._sort_formats(formats)
|
||||||
|
@ -1,158 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
from .common import InfoExtractor
|
|
||||||
from ..utils import (
|
|
||||||
ExtractorError,
|
|
||||||
int_or_none,
|
|
||||||
qualities,
|
|
||||||
remove_start,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class WrzutaIE(InfoExtractor):
|
|
||||||
IE_NAME = 'wrzuta.pl'
|
|
||||||
|
|
||||||
_VALID_URL = r'https?://(?P<uploader>[0-9a-zA-Z]+)\.wrzuta\.pl/(?P<typ>film|audio)/(?P<id>[0-9a-zA-Z]+)'
|
|
||||||
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'http://laboratoriumdextera.wrzuta.pl/film/aq4hIZWrkBu/nike_football_the_last_game',
|
|
||||||
'md5': '9e67e05bed7c03b82488d87233a9efe7',
|
|
||||||
'info_dict': {
|
|
||||||
'id': 'aq4hIZWrkBu',
|
|
||||||
'ext': 'mp4',
|
|
||||||
'title': 'Nike Football: The Last Game',
|
|
||||||
'duration': 307,
|
|
||||||
'uploader_id': 'laboratoriumdextera',
|
|
||||||
'description': 'md5:7fb5ef3c21c5893375fda51d9b15d9cd',
|
|
||||||
},
|
|
||||||
'skip': 'Redirected to wrzuta.pl',
|
|
||||||
}, {
|
|
||||||
'url': 'http://vexling.wrzuta.pl/audio/01xBFabGXu6/james_horner_-_into_the_na_39_vi_world_bonus',
|
|
||||||
'md5': 'f80564fb5a2ec6ec59705ae2bf2ba56d',
|
|
||||||
'info_dict': {
|
|
||||||
'id': '01xBFabGXu6',
|
|
||||||
'ext': 'mp3',
|
|
||||||
'title': 'James Horner - Into The Na\'vi World [Bonus]',
|
|
||||||
'description': 'md5:30a70718b2cd9df3120fce4445b0263b',
|
|
||||||
'duration': 95,
|
|
||||||
'uploader_id': 'vexling',
|
|
||||||
},
|
|
||||||
}]
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
mobj = re.match(self._VALID_URL, url)
|
|
||||||
video_id = mobj.group('id')
|
|
||||||
typ = mobj.group('typ')
|
|
||||||
uploader = mobj.group('uploader')
|
|
||||||
|
|
||||||
webpage, urlh = self._download_webpage_handle(url, video_id)
|
|
||||||
|
|
||||||
if urlh.geturl() == 'http://www.wrzuta.pl/':
|
|
||||||
raise ExtractorError('Video removed', expected=True)
|
|
||||||
|
|
||||||
quality = qualities(['SD', 'MQ', 'HQ', 'HD'])
|
|
||||||
|
|
||||||
audio_table = {'flv': 'mp3', 'webm': 'ogg', '???': 'mp3'}
|
|
||||||
|
|
||||||
embedpage = self._download_json('http://www.wrzuta.pl/npp/embed/%s/%s' % (uploader, video_id), video_id)
|
|
||||||
|
|
||||||
formats = []
|
|
||||||
for media in embedpage['url']:
|
|
||||||
fmt = media['type'].split('@')[0]
|
|
||||||
if typ == 'audio':
|
|
||||||
ext = audio_table.get(fmt, fmt)
|
|
||||||
else:
|
|
||||||
ext = fmt
|
|
||||||
|
|
||||||
formats.append({
|
|
||||||
'format_id': '%s_%s' % (ext, media['quality'].lower()),
|
|
||||||
'url': media['url'],
|
|
||||||
'ext': ext,
|
|
||||||
'quality': quality(media['quality']),
|
|
||||||
})
|
|
||||||
|
|
||||||
self._sort_formats(formats)
|
|
||||||
|
|
||||||
return {
|
|
||||||
'id': video_id,
|
|
||||||
'title': self._og_search_title(webpage),
|
|
||||||
'thumbnail': self._og_search_thumbnail(webpage),
|
|
||||||
'formats': formats,
|
|
||||||
'duration': int_or_none(embedpage['duration']),
|
|
||||||
'uploader_id': uploader,
|
|
||||||
'description': self._og_search_description(webpage),
|
|
||||||
'age_limit': embedpage.get('minimalAge', 0),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class WrzutaPlaylistIE(InfoExtractor):
|
|
||||||
"""
|
|
||||||
this class covers extraction of wrzuta playlist entries
|
|
||||||
the extraction process bases on following steps:
|
|
||||||
* collect information of playlist size
|
|
||||||
* download all entries provided on
|
|
||||||
the playlist webpage (the playlist is split
|
|
||||||
on two pages: first directly reached from webpage
|
|
||||||
second: downloaded on demand by ajax call and rendered
|
|
||||||
using the ajax call response)
|
|
||||||
* in case size of extracted entries not reached total number of entries
|
|
||||||
use the ajax call to collect the remaining entries
|
|
||||||
"""
|
|
||||||
|
|
||||||
IE_NAME = 'wrzuta.pl:playlist'
|
|
||||||
_VALID_URL = r'https?://(?P<uploader>[0-9a-zA-Z]+)\.wrzuta\.pl/playlista/(?P<id>[0-9a-zA-Z]+)'
|
|
||||||
_TESTS = [{
|
|
||||||
'url': 'http://miromak71.wrzuta.pl/playlista/7XfO4vE84iR/moja_muza',
|
|
||||||
'playlist_mincount': 14,
|
|
||||||
'info_dict': {
|
|
||||||
'id': '7XfO4vE84iR',
|
|
||||||
'title': 'Moja muza',
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
'url': 'http://heroesf70.wrzuta.pl/playlista/6Nj3wQHx756/lipiec_-_lato_2015_muzyka_swiata',
|
|
||||||
'playlist_mincount': 144,
|
|
||||||
'info_dict': {
|
|
||||||
'id': '6Nj3wQHx756',
|
|
||||||
'title': 'Lipiec - Lato 2015 Muzyka Świata',
|
|
||||||
},
|
|
||||||
}, {
|
|
||||||
'url': 'http://miromak71.wrzuta.pl/playlista/7XfO4vE84iR',
|
|
||||||
'only_matching': True,
|
|
||||||
}]
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
mobj = re.match(self._VALID_URL, url)
|
|
||||||
playlist_id = mobj.group('id')
|
|
||||||
uploader = mobj.group('uploader')
|
|
||||||
|
|
||||||
webpage = self._download_webpage(url, playlist_id)
|
|
||||||
|
|
||||||
playlist_size = int_or_none(self._html_search_regex(
|
|
||||||
(r'<div[^>]+class=["\']playlist-counter["\'][^>]*>\d+/(\d+)',
|
|
||||||
r'<div[^>]+class=["\']all-counter["\'][^>]*>(.+?)</div>'),
|
|
||||||
webpage, 'playlist size', default=None))
|
|
||||||
|
|
||||||
playlist_title = remove_start(
|
|
||||||
self._og_search_title(webpage), 'Playlista: ')
|
|
||||||
|
|
||||||
entries = []
|
|
||||||
if playlist_size:
|
|
||||||
entries = [
|
|
||||||
self.url_result(entry_url)
|
|
||||||
for _, entry_url in re.findall(
|
|
||||||
r'<a[^>]+href=(["\'])(http.+?)\1[^>]+class=["\']playlist-file-page',
|
|
||||||
webpage)]
|
|
||||||
if playlist_size > len(entries):
|
|
||||||
playlist_content = self._download_json(
|
|
||||||
'http://%s.wrzuta.pl/xhr/get_playlist_offset/%s' % (uploader, playlist_id),
|
|
||||||
playlist_id,
|
|
||||||
'Downloading playlist JSON',
|
|
||||||
'Unable to download playlist JSON')
|
|
||||||
entries.extend([
|
|
||||||
self.url_result(entry['filelink'])
|
|
||||||
for entry in playlist_content.get('files', []) if entry.get('filelink')])
|
|
||||||
|
|
||||||
return self.playlist_result(entries, playlist_id, playlist_title)
|
|
@ -69,25 +69,28 @@ class YandexMusicTrackIE(YandexMusicBaseIE):
|
|||||||
'skip': 'Travis CI servers blocked by YandexMusic',
|
'skip': 'Travis CI servers blocked by YandexMusic',
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_track_url(self, storage_dir, track_id):
|
def _real_extract(self, url):
|
||||||
data = self._download_json(
|
mobj = re.match(self._VALID_URL, url)
|
||||||
'http://music.yandex.ru/api/v1.5/handlers/api-jsonp.jsx?action=getTrackSrc&p=download-info/%s'
|
album_id, track_id = mobj.group('album_id'), mobj.group('id')
|
||||||
% storage_dir,
|
|
||||||
track_id, 'Downloading track location JSON')
|
|
||||||
|
|
||||||
# Each string is now wrapped in a list, this is probably only temporarily thus
|
track = self._download_json(
|
||||||
# supporting both scenarios (see https://github.com/ytdl-org/youtube-dl/issues/10193)
|
'http://music.yandex.ru/handlers/track.jsx?track=%s:%s' % (track_id, album_id),
|
||||||
for k, v in data.items():
|
track_id, 'Downloading track JSON')['track']
|
||||||
if v and isinstance(v, list):
|
track_title = track['title']
|
||||||
data[k] = v[0]
|
|
||||||
|
|
||||||
key = hashlib.md5(('XGRlBW9FXlekgbPrRHuSiA' + data['path'][1:] + data['s']).encode('utf-8')).hexdigest()
|
download_data = self._download_json(
|
||||||
storage = storage_dir.split('.')
|
'https://music.yandex.ru/api/v2.1/handlers/track/%s:%s/web-album_track-track-track-main/download/m' % (track_id, album_id),
|
||||||
|
track_id, 'Downloading track location url JSON',
|
||||||
|
headers={'X-Retpath-Y': url})
|
||||||
|
|
||||||
return ('http://%s/get-mp3/%s/%s?track-id=%s&from=service-10-track&similarities-experiment=default'
|
fd_data = self._download_json(
|
||||||
% (data['host'], key, data['ts'] + data['path'], storage[1]))
|
download_data['src'], track_id,
|
||||||
|
'Downloading track location JSON',
|
||||||
|
query={'format': 'json'})
|
||||||
|
key = hashlib.md5(('XGRlBW9FXlekgbPrRHuSiA' + fd_data['path'][1:] + fd_data['s']).encode('utf-8')).hexdigest()
|
||||||
|
storage = track['storageDir'].split('.')
|
||||||
|
f_url = 'http://%s/get-mp3/%s/%s?track-id=%s ' % (fd_data['host'], key, fd_data['ts'] + fd_data['path'], storage[1])
|
||||||
|
|
||||||
def _get_track_info(self, track):
|
|
||||||
thumbnail = None
|
thumbnail = None
|
||||||
cover_uri = track.get('albums', [{}])[0].get('coverUri')
|
cover_uri = track.get('albums', [{}])[0].get('coverUri')
|
||||||
if cover_uri:
|
if cover_uri:
|
||||||
@ -95,15 +98,16 @@ class YandexMusicTrackIE(YandexMusicBaseIE):
|
|||||||
if not thumbnail.startswith('http'):
|
if not thumbnail.startswith('http'):
|
||||||
thumbnail = 'http://' + thumbnail
|
thumbnail = 'http://' + thumbnail
|
||||||
|
|
||||||
track_title = track['title']
|
|
||||||
track_info = {
|
track_info = {
|
||||||
'id': track['id'],
|
'id': track_id,
|
||||||
'ext': 'mp3',
|
'ext': 'mp3',
|
||||||
'url': self._get_track_url(track['storageDir'], track['id']),
|
'url': f_url,
|
||||||
'filesize': int_or_none(track.get('fileSize')),
|
'filesize': int_or_none(track.get('fileSize')),
|
||||||
'duration': float_or_none(track.get('durationMs'), 1000),
|
'duration': float_or_none(track.get('durationMs'), 1000),
|
||||||
'thumbnail': thumbnail,
|
'thumbnail': thumbnail,
|
||||||
'track': track_title,
|
'track': track_title,
|
||||||
|
'acodec': download_data.get('codec'),
|
||||||
|
'abr': int_or_none(download_data.get('bitrate')),
|
||||||
}
|
}
|
||||||
|
|
||||||
def extract_artist(artist_list):
|
def extract_artist(artist_list):
|
||||||
@ -131,18 +135,9 @@ class YandexMusicTrackIE(YandexMusicBaseIE):
|
|||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
track_info['title'] = track_title
|
track_info['title'] = track_title
|
||||||
|
|
||||||
return track_info
|
return track_info
|
||||||
|
|
||||||
def _real_extract(self, url):
|
|
||||||
mobj = re.match(self._VALID_URL, url)
|
|
||||||
album_id, track_id = mobj.group('album_id'), mobj.group('id')
|
|
||||||
|
|
||||||
track = self._download_json(
|
|
||||||
'http://music.yandex.ru/handlers/track.jsx?track=%s:%s' % (track_id, album_id),
|
|
||||||
track_id, 'Downloading track JSON')['track']
|
|
||||||
|
|
||||||
return self._get_track_info(track)
|
|
||||||
|
|
||||||
|
|
||||||
class YandexMusicPlaylistBaseIE(YandexMusicBaseIE):
|
class YandexMusicPlaylistBaseIE(YandexMusicBaseIE):
|
||||||
def _build_playlist(self, tracks):
|
def _build_playlist(self, tracks):
|
||||||
|
@ -16,6 +16,7 @@ from ..jsinterp import JSInterpreter
|
|||||||
from ..swfinterp import SWFInterpreter
|
from ..swfinterp import SWFInterpreter
|
||||||
from ..compat import (
|
from ..compat import (
|
||||||
compat_chr,
|
compat_chr,
|
||||||
|
compat_HTTPError,
|
||||||
compat_kwargs,
|
compat_kwargs,
|
||||||
compat_parse_qs,
|
compat_parse_qs,
|
||||||
compat_urllib_parse_unquote,
|
compat_urllib_parse_unquote,
|
||||||
@ -27,6 +28,7 @@ from ..compat import (
|
|||||||
)
|
)
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
clean_html,
|
clean_html,
|
||||||
|
dict_get,
|
||||||
error_to_compat_str,
|
error_to_compat_str,
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
float_or_none,
|
float_or_none,
|
||||||
@ -287,10 +289,25 @@ class YoutubeEntryListBaseInfoExtractor(YoutubeBaseInfoExtractor):
|
|||||||
if not mobj:
|
if not mobj:
|
||||||
break
|
break
|
||||||
|
|
||||||
more = self._download_json(
|
count = 0
|
||||||
'https://youtube.com/%s' % mobj.group('more'), playlist_id,
|
retries = 3
|
||||||
'Downloading page #%s' % page_num,
|
while count <= retries:
|
||||||
transform_source=uppercase_escape)
|
try:
|
||||||
|
# Downloading page may result in intermittent 5xx HTTP error
|
||||||
|
# that is usually worked around with a retry
|
||||||
|
more = self._download_json(
|
||||||
|
'https://youtube.com/%s' % mobj.group('more'), playlist_id,
|
||||||
|
'Downloading page #%s%s'
|
||||||
|
% (page_num, ' (retry #%d)' % count if count else ''),
|
||||||
|
transform_source=uppercase_escape)
|
||||||
|
break
|
||||||
|
except ExtractorError as e:
|
||||||
|
if isinstance(e.cause, compat_HTTPError) and e.cause.code in (500, 503):
|
||||||
|
count += 1
|
||||||
|
if count <= retries:
|
||||||
|
continue
|
||||||
|
raise
|
||||||
|
|
||||||
content_html = more['content_html']
|
content_html = more['content_html']
|
||||||
if not content_html.strip():
|
if not content_html.strip():
|
||||||
# Some webpages show a "Load more" button but they don't
|
# Some webpages show a "Load more" button but they don't
|
||||||
@ -908,6 +925,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
'creator': 'Todd Haberman, Daniel Law Heath and Aaron Kaplan',
|
'creator': 'Todd Haberman, Daniel Law Heath and Aaron Kaplan',
|
||||||
'track': 'Dark Walk - Position Music',
|
'track': 'Dark Walk - Position Music',
|
||||||
'artist': 'Todd Haberman, Daniel Law Heath and Aaron Kaplan',
|
'artist': 'Todd Haberman, Daniel Law Heath and Aaron Kaplan',
|
||||||
|
'album': 'Position Music - Production Music Vol. 143 - Dark Walk',
|
||||||
},
|
},
|
||||||
'params': {
|
'params': {
|
||||||
'skip_download': True,
|
'skip_download': True,
|
||||||
@ -1086,7 +1104,95 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
'skip_download': True,
|
'skip_download': True,
|
||||||
'youtube_include_dash_manifest': False,
|
'youtube_include_dash_manifest': False,
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
# Youtube Music Auto-generated description
|
||||||
|
'url': 'https://music.youtube.com/watch?v=MgNrAu2pzNs',
|
||||||
|
'info_dict': {
|
||||||
|
'id': 'MgNrAu2pzNs',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Voyeur Girl',
|
||||||
|
'description': 'md5:7ae382a65843d6df2685993e90a8628f',
|
||||||
|
'upload_date': '20190312',
|
||||||
|
'uploader': 'Various Artists - Topic',
|
||||||
|
'uploader_id': 'UCVWKBi1ELZn0QX2CBLSkiyw',
|
||||||
|
'artist': 'Stephen',
|
||||||
|
'track': 'Voyeur Girl',
|
||||||
|
'album': 'it\'s too much love to know my dear',
|
||||||
|
'release_date': '20190313',
|
||||||
|
'release_year': 2019,
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Youtube Music Auto-generated description
|
||||||
|
# Retrieve 'artist' field from 'Artist:' in video description
|
||||||
|
# when it is present on youtube music video
|
||||||
|
'url': 'https://www.youtube.com/watch?v=k0jLE7tTwjY',
|
||||||
|
'info_dict': {
|
||||||
|
'id': 'k0jLE7tTwjY',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Latch Feat. Sam Smith',
|
||||||
|
'description': 'md5:3cb1e8101a7c85fcba9b4fb41b951335',
|
||||||
|
'upload_date': '20150110',
|
||||||
|
'uploader': 'Various Artists - Topic',
|
||||||
|
'uploader_id': 'UCNkEcmYdjrH4RqtNgh7BZ9w',
|
||||||
|
'artist': 'Disclosure',
|
||||||
|
'track': 'Latch Feat. Sam Smith',
|
||||||
|
'album': 'Latch Featuring Sam Smith',
|
||||||
|
'release_date': '20121008',
|
||||||
|
'release_year': 2012,
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Youtube Music Auto-generated description
|
||||||
|
# handle multiple artists on youtube music video
|
||||||
|
'url': 'https://www.youtube.com/watch?v=74qn0eJSjpA',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '74qn0eJSjpA',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Eastside',
|
||||||
|
'description': 'md5:290516bb73dcbfab0dcc4efe6c3de5f2',
|
||||||
|
'upload_date': '20180710',
|
||||||
|
'uploader': 'Benny Blanco - Topic',
|
||||||
|
'uploader_id': 'UCzqz_ksRu_WkIzmivMdIS7A',
|
||||||
|
'artist': 'benny blanco, Halsey, Khalid',
|
||||||
|
'track': 'Eastside',
|
||||||
|
'album': 'Eastside',
|
||||||
|
'release_date': '20180713',
|
||||||
|
'release_year': 2018,
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# Youtube Music Auto-generated description
|
||||||
|
# handle youtube music video with release_year and no release_date
|
||||||
|
'url': 'https://www.youtube.com/watch?v=-hcAI0g-f5M',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '-hcAI0g-f5M',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Put It On Me',
|
||||||
|
'description': 'md5:93c55acc682ae7b0c668f2e34e1c069e',
|
||||||
|
'upload_date': '20180426',
|
||||||
|
'uploader': 'Matt Maeson - Topic',
|
||||||
|
'uploader_id': 'UCnEkIGqtGcQMLk73Kp-Q5LQ',
|
||||||
|
'artist': 'Matt Maeson',
|
||||||
|
'track': 'Put It On Me',
|
||||||
|
'album': 'The Hearse',
|
||||||
|
'release_date': None,
|
||||||
|
'release_year': 2018,
|
||||||
|
},
|
||||||
|
'params': {
|
||||||
|
'skip_download': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
@ -1563,6 +1669,9 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
def extract_view_count(v_info):
|
def extract_view_count(v_info):
|
||||||
return int_or_none(try_get(v_info, lambda x: x['view_count'][0]))
|
return int_or_none(try_get(v_info, lambda x: x['view_count'][0]))
|
||||||
|
|
||||||
|
def extract_token(v_info):
|
||||||
|
return dict_get(v_info, ('account_playback_token', 'accountPlaybackToken', 'token'))
|
||||||
|
|
||||||
player_response = {}
|
player_response = {}
|
||||||
|
|
||||||
# Get video info
|
# Get video info
|
||||||
@ -1622,7 +1731,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
# The general idea is to take a union of itags of both DASH manifests (for example
|
# The general idea is to take a union of itags of both DASH manifests (for example
|
||||||
# video with such 'manifest behavior' see https://github.com/ytdl-org/youtube-dl/issues/6093)
|
# video with such 'manifest behavior' see https://github.com/ytdl-org/youtube-dl/issues/6093)
|
||||||
self.report_video_info_webpage_download(video_id)
|
self.report_video_info_webpage_download(video_id)
|
||||||
for el in ('info', 'embedded', 'detailpage', 'vevo', ''):
|
for el in ('embedded', 'detailpage', 'vevo', ''):
|
||||||
query = {
|
query = {
|
||||||
'video_id': video_id,
|
'video_id': video_id,
|
||||||
'ps': 'default',
|
'ps': 'default',
|
||||||
@ -1652,7 +1761,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
view_count = extract_view_count(get_video_info)
|
view_count = extract_view_count(get_video_info)
|
||||||
if not video_info:
|
if not video_info:
|
||||||
video_info = get_video_info
|
video_info = get_video_info
|
||||||
get_token = get_video_info.get('token') or get_video_info.get('account_playback_token')
|
get_token = extract_token(get_video_info)
|
||||||
if get_token:
|
if get_token:
|
||||||
# Different get_video_info requests may report different results, e.g.
|
# Different get_video_info requests may report different results, e.g.
|
||||||
# some may report video unavailability, but some may serve it without
|
# some may report video unavailability, but some may serve it without
|
||||||
@ -1663,7 +1772,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
# due to YouTube measures against IP ranges of hosting providers.
|
# due to YouTube measures against IP ranges of hosting providers.
|
||||||
# Working around by preferring the first succeeded video_info containing
|
# Working around by preferring the first succeeded video_info containing
|
||||||
# the token if no such video_info yet was found.
|
# the token if no such video_info yet was found.
|
||||||
token = video_info.get('token') or video_info.get('account_playback_token')
|
token = extract_token(video_info)
|
||||||
if not token:
|
if not token:
|
||||||
video_info = get_video_info
|
video_info = get_video_info
|
||||||
break
|
break
|
||||||
@ -1680,28 +1789,6 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
raise ExtractorError(
|
raise ExtractorError(
|
||||||
'YouTube said: %s' % unavailable_message, expected=True, video_id=video_id)
|
'YouTube said: %s' % unavailable_message, expected=True, video_id=video_id)
|
||||||
|
|
||||||
token = video_info.get('token') or video_info.get('account_playback_token')
|
|
||||||
if not token:
|
|
||||||
if 'reason' in video_info:
|
|
||||||
if 'The uploader has not made this video available in your country.' in video_info['reason']:
|
|
||||||
regions_allowed = self._html_search_meta(
|
|
||||||
'regionsAllowed', video_webpage, default=None)
|
|
||||||
countries = regions_allowed.split(',') if regions_allowed else None
|
|
||||||
self.raise_geo_restricted(
|
|
||||||
msg=video_info['reason'][0], countries=countries)
|
|
||||||
reason = video_info['reason'][0]
|
|
||||||
if 'Invalid parameters' in reason:
|
|
||||||
unavailable_message = extract_unavailable_message()
|
|
||||||
if unavailable_message:
|
|
||||||
reason = unavailable_message
|
|
||||||
raise ExtractorError(
|
|
||||||
'YouTube said: %s' % reason,
|
|
||||||
expected=True, video_id=video_id)
|
|
||||||
else:
|
|
||||||
raise ExtractorError(
|
|
||||||
'"token" parameter not in video info for unknown reason',
|
|
||||||
video_id=video_id)
|
|
||||||
|
|
||||||
if video_info.get('license_info'):
|
if video_info.get('license_info'):
|
||||||
raise ExtractorError('This video is DRM protected.', expected=True)
|
raise ExtractorError('This video is DRM protected.', expected=True)
|
||||||
|
|
||||||
@ -2073,6 +2160,27 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
|
|
||||||
track = extract_meta('Song')
|
track = extract_meta('Song')
|
||||||
artist = extract_meta('Artist')
|
artist = extract_meta('Artist')
|
||||||
|
album = extract_meta('Album')
|
||||||
|
|
||||||
|
# Youtube Music Auto-generated description
|
||||||
|
release_date = release_year = None
|
||||||
|
if video_description:
|
||||||
|
mobj = re.search(r'(?s)Provided to YouTube by [^\n]+\n+(?P<track>[^·]+)·(?P<artist>[^\n]+)\n+(?P<album>[^\n]+)(?:.+?℗\s*(?P<release_year>\d{4})(?!\d))?(?:.+?Released on\s*:\s*(?P<release_date>\d{4}-\d{2}-\d{2}))?(.+?\nArtist\s*:\s*(?P<clean_artist>[^\n]+))?', video_description)
|
||||||
|
if mobj:
|
||||||
|
if not track:
|
||||||
|
track = mobj.group('track').strip()
|
||||||
|
if not artist:
|
||||||
|
artist = mobj.group('clean_artist') or ', '.join(a.strip() for a in mobj.group('artist').split('·'))
|
||||||
|
if not album:
|
||||||
|
album = mobj.group('album'.strip())
|
||||||
|
release_year = mobj.group('release_year')
|
||||||
|
release_date = mobj.group('release_date')
|
||||||
|
if release_date:
|
||||||
|
release_date = release_date.replace('-', '')
|
||||||
|
if not release_year:
|
||||||
|
release_year = int(release_date[:4])
|
||||||
|
if release_year:
|
||||||
|
release_year = int(release_year)
|
||||||
|
|
||||||
m_episode = re.search(
|
m_episode = re.search(
|
||||||
r'<div[^>]+id="watch7-headline"[^>]*>\s*<span[^>]*>.*?>(?P<series>[^<]+)</a></b>\s*S(?P<season>\d+)\s*•\s*E(?P<episode>\d+)</span>',
|
r'<div[^>]+id="watch7-headline"[^>]*>\s*<span[^>]*>.*?>(?P<series>[^<]+)</a></b>\s*S(?P<season>\d+)\s*•\s*E(?P<episode>\d+)</span>',
|
||||||
@ -2186,6 +2294,29 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
if f.get('vcodec') != 'none':
|
if f.get('vcodec') != 'none':
|
||||||
f['stretched_ratio'] = ratio
|
f['stretched_ratio'] = ratio
|
||||||
|
|
||||||
|
if not formats:
|
||||||
|
token = extract_token(video_info)
|
||||||
|
if not token:
|
||||||
|
if 'reason' in video_info:
|
||||||
|
if 'The uploader has not made this video available in your country.' in video_info['reason']:
|
||||||
|
regions_allowed = self._html_search_meta(
|
||||||
|
'regionsAllowed', video_webpage, default=None)
|
||||||
|
countries = regions_allowed.split(',') if regions_allowed else None
|
||||||
|
self.raise_geo_restricted(
|
||||||
|
msg=video_info['reason'][0], countries=countries)
|
||||||
|
reason = video_info['reason'][0]
|
||||||
|
if 'Invalid parameters' in reason:
|
||||||
|
unavailable_message = extract_unavailable_message()
|
||||||
|
if unavailable_message:
|
||||||
|
reason = unavailable_message
|
||||||
|
raise ExtractorError(
|
||||||
|
'YouTube said: %s' % reason,
|
||||||
|
expected=True, video_id=video_id)
|
||||||
|
else:
|
||||||
|
raise ExtractorError(
|
||||||
|
'"token" parameter not in video info for unknown reason',
|
||||||
|
video_id=video_id)
|
||||||
|
|
||||||
self._sort_formats(formats)
|
self._sort_formats(formats)
|
||||||
|
|
||||||
self.mark_watched(video_id, video_info, player_response)
|
self.mark_watched(video_id, video_info, player_response)
|
||||||
@ -2226,6 +2357,9 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
|
|||||||
'episode_number': episode_number,
|
'episode_number': episode_number,
|
||||||
'track': track,
|
'track': track,
|
||||||
'artist': artist,
|
'artist': artist,
|
||||||
|
'album': album,
|
||||||
|
'release_date': release_date,
|
||||||
|
'release_year': release_year,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
__version__ = '2019.04.24'
|
__version__ = '2019.04.30'
|
||||||
|
Loading…
Reference in New Issue
Block a user