mirror of
https://codeberg.org/polarisfm/youtube-dl
synced 2025-01-09 14:47:55 +01:00
Merge branch 'master' of https://github.com/rg3/youtube-dl
This commit is contained in:
commit
b3b8237cfd
6
.github/ISSUE_TEMPLATE.md
vendored
6
.github/ISSUE_TEMPLATE.md
vendored
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2017.11.06*. If it's not, read [this FAQ entry](https://github.com/rg3/youtube-dl/blob/master/README.md#how-do-i-update-youtube-dl) and update. Issues with outdated version will be rejected.
|
### Make sure you are using the *latest* version: run `youtube-dl --version` and ensure your version is *2017.11.15*. If it's not, read [this FAQ entry](https://github.com/rg3/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 **2017.11.06**
|
- [ ] I've **verified** and **I assure** that I'm running youtube-dl **2017.11.15**
|
||||||
|
|
||||||
### Before submitting an *issue* make sure you have:
|
### Before submitting an *issue* make sure you have:
|
||||||
- [ ] At least skimmed through the [README](https://github.com/rg3/youtube-dl/blob/master/README.md), **most notably** the [FAQ](https://github.com/rg3/youtube-dl#faq) and [BUGS](https://github.com/rg3/youtube-dl#bugs) sections
|
- [ ] At least skimmed through the [README](https://github.com/rg3/youtube-dl/blob/master/README.md), **most notably** the [FAQ](https://github.com/rg3/youtube-dl#faq) and [BUGS](https://github.com/rg3/youtube-dl#bugs) sections
|
||||||
@ -35,7 +35,7 @@ Add the `-v` flag to **your command line** you run youtube-dl with (`youtube-dl
|
|||||||
[debug] User config: []
|
[debug] User config: []
|
||||||
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
[debug] Command-line args: [u'-v', u'http://www.youtube.com/watch?v=BaW_jenozKcj']
|
||||||
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
[debug] Encodings: locale cp1251, fs mbcs, out cp866, pref cp1251
|
||||||
[debug] youtube-dl version 2017.11.06
|
[debug] youtube-dl version 2017.11.15
|
||||||
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
[debug] Python version 2.7.11 - Windows-2003Server-5.2.3790-SP2
|
||||||
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
[debug] exe versions: ffmpeg N-75573-g1d0487f, ffprobe N-75573-g1d0487f, rtmpdump 2.4
|
||||||
[debug] Proxy map: {}
|
[debug] Proxy map: {}
|
||||||
|
20
ChangeLog
20
ChangeLog
@ -1,7 +1,25 @@
|
|||||||
version <unreleased>
|
version 2017.11.15
|
||||||
|
|
||||||
|
Core
|
||||||
|
* [common] Skip Apple FairPlay m3u8 manifests (#14741)
|
||||||
|
* [YoutubeDL] Fix playlist range optimization for --playlist-items (#14740)
|
||||||
|
|
||||||
Extractors
|
Extractors
|
||||||
|
* [vshare] Capture and output error message
|
||||||
|
* [vshare] Fix extraction (#14473)
|
||||||
|
* [crunchyroll] Extract old RTMP formats
|
||||||
|
* [tva] Fix extraction (#14736)
|
||||||
|
* [gamespot] Lower preference of HTTP formats (#14652)
|
||||||
|
* [instagram:user] Fix extraction (#14699)
|
||||||
|
* [ccma] Fix typo (#14730)
|
||||||
|
- Remove sensitive data from logging in messages
|
||||||
|
* [instagram:user] Fix extraction (#14699)
|
||||||
|
+ [gamespot] Add support for article URLs (#14652)
|
||||||
|
* [gamespot] Skip Brightcove Once HTTP formats (#14652)
|
||||||
|
* [cartoonnetwork] Update tokenizer_src (#14666)
|
||||||
+ [wsj] Recognize another URL pattern (#14704)
|
+ [wsj] Recognize another URL pattern (#14704)
|
||||||
|
* [pandatv] Update API URL and sign format URLs (#14693)
|
||||||
|
* [crunchyroll] Use old login method (#11572)
|
||||||
|
|
||||||
|
|
||||||
version 2017.11.06
|
version 2017.11.06
|
||||||
|
@ -592,19 +592,11 @@ class InfoExtractor(object):
|
|||||||
if not encoding:
|
if not encoding:
|
||||||
encoding = self._guess_encoding_from_content(content_type, webpage_bytes)
|
encoding = self._guess_encoding_from_content(content_type, webpage_bytes)
|
||||||
if self._downloader.params.get('dump_intermediate_pages', False):
|
if self._downloader.params.get('dump_intermediate_pages', False):
|
||||||
try:
|
self.to_screen('Dumping request to ' + urlh.geturl())
|
||||||
url = url_or_request.get_full_url()
|
|
||||||
except AttributeError:
|
|
||||||
url = url_or_request
|
|
||||||
self.to_screen('Dumping request to ' + url)
|
|
||||||
dump = base64.b64encode(webpage_bytes).decode('ascii')
|
dump = base64.b64encode(webpage_bytes).decode('ascii')
|
||||||
self._downloader.to_screen(dump)
|
self._downloader.to_screen(dump)
|
||||||
if self._downloader.params.get('write_pages', False):
|
if self._downloader.params.get('write_pages', False):
|
||||||
try:
|
basen = '%s_%s' % (video_id, urlh.geturl())
|
||||||
url = url_or_request.get_full_url()
|
|
||||||
except AttributeError:
|
|
||||||
url = url_or_request
|
|
||||||
basen = '%s_%s' % (video_id, url)
|
|
||||||
if len(basen) > 240:
|
if len(basen) > 240:
|
||||||
h = '___' + hashlib.md5(basen.encode('utf-8')).hexdigest()
|
h = '___' + hashlib.md5(basen.encode('utf-8')).hexdigest()
|
||||||
basen = basen[:240 - len(h)] + h
|
basen = basen[:240 - len(h)] + h
|
||||||
@ -1356,6 +1348,9 @@ class InfoExtractor(object):
|
|||||||
if '#EXT-X-FAXS-CM:' in m3u8_doc: # Adobe Flash Access
|
if '#EXT-X-FAXS-CM:' in m3u8_doc: # Adobe Flash Access
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
if re.search(r'#EXT-X-SESSION-KEY:.*?URI="skd://', m3u8_doc): # Apple FairPlay
|
||||||
|
return []
|
||||||
|
|
||||||
formats = []
|
formats = []
|
||||||
|
|
||||||
format_url = lambda u: (
|
format_url = lambda u: (
|
||||||
|
@ -10,7 +10,7 @@ from ..utils import (
|
|||||||
|
|
||||||
|
|
||||||
class DrTuberIE(InfoExtractor):
|
class DrTuberIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.)?drtuber\.com/(?:video|embed)/(?P<id>\d+)(?:/(?P<display_id>[\w-]+))?'
|
_VALID_URL = r'https?://(?:(?:www|m)\.)?drtuber\.com/(?:video|embed)/(?P<id>\d+)(?:/(?P<display_id>[\w-]+))?'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'http://www.drtuber.com/video/1740434/hot-perky-blonde-naked-golf',
|
'url': 'http://www.drtuber.com/video/1740434/hot-perky-blonde-naked-golf',
|
||||||
'md5': '93e680cf2536ad0dfb7e74d94a89facd',
|
'md5': '93e680cf2536ad0dfb7e74d94a89facd',
|
||||||
@ -28,6 +28,9 @@ class DrTuberIE(InfoExtractor):
|
|||||||
}, {
|
}, {
|
||||||
'url': 'http://www.drtuber.com/embed/489939',
|
'url': 'http://www.drtuber.com/embed/489939',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
'url': 'http://m.drtuber.com/video/3893529/lingerie-blowjob-from-beautiful-teen',
|
||||||
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -102,6 +102,7 @@ from .joj import JojIE
|
|||||||
from .megaphone import MegaphoneIE
|
from .megaphone import MegaphoneIE
|
||||||
from .vzaar import VzaarIE
|
from .vzaar import VzaarIE
|
||||||
from .channel9 import Channel9IE
|
from .channel9 import Channel9IE
|
||||||
|
from .vshare import VShareIE
|
||||||
|
|
||||||
|
|
||||||
class GenericIE(InfoExtractor):
|
class GenericIE(InfoExtractor):
|
||||||
@ -1921,6 +1922,16 @@ class GenericIE(InfoExtractor):
|
|||||||
'title': 'Rescue Kit 14 Free Edition - Getting started',
|
'title': 'Rescue Kit 14 Free Edition - Getting started',
|
||||||
},
|
},
|
||||||
'playlist_count': 4,
|
'playlist_count': 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
# vshare embed
|
||||||
|
'url': 'https://youtube-dl-demo.neocities.org/vshare.html',
|
||||||
|
'md5': '17b39f55b5497ae8b59f5fbce8e35886',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '0f64ce6',
|
||||||
|
'title': 'vl14062007715967',
|
||||||
|
'ext': 'mp4',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# {
|
# {
|
||||||
# # TODO: find another test
|
# # TODO: find another test
|
||||||
@ -2879,6 +2890,11 @@ class GenericIE(InfoExtractor):
|
|||||||
return self.playlist_from_matches(
|
return self.playlist_from_matches(
|
||||||
channel9_urls, video_id, video_title, ie=Channel9IE.ie_key())
|
channel9_urls, video_id, video_title, ie=Channel9IE.ie_key())
|
||||||
|
|
||||||
|
vshare_urls = VShareIE._extract_urls(webpage)
|
||||||
|
if vshare_urls:
|
||||||
|
return self.playlist_from_matches(
|
||||||
|
vshare_urls, video_id, video_title, ie=VShareIE.ie_key())
|
||||||
|
|
||||||
def merge_dicts(dict1, dict2):
|
def merge_dicts(dict1, dict2):
|
||||||
merged = {}
|
merged = {}
|
||||||
for k, v in dict1.items():
|
for k, v in dict1.items():
|
||||||
|
@ -130,13 +130,21 @@ class InstagramIE(InfoExtractor):
|
|||||||
video_url = media.get('video_url')
|
video_url = media.get('video_url')
|
||||||
height = int_or_none(media.get('dimensions', {}).get('height'))
|
height = int_or_none(media.get('dimensions', {}).get('height'))
|
||||||
width = int_or_none(media.get('dimensions', {}).get('width'))
|
width = int_or_none(media.get('dimensions', {}).get('width'))
|
||||||
description = media.get('caption')
|
description = try_get(
|
||||||
|
media, lambda x: x['edge_media_to_caption']['edges'][0]['node']['text'],
|
||||||
|
compat_str) or media.get('caption')
|
||||||
thumbnail = media.get('display_src')
|
thumbnail = media.get('display_src')
|
||||||
timestamp = int_or_none(media.get('date'))
|
timestamp = int_or_none(media.get('taken_at_timestamp') or media.get('date'))
|
||||||
uploader = media.get('owner', {}).get('full_name')
|
uploader = media.get('owner', {}).get('full_name')
|
||||||
uploader_id = media.get('owner', {}).get('username')
|
uploader_id = media.get('owner', {}).get('username')
|
||||||
like_count = int_or_none(media.get('likes', {}).get('count'))
|
|
||||||
comment_count = int_or_none(media.get('comments', {}).get('count'))
|
def get_count(key, kind):
|
||||||
|
return int_or_none(try_get(
|
||||||
|
media, (lambda x: x['edge_media_%s' % key]['count'],
|
||||||
|
lambda x: x['%ss' % kind]['count'])))
|
||||||
|
like_count = get_count('preview_like', 'like')
|
||||||
|
comment_count = get_count('to_comment', 'comment')
|
||||||
|
|
||||||
comments = [{
|
comments = [{
|
||||||
'author': comment.get('user', {}).get('username'),
|
'author': comment.get('user', {}).get('username'),
|
||||||
'author_id': comment.get('user', {}).get('id'),
|
'author_id': comment.get('user', {}).get('id'),
|
||||||
|
@ -7,7 +7,7 @@ from ..utils import ExtractorError
|
|||||||
|
|
||||||
|
|
||||||
class SpankBangIE(InfoExtractor):
|
class SpankBangIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:(?:www|[a-z]{2})\.)?spankbang\.com/(?P<id>[\da-z]+)/video'
|
_VALID_URL = r'https?://(?:(?:www|m|[a-z]{2})\.)?spankbang\.com/(?P<id>[\da-z]+)/video'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'http://spankbang.com/3vvn/video/fantasy+solo',
|
'url': 'http://spankbang.com/3vvn/video/fantasy+solo',
|
||||||
'md5': '1cc433e1d6aa14bc376535b8679302f7',
|
'md5': '1cc433e1d6aa14bc376535b8679302f7',
|
||||||
@ -15,7 +15,7 @@ class SpankBangIE(InfoExtractor):
|
|||||||
'id': '3vvn',
|
'id': '3vvn',
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'title': 'fantasy solo',
|
'title': 'fantasy solo',
|
||||||
'description': 'Watch fantasy solo free HD porn video - 05 minutes - dillion harper masturbates on a bed free adult movies.',
|
'description': 'Watch fantasy solo free HD porn video - 05 minutes - Babe,Masturbation,Solo,Toy - dillion harper masturbates on a bed free adult movies sexy clips.',
|
||||||
'thumbnail': r're:^https?://.*\.jpg$',
|
'thumbnail': r're:^https?://.*\.jpg$',
|
||||||
'uploader': 'silly2587',
|
'uploader': 'silly2587',
|
||||||
'age_limit': 18,
|
'age_limit': 18,
|
||||||
@ -28,6 +28,10 @@ class SpankBangIE(InfoExtractor):
|
|||||||
# no uploader
|
# no uploader
|
||||||
'url': 'http://spankbang.com/lklg/video/sex+with+anyone+wedding+edition+2',
|
'url': 'http://spankbang.com/lklg/video/sex+with+anyone+wedding+edition+2',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
|
}, {
|
||||||
|
# mobile page
|
||||||
|
'url': 'http://m.spankbang.com/1o2de/video/can+t+remember+her+name',
|
||||||
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
|
from ..compat import compat_chr
|
||||||
|
from ..utils import (
|
||||||
|
decode_packed_codes,
|
||||||
|
ExtractorError,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class VShareIE(InfoExtractor):
|
class VShareIE(InfoExtractor):
|
||||||
_VALID_URL = r'https?://(?:www\.)?vshare\.io/[dv]/(?P<id>[^/?#&]+)'
|
_VALID_URL = r'https?://(?:www\.)?vshare\.io/[dv]/(?P<id>[^/?#&]+)'
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://vshare.io/d/0f64ce6',
|
'url': 'https://vshare.io/d/0f64ce6',
|
||||||
'md5': '16d7b8fef58846db47419199ff1ab3e7',
|
'md5': '17b39f55b5497ae8b59f5fbce8e35886',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
'id': '0f64ce6',
|
'id': '0f64ce6',
|
||||||
'title': 'vl14062007715967',
|
'title': 'vl14062007715967',
|
||||||
@ -19,20 +26,49 @@ class VShareIE(InfoExtractor):
|
|||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
}]
|
}]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _extract_urls(webpage):
|
||||||
|
return re.findall(
|
||||||
|
r'<iframe[^>]+?src=["\'](?P<url>(?:https?:)?//(?:www\.)?vshare\.io/v/[^/?#&]+)',
|
||||||
|
webpage)
|
||||||
|
|
||||||
|
def _extract_packed(self, webpage):
|
||||||
|
packed = self._search_regex(
|
||||||
|
r'(eval\(function.+)', webpage, 'packed code')
|
||||||
|
unpacked = decode_packed_codes(packed)
|
||||||
|
digits = self._search_regex(r'\[((?:\d+,?)+)\]', unpacked, 'digits')
|
||||||
|
digits = [int(digit) for digit in digits.split(',')]
|
||||||
|
key_digit = self._search_regex(
|
||||||
|
r'fromCharCode\(.+?(\d+)\)}', unpacked, 'key digit')
|
||||||
|
chars = [compat_chr(d - int(key_digit)) for d in digits]
|
||||||
|
return ''.join(chars)
|
||||||
|
|
||||||
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(
|
webpage = self._download_webpage(
|
||||||
'https://vshare.io/d/%s' % video_id, video_id)
|
'https://vshare.io/v/%s/width-650/height-430/1' % video_id,
|
||||||
|
video_id)
|
||||||
|
|
||||||
title = self._html_search_regex(
|
title = self._html_search_regex(
|
||||||
r'(?s)<div id="root-container">(.+?)<br/>', webpage, 'title')
|
r'<title>([^<]+)</title>', webpage, 'title')
|
||||||
video_url = self._search_regex(
|
title = title.split(' - ')[0]
|
||||||
r'<a[^>]+href=(["\'])(?P<url>(?:https?:)?//.+?)\1[^>]*>[Cc]lick\s+here',
|
|
||||||
webpage, 'video url', group='url')
|
|
||||||
|
|
||||||
return {
|
error = self._html_search_regex(
|
||||||
|
r'(?s)<div[^>]+\bclass=["\']xxx-error[^>]+>(.+?)</div', webpage,
|
||||||
|
'error', default=None)
|
||||||
|
if error:
|
||||||
|
raise ExtractorError(error, expected=True)
|
||||||
|
|
||||||
|
info = self._parse_html5_media_entries(
|
||||||
|
url, '<video>%s</video>' % self._extract_packed(webpage),
|
||||||
|
video_id)[0]
|
||||||
|
|
||||||
|
self._sort_formats(info['formats'])
|
||||||
|
|
||||||
|
info.update({
|
||||||
'id': video_id,
|
'id': video_id,
|
||||||
'title': title,
|
'title': title,
|
||||||
'url': video_url,
|
})
|
||||||
}
|
|
||||||
|
return info
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
__version__ = '2017.11.06'
|
__version__ = '2017.11.15'
|
||||||
|
Loading…
Reference in New Issue
Block a user