summaryrefslogtreecommitdiffstats
path: root/yt_dlp/extractor/francetv.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 09:06:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-08-05 09:06:10 +0000
commit137f07c27a88b07df57df5b2cdebebe3c7722bac (patch)
tree4ebdcbea6b540f69c40ba0be6ac766008030d149 /yt_dlp/extractor/francetv.py
parentAdding debian version 2024.05.27-1. (diff)
downloadyt-dlp-137f07c27a88b07df57df5b2cdebebe3c7722bac.tar.xz
yt-dlp-137f07c27a88b07df57df5b2cdebebe3c7722bac.zip
Merging upstream version 2024.07.01.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'yt_dlp/extractor/francetv.py')
-rw-r--r--yt_dlp/extractor/francetv.py54
1 files changed, 41 insertions, 13 deletions
diff --git a/yt_dlp/extractor/francetv.py b/yt_dlp/extractor/francetv.py
index 7b8f7dd..ab08f1c 100644
--- a/yt_dlp/extractor/francetv.py
+++ b/yt_dlp/extractor/francetv.py
@@ -5,6 +5,7 @@ from .common import InfoExtractor
from .dailymotion import DailymotionIE
from ..networking import HEADRequest
from ..utils import (
+ clean_html,
determine_ext,
filter_dict,
format_field,
@@ -33,6 +34,7 @@ class FranceTVIE(InfoExtractor):
_GEO_BYPASS = False
_TESTS = [{
+ # tokenized url is in dinfo['video']['token']
'url': 'francetv:ec217ecc-0733-48cf-ac06-af1347b849d1',
'info_dict': {
'id': 'ec217ecc-0733-48cf-ac06-af1347b849d1',
@@ -45,6 +47,19 @@ class FranceTVIE(InfoExtractor):
},
'params': {'skip_download': 'm3u8'},
}, {
+ # tokenized url is in dinfo['video']['token']['akamai']
+ 'url': 'francetv:c5bda21d-2c6f-4470-8849-3d8327adb2ba',
+ 'info_dict': {
+ 'id': 'c5bda21d-2c6f-4470-8849-3d8327adb2ba',
+ 'ext': 'mp4',
+ 'title': '13h15, le dimanche... - Les mystères de Jésus',
+ 'timestamp': 1514118300,
+ 'duration': 2880,
+ 'thumbnail': r're:^https?://.*\.jpg$',
+ 'upload_date': '20171224',
+ },
+ 'params': {'skip_download': 'm3u8'},
+ }, {
'url': 'francetv:162311093',
'only_matching': True,
}, {
@@ -68,6 +83,7 @@ class FranceTVIE(InfoExtractor):
def _extract_video(self, video_id, hostname=None):
is_live = None
videos = []
+ drm_formats = False
title = None
subtitle = None
episode_number = None
@@ -85,13 +101,12 @@ class FranceTVIE(InfoExtractor):
'device_type': device_type,
'browser': browser,
'domain': hostname,
- }), fatal=False)
+ }), fatal=False, expected_status=422) # 422 json gives detailed error code/message
if not dinfo:
continue
- video = traverse_obj(dinfo, ('video', {dict}))
- if video:
+ if video := traverse_obj(dinfo, ('video', {dict})):
videos.append(video)
if duration is None:
duration = video.get('duration')
@@ -99,9 +114,19 @@ class FranceTVIE(InfoExtractor):
is_live = video.get('is_live')
if spritesheets is None:
spritesheets = video.get('spritesheets')
+ elif code := traverse_obj(dinfo, ('code', {int})):
+ if code == 2009:
+ self.raise_geo_restricted(countries=self._GEO_COUNTRIES)
+ elif code in (2015, 2017):
+ # 2015: L'accès à cette vidéo est impossible. (DRM-only)
+ # 2017: Cette vidéo n'est pas disponible depuis le site web mobile (b/c DRM)
+ drm_formats = True
+ continue
+ self.report_warning(
+ f'{self.IE_NAME} said: {code} "{clean_html(dinfo.get("message"))}"')
+ continue
- meta = traverse_obj(dinfo, ('meta', {dict}))
- if meta:
+ if meta := traverse_obj(dinfo, ('meta', {dict})):
if title is None:
title = meta.get('title')
# meta['pre_title'] contains season and episode number for series in format "S<ID> E<ID>"
@@ -114,12 +139,15 @@ class FranceTVIE(InfoExtractor):
if timestamp is None:
timestamp = parse_iso8601(meta.get('broadcasted_at'))
+ if not videos and drm_formats:
+ self.report_drm(video_id)
+
formats, subtitles, video_url = [], {}, None
for video in traverse_obj(videos, lambda _, v: url_or_none(v['url'])):
video_url = video['url']
format_id = video.get('format')
- if token_url := url_or_none(video.get('token')):
+ if token_url := traverse_obj(video, ('token', (None, 'akamai'), {url_or_none}, any)):
tokenized_url = traverse_obj(self._download_json(
token_url, video_id, f'Downloading signed {format_id} manifest URL',
fatal=False, query={
@@ -175,7 +203,7 @@ class FranceTVIE(InfoExtractor):
for f in formats:
if f.get('acodec') != 'none' and f.get('language') in ('qtz', 'qad'):
f['language_preference'] = -10
- f['format_note'] = 'audio description%s' % format_field(f, 'format_note', ', %s')
+ f['format_note'] = 'audio description{}'.format(format_field(f, 'format_note', ', %s'))
if spritesheets:
formats.append({
@@ -189,10 +217,10 @@ class FranceTVIE(InfoExtractor):
'fragments': [{
'url': sheet,
# XXX: not entirely accurate; each spritesheet seems to be
- # a 10×10 grid of thumbnails corresponding to approximately
+ # a 10x10 grid of thumbnails corresponding to approximately
# 2 seconds of the video; the last spritesheet may be shorter
'duration': 200,
- } for sheet in traverse_obj(spritesheets, (..., {url_or_none}))]
+ } for sheet in traverse_obj(spritesheets, (..., {url_or_none}))],
})
return {
@@ -225,13 +253,13 @@ class FranceTVSiteIE(FranceTVBaseInfoExtractor):
_TESTS = [{
'url': 'https://www.france.tv/france-2/13h15-le-dimanche/140921-les-mysteres-de-jesus.html',
'info_dict': {
- 'id': 'ec217ecc-0733-48cf-ac06-af1347b849d1',
+ 'id': 'c5bda21d-2c6f-4470-8849-3d8327adb2ba',
'ext': 'mp4',
'title': '13h15, le dimanche... - Les mystères de Jésus',
- 'timestamp': 1502623500,
- 'duration': 2580,
+ 'timestamp': 1514118300,
+ 'duration': 2880,
'thumbnail': r're:^https?://.*\.jpg$',
- 'upload_date': '20170813',
+ 'upload_date': '20171224',
},
'params': {
'skip_download': True,