mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-26 09:11:25 +01:00
Compare commits
1 Commits
b3e9e252aa
...
e9c0c720f6
Author | SHA1 | Date | |
---|---|---|---|
|
e9c0c720f6 |
|
@ -1,4 +1,3 @@
|
||||||
import functools
|
|
||||||
import json
|
import json
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
|
@ -6,12 +5,10 @@ from .common import InfoExtractor
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
int_or_none,
|
int_or_none,
|
||||||
join_nonempty,
|
|
||||||
smuggle_url,
|
smuggle_url,
|
||||||
traverse_obj,
|
traverse_obj,
|
||||||
try_call,
|
try_call,
|
||||||
unsmuggle_url,
|
unsmuggle_url,
|
||||||
urljoin,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,52 +70,71 @@ class LiTVIE(InfoExtractor):
|
||||||
|
|
||||||
webpage = self._download_webpage(url, video_id)
|
webpage = self._download_webpage(url, video_id)
|
||||||
|
|
||||||
vod_data = self._search_nextjs_data(webpage, video_id, default={})
|
vod_data = self._parse_json(self._search_regex(
|
||||||
|
r'<script\s+id="__NEXT_DATA__"[^>]*>(.+)</script>', webpage, 'VOD data', default='{}'),
|
||||||
|
video_id)
|
||||||
|
|
||||||
program_info = traverse_obj(vod_data, ('props', 'pageProps', 'programInformation', {dict})) or {}
|
program_info = traverse_obj(
|
||||||
|
vod_data,
|
||||||
|
('props', 'pageProps', 'programInformation'),
|
||||||
|
default={}, expected_type=dict)
|
||||||
|
series_id = program_info.get('series_id')
|
||||||
playlist_data = traverse_obj(vod_data, ('props', 'pageProps', 'seriesTree'))
|
playlist_data = traverse_obj(vod_data, ('props', 'pageProps', 'seriesTree'))
|
||||||
if playlist_data is not None and self._yes_playlist(program_info.get('series_id'), video_id, smuggled_data):
|
if playlist_data is not None and self._yes_playlist(series_id, video_id, smuggled_data):
|
||||||
return self._extract_playlist(playlist_data, program_info.get('content_type'))
|
content_type = program_info.get('content_type')
|
||||||
|
return self._extract_playlist(playlist_data, content_type)
|
||||||
|
|
||||||
asset_id = traverse_obj(program_info, ('assets', 0, 'asset_id', {str}))
|
asset_id = traverse_obj(program_info, ('assets', 0, 'asset_id'))
|
||||||
if asset_id: # This is a live stream
|
if asset_id is None: # live stream case
|
||||||
|
asset_id = program_info.get('content_id')
|
||||||
|
media_type = program_info.get('content_type')
|
||||||
|
else: # vod case
|
||||||
media_type = 'vod'
|
media_type = 'vod'
|
||||||
else: # This is a VOD
|
|
||||||
asset_id = program_info['content_id']
|
|
||||||
media_type = program_info['content_type']
|
|
||||||
puid = try_call(lambda: self._get_cookies('https://www.litv.tv/')['PUID'].value)
|
puid = try_call(lambda: self._get_cookies('https://www.litv.tv/')['PUID'].value)
|
||||||
if puid:
|
if puid is None:
|
||||||
endpoint = 'get-urls'
|
|
||||||
else:
|
|
||||||
puid = str(uuid.uuid4())
|
puid = str(uuid.uuid4())
|
||||||
endpoint = 'get-urls-no-auth'
|
endpoint = 'get-urls-no-auth'
|
||||||
|
else:
|
||||||
|
endpoint = 'get-urls'
|
||||||
|
payload = {'AssetId': asset_id, 'MediaType': media_type, 'puid': puid}
|
||||||
video_data = self._download_json(
|
video_data = self._download_json(
|
||||||
f'https://www.litv.tv/api/{endpoint}', video_id,
|
f'https://www.litv.tv/api/{endpoint}', video_id,
|
||||||
data=json.dumps({'AssetId': asset_id, 'MediaType': media_type, 'puid': puid}).encode(),
|
data=json.dumps(payload).encode(),
|
||||||
headers={'Content-Type': 'application/json'})
|
headers={'Content-Type': 'application/json'})
|
||||||
|
|
||||||
if error := traverse_obj(video_data, ('error', {dict})):
|
if video_data.get('error'):
|
||||||
error_msg = traverse_obj(error, ('message', {str}))
|
error_msg = traverse_obj(video_data, ('error', 'message'))
|
||||||
if error_msg and 'OutsideRegionError' in error_msg:
|
if error_msg == 'OutsideRegionError: ':
|
||||||
self.raise_geo_restricted('This video is available in Taiwan only')
|
self.raise_geo_restricted('This video is available in Taiwan only')
|
||||||
elif error_msg:
|
if error_msg:
|
||||||
raise ExtractorError(f'{self.IE_NAME} said: {error_msg}', expected=True)
|
raise ExtractorError(f'{self.IE_NAME} said: {error_msg}', expected=True)
|
||||||
raise ExtractorError(f'Unexpected error from {self.IE_NAME}')
|
raise ExtractorError(f'Unexpected error from {self.IE_NAME}')
|
||||||
|
|
||||||
|
try:
|
||||||
|
asset_url = video_data['result']['AssetURLs'][0]
|
||||||
|
except KeyError:
|
||||||
|
raise ExtractorError(f'Unexpected result from {self.IE_NAME}')
|
||||||
formats = self._extract_m3u8_formats(
|
formats = self._extract_m3u8_formats(
|
||||||
video_data['result']['AssetURLs'][0], video_id, ext='mp4', m3u8_id='hls')
|
asset_url, video_id, ext='mp4',
|
||||||
|
entry_protocol='m3u8_native', m3u8_id='hls')
|
||||||
for a_format in formats:
|
for a_format in formats:
|
||||||
# LiTV HLS segments doesn't like compressions
|
# LiTV HLS segments doesn't like compressions
|
||||||
a_format.setdefault('http_headers', {})['Accept-Encoding'] = 'identity'
|
a_format.setdefault('http_headers', {})['Accept-Encoding'] = 'identity'
|
||||||
|
|
||||||
|
title = program_info['title'] + program_info.get('secondary_mark', '')
|
||||||
|
description = program_info.get('description')
|
||||||
|
thumbnail = program_info.get('picture')
|
||||||
|
if thumbnail is not None:
|
||||||
|
thumbnail = 'https://p-cdnstatic.svc.litv.tv/' + thumbnail
|
||||||
|
categories = [item['name'] for item in program_info.get('genres', [])]
|
||||||
|
episode = int_or_none(program_info.get('episode'))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'id': video_id,
|
'id': video_id,
|
||||||
'formats': formats,
|
'formats': formats,
|
||||||
'title': join_nonempty('title', 'secondary_mark', delim='', from_dict=program_info),
|
'title': title,
|
||||||
**traverse_obj(program_info, {
|
'description': description,
|
||||||
'description': ('description', {str}),
|
'thumbnail': thumbnail,
|
||||||
'thumbnail': ('picture', {functools.partial(urljoin, 'https://p-cdnstatic.svc.litv.tv/')}),
|
'categories': categories,
|
||||||
'categories': ('genres', ..., 'name', {str}),
|
'episode_number': episode,
|
||||||
'episode_number': ('episode', {int_or_none}),
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user