X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=youtube_dl%2Fextractor%2Ffrancetv.py;h=c02cd03de1c59452ac1ff2432f9e5ea54134e7de;hb=54fc90aabfb71968f28af68dfe3f7a3544cc2f0b;hp=e0734d59ac3189ada79eaf98d1461d8c07c47ecb;hpb=99892e9908c5366be334f48d5c9ce0044ec37a47;p=youtube-dl diff --git a/youtube_dl/extractor/francetv.py b/youtube_dl/extractor/francetv.py index e0734d59a..c02cd03de 100644 --- a/youtube_dl/extractor/francetv.py +++ b/youtube_dl/extractor/francetv.py @@ -11,21 +11,23 @@ from ..compat import ( ) from ..utils import ( clean_html, + determine_ext, ExtractorError, int_or_none, parse_duration, - determine_ext, + try_get, ) from .dailymotion import DailymotionIE class FranceTVBaseInfoExtractor(InfoExtractor): - def _make_url_result(self, video_id, catalog=None): - full_id = 'francetv:%s' % video_id - if catalog: + def _make_url_result(self, video_or_full_id, catalog=None): + full_id = 'francetv:%s' % video_or_full_id + if '@' not in video_or_full_id and catalog: full_id += '@%s' % catalog return self.url_result( - full_id, ie=FranceTVIE.ie_key(), video_id=video_id) + full_id, ie=FranceTVIE.ie_key(), + video_id=video_or_full_id.split('@')[0]) class FranceTVIE(InfoExtractor): @@ -76,6 +78,10 @@ class FranceTVIE(InfoExtractor): }, { 'url': 'francetv:NI_657393@Regions', 'only_matching': True, + }, { + # france-3 live + 'url': 'francetv:SIM_France3', + 'only_matching': True, }] def _extract_video(self, video_id, catalogue=None): @@ -120,6 +126,8 @@ class FranceTVIE(InfoExtractor): return signed_url return manifest_url + is_live = None + formats = [] for video in info['videos']: if video['statut'] != 'ONLINE': @@ -127,6 +135,10 @@ class FranceTVIE(InfoExtractor): video_url = video['url'] if not video_url: continue + if is_live is None: + is_live = (try_get( + video, lambda x: x['plages_ouverture'][0]['direct'], + bool) is True) or '/live.francetv.fr/' in video_url format_id = video['format'] ext = determine_ext(video_url) if ext == 'f4m': @@ -172,11 +184,12 @@ class FranceTVIE(InfoExtractor): return { 'id': video_id, - 'title': title, + 'title': self._live_title(title) if is_live else title, 'description': clean_html(info['synopsis']), 'thumbnail': compat_urlparse.urljoin('http://pluzz.francetv.fr', info['image']), 'duration': int_or_none(info.get('real_duration')) or parse_duration(info['duree']), 'timestamp': int_or_none(info['diffusion']['timestamp']), + 'is_live': is_live, 'formats': formats, 'subtitles': subtitles, } @@ -245,6 +258,10 @@ class FranceTVSiteIE(FranceTVBaseInfoExtractor): }, { 'url': 'https://www.france.tv/142749-rouge-sang.html', 'only_matching': True, + }, { + # france-3 live + 'url': 'https://www.france.tv/france-3/direct.html', + 'only_matching': True, }] def _real_extract(self, url): @@ -431,3 +448,43 @@ class CultureboxIE(FranceTVBaseInfoExtractor): webpage, 'video id').split('@') return self._make_url_result(video_id, catalogue) + + +class FranceTVJeunesseIE(FranceTVBaseInfoExtractor): + _VALID_URL = r'(?Phttps?://(?:www\.)?(?:zouzous|ludo)\.fr/heros/(?P[^/?#&]+))' + + _TESTS = [{ + 'url': 'https://www.zouzous.fr/heros/simon', + 'info_dict': { + 'id': 'simon', + }, + 'playlist_count': 9, + }, { + 'url': 'https://www.ludo.fr/heros/ninjago', + 'info_dict': { + 'id': 'ninjago', + }, + 'playlist_count': 10, + }, { + 'url': 'https://www.zouzous.fr/heros/simon?abc', + 'only_matching': True, + }] + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + playlist_id = mobj.group('id') + + playlist = self._download_json( + '%s/%s' % (mobj.group('url'), 'playlist'), playlist_id) + + if not playlist.get('count'): + raise ExtractorError( + '%s is not available' % playlist_id, expected=True) + + entries = [] + for item in playlist['items']: + identity = item.get('identity') + if identity and isinstance(identity, compat_str): + entries.append(self._make_url_result(identity)) + + return self.playlist_result(entries, playlist_id)