Merge branch 'remitamine-snagfilms'
This commit is contained in:
commit
9d1bf70234
3 changed files with 159 additions and 0 deletions
|
@ -493,6 +493,10 @@ from .smotri import (
|
||||||
SmotriUserIE,
|
SmotriUserIE,
|
||||||
SmotriBroadcastIE,
|
SmotriBroadcastIE,
|
||||||
)
|
)
|
||||||
|
from .snagfilms import (
|
||||||
|
SnagFilmsIE,
|
||||||
|
SnagFilmsEmbedIE,
|
||||||
|
)
|
||||||
from .snotr import SnotrIE
|
from .snotr import SnotrIE
|
||||||
from .sohu import SohuIE
|
from .sohu import SohuIE
|
||||||
from .soompi import (
|
from .soompi import (
|
||||||
|
|
|
@ -47,6 +47,7 @@ from .xhamster import XHamsterEmbedIE
|
||||||
from .vimeo import VimeoIE
|
from .vimeo import VimeoIE
|
||||||
from .dailymotion import DailymotionCloudIE
|
from .dailymotion import DailymotionCloudIE
|
||||||
from .onionstudios import OnionStudiosIE
|
from .onionstudios import OnionStudiosIE
|
||||||
|
from .snagfilms import SnagFilmsEmbedIE
|
||||||
|
|
||||||
|
|
||||||
class GenericIE(InfoExtractor):
|
class GenericIE(InfoExtractor):
|
||||||
|
@ -849,6 +850,15 @@ class GenericIE(InfoExtractor):
|
||||||
'uploader_id': 'clickhole',
|
'uploader_id': 'clickhole',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
# SnagFilms embed
|
||||||
|
{
|
||||||
|
'url': 'http://whilewewatch.blogspot.ru/2012/06/whilewewatch-whilewewatch-gripping.html',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '74849a00-85a9-11e1-9660-123139220831',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': '#whilewewatch',
|
||||||
|
}
|
||||||
|
},
|
||||||
# AdobeTVVideo embed
|
# AdobeTVVideo embed
|
||||||
{
|
{
|
||||||
'url': 'https://helpx.adobe.com/acrobat/how-to/new-experience-acrobat-dc.html?set=acrobat--get-started--essential-beginners',
|
'url': 'https://helpx.adobe.com/acrobat/how-to/new-experience-acrobat-dc.html?set=acrobat--get-started--essential-beginners',
|
||||||
|
@ -1550,6 +1560,11 @@ class GenericIE(InfoExtractor):
|
||||||
if onionstudios_url:
|
if onionstudios_url:
|
||||||
return self.url_result(onionstudios_url)
|
return self.url_result(onionstudios_url)
|
||||||
|
|
||||||
|
# Look for SnagFilms embeds
|
||||||
|
snagfilms_url = SnagFilmsEmbedIE._extract_url(webpage)
|
||||||
|
if snagfilms_url:
|
||||||
|
return self.url_result(snagfilms_url)
|
||||||
|
|
||||||
# Look for AdobeTVVideo embeds
|
# Look for AdobeTVVideo embeds
|
||||||
mobj = re.search(
|
mobj = re.search(
|
||||||
r'<iframe[^>]+src=[\'"]((?:https?:)?//video\.tv\.adobe\.com/v/\d+[^"]+)[\'"]',
|
r'<iframe[^>]+src=[\'"]((?:https?:)?//video\.tv\.adobe\.com/v/\d+[^"]+)[\'"]',
|
||||||
|
|
140
youtube_dl/extractor/snagfilms.py
Normal file
140
youtube_dl/extractor/snagfilms.py
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
from .common import InfoExtractor
|
||||||
|
from ..utils import (
|
||||||
|
clean_html,
|
||||||
|
determine_ext,
|
||||||
|
int_or_none,
|
||||||
|
js_to_json,
|
||||||
|
parse_duration,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class SnagFilmsEmbedIE(InfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:(?:www|embed)\.)?snagfilms\.com/embed/player\?.*\bfilmId=(?P<id>[\da-f-]{36})'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'http://embed.snagfilms.com/embed/player?filmId=74849a00-85a9-11e1-9660-123139220831&w=500',
|
||||||
|
'md5': '2924e9215c6eff7a55ed35b72276bd93',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '74849a00-85a9-11e1-9660-123139220831',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': '#whilewewatch',
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'url': 'http://www.snagfilms.com/embed/player?filmId=0000014c-de2f-d5d6-abcf-ffef58af0017',
|
||||||
|
'only_matching': True,
|
||||||
|
}]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _extract_url(webpage):
|
||||||
|
mobj = re.search(
|
||||||
|
r'<iframe[^>]+?src=(["\'])(?P<url>(?:https?:)?//(?:embed\.)?snagfilms\.com/embed/player.+?)\1', webpage)
|
||||||
|
if mobj:
|
||||||
|
return mobj.group('url')
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
video_id = self._match_id(url)
|
||||||
|
|
||||||
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
|
||||||
|
formats = []
|
||||||
|
for source in self._parse_json(js_to_json(self._search_regex(
|
||||||
|
r'(?s)sources:\s*(\[.+?\]),', webpage, 'json')), video_id):
|
||||||
|
file_ = source.get('file')
|
||||||
|
if not file_:
|
||||||
|
continue
|
||||||
|
type_ = source.get('type')
|
||||||
|
format_id = source.get('label')
|
||||||
|
ext = determine_ext(file_)
|
||||||
|
if any(_ == 'm3u8' for _ in (type_, ext)):
|
||||||
|
formats.extend(self._extract_m3u8_formats(
|
||||||
|
file_, video_id, 'mp4', m3u8_id='hls'))
|
||||||
|
else:
|
||||||
|
bitrate = int_or_none(self._search_regex(
|
||||||
|
r'(\d+)kbps', file_, 'bitrate', default=None))
|
||||||
|
height = int_or_none(self._search_regex(
|
||||||
|
r'^(\d+)[pP]$', format_id, 'height', default=None))
|
||||||
|
formats.append({
|
||||||
|
'url': file_,
|
||||||
|
'format_id': format_id,
|
||||||
|
'tbr': bitrate,
|
||||||
|
'height': height,
|
||||||
|
})
|
||||||
|
self._sort_formats(formats)
|
||||||
|
|
||||||
|
title = self._search_regex(
|
||||||
|
[r"title\s*:\s*'([^']+)'", r'<title>([^<]+)</title>'],
|
||||||
|
webpage, 'title')
|
||||||
|
|
||||||
|
return {
|
||||||
|
'id': video_id,
|
||||||
|
'title': title,
|
||||||
|
'formats': formats,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class SnagFilmsIE(InfoExtractor):
|
||||||
|
_VALID_URL = r'https?://(?:www\.)?snagfilms\.com/films/title/(?P<id>[^/]+)'
|
||||||
|
_TEST = {
|
||||||
|
'url': 'http://www.snagfilms.com/films/title/lost_for_life',
|
||||||
|
'md5': '19844f897b35af219773fd63bdec2942',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '0000014c-de2f-d5d6-abcf-ffef58af0017',
|
||||||
|
'display_id': 'lost_for_life',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Lost for Life',
|
||||||
|
'description': 'md5:fbdacc8bb6b455e464aaf98bc02e1c82',
|
||||||
|
'thumbnail': 're:^https?://.*\.jpg',
|
||||||
|
'duration': 4489,
|
||||||
|
'categories': ['Documentary', 'Crime', 'Award Winning', 'Festivals']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
display_id = self._match_id(url)
|
||||||
|
|
||||||
|
webpage = self._download_webpage(url, display_id)
|
||||||
|
|
||||||
|
film_id = self._search_regex(r'filmId=([\da-f-]{36})"', webpage, 'film id')
|
||||||
|
|
||||||
|
snag = self._parse_json(
|
||||||
|
self._search_regex(
|
||||||
|
'Snag\.page\.data\s*=\s*(\[.+?\]);', webpage, 'snag'),
|
||||||
|
display_id)
|
||||||
|
|
||||||
|
for item in snag:
|
||||||
|
if item.get('data', {}).get('film', {}).get('id') == film_id:
|
||||||
|
data = item['data']['film']
|
||||||
|
title = data['title']
|
||||||
|
description = clean_html(data.get('synopsis'))
|
||||||
|
thumbnail = data.get('image')
|
||||||
|
duration = int_or_none(data.get('duration') or data.get('runtime'))
|
||||||
|
categories = [
|
||||||
|
category['title'] for category in data.get('categories', [])
|
||||||
|
if category.get('title')]
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
title = self._search_regex(
|
||||||
|
r'itemprop="title">([^<]+)<', webpage, 'title')
|
||||||
|
description = self._html_search_regex(
|
||||||
|
r'(?s)<div itemprop="description" class="film-synopsis-inner ">(.+?)</div>',
|
||||||
|
webpage, 'description', default=None) or self._og_search_description(webpage)
|
||||||
|
thumbnail = self._og_search_thumbnail(webpage)
|
||||||
|
duration = parse_duration(self._search_regex(
|
||||||
|
r'<span itemprop="duration" class="film-duration strong">([^<]+)<',
|
||||||
|
webpage, 'duration', fatal=False))
|
||||||
|
categories = re.findall(r'<a href="/movies/[^"]+">([^<]+)</a>', webpage)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'_type': 'url_transparent',
|
||||||
|
'url': 'http://embed.snagfilms.com/embed/player?filmId=%s' % film_id,
|
||||||
|
'id': film_id,
|
||||||
|
'display_id': display_id,
|
||||||
|
'title': title,
|
||||||
|
'description': description,
|
||||||
|
'thumbnail': thumbnail,
|
||||||
|
'duration': duration,
|
||||||
|
'categories': categories,
|
||||||
|
}
|
Loading…
Reference in a new issue