mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2026-06-23 19:24:39 +00:00
Compare commits
No commits in common. "bf5d18016b03a3f2fd5d3494d9efe85d3f8beeac" and "e123a48f1155703d8709a4221a42bd45c0a2b3ce" have entirely different histories.
bf5d18016b
...
e123a48f11
@ -1,6 +1,5 @@
|
|||||||
from .common import InfoExtractor
|
from .common import InfoExtractor
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
clean_html,
|
|
||||||
clean_podcast_url,
|
clean_podcast_url,
|
||||||
int_or_none,
|
int_or_none,
|
||||||
parse_iso8601,
|
parse_iso8601,
|
||||||
@ -18,7 +17,7 @@ class ApplePodcastsIE(InfoExtractor):
|
|||||||
'ext': 'mp3',
|
'ext': 'mp3',
|
||||||
'title': 'Ferreck Dawn - To The Break of Dawn 117',
|
'title': 'Ferreck Dawn - To The Break of Dawn 117',
|
||||||
'episode': 'Ferreck Dawn - To The Break of Dawn 117',
|
'episode': 'Ferreck Dawn - To The Break of Dawn 117',
|
||||||
'description': 'md5:8c4f5c2c30af17ed6a98b0b9daf15b76',
|
'description': 'md5:1fc571102f79dbd0a77bfd71ffda23bc',
|
||||||
'upload_date': '20240812',
|
'upload_date': '20240812',
|
||||||
'timestamp': 1723449600,
|
'timestamp': 1723449600,
|
||||||
'duration': 3596,
|
'duration': 3596,
|
||||||
@ -59,7 +58,7 @@ class ApplePodcastsIE(InfoExtractor):
|
|||||||
r'<script [^>]*\bid=["\']serialized-server-data["\'][^>]*>', webpage,
|
r'<script [^>]*\bid=["\']serialized-server-data["\'][^>]*>', webpage,
|
||||||
'server data', episode_id, contains_pattern=r'\[{(?s:.+)}\]')[0]['data']
|
'server data', episode_id, contains_pattern=r'\[{(?s:.+)}\]')[0]['data']
|
||||||
model_data = traverse_obj(server_data, (
|
model_data = traverse_obj(server_data, (
|
||||||
'headerButtonItems', lambda _, v: v['$kind'] == 'share' and v['modelType'] == 'EpisodeLockup',
|
'headerButtonItems', lambda _, v: v['$kind'] == 'bookmark' and v['modelType'] == 'EpisodeOffer',
|
||||||
'model', {dict}, any))
|
'model', {dict}, any))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -69,8 +68,7 @@ class ApplePodcastsIE(InfoExtractor):
|
|||||||
or self._yield_json_ld(webpage, episode_id, fatal=False), episode_id, fatal=False),
|
or self._yield_json_ld(webpage, episode_id, fatal=False), episode_id, fatal=False),
|
||||||
**traverse_obj(model_data, {
|
**traverse_obj(model_data, {
|
||||||
'title': ('title', {str}),
|
'title': ('title', {str}),
|
||||||
'description': ('summary', {clean_html}),
|
'url': ('streamUrl', {clean_podcast_url}),
|
||||||
'url': ('playAction', 'episodeOffer', 'streamUrl', {clean_podcast_url}),
|
|
||||||
'timestamp': ('releaseDate', {parse_iso8601}),
|
'timestamp': ('releaseDate', {parse_iso8601}),
|
||||||
'duration': ('duration', {int_or_none}),
|
'duration': ('duration', {int_or_none}),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@ -3,19 +3,15 @@ from ..networking.exceptions import HTTPError
|
|||||||
from ..utils import (
|
from ..utils import (
|
||||||
ExtractorError,
|
ExtractorError,
|
||||||
UserNotLive,
|
UserNotLive,
|
||||||
int_or_none,
|
|
||||||
join_nonempty,
|
|
||||||
parse_iso8601,
|
parse_iso8601,
|
||||||
str_or_none,
|
str_or_none,
|
||||||
|
traverse_obj,
|
||||||
url_or_none,
|
url_or_none,
|
||||||
)
|
)
|
||||||
from ..utils.traversal import traverse_obj
|
|
||||||
|
|
||||||
|
|
||||||
class FlexTVIE(InfoExtractor):
|
class FlexTVIE(InfoExtractor):
|
||||||
IE_NAME = 'ttinglive'
|
_VALID_URL = r'https?://(?:www\.)?flextv\.co\.kr/channels/(?P<id>\d+)/live'
|
||||||
IE_DESC = '띵라이브 (formerly FlexTV)'
|
|
||||||
_VALID_URL = r'https?://(?:www\.)?(?:ttinglive\.com|flextv\.co\.kr)/channels/(?P<id>\d+)/live'
|
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
'url': 'https://www.flextv.co.kr/channels/231638/live',
|
'url': 'https://www.flextv.co.kr/channels/231638/live',
|
||||||
'info_dict': {
|
'info_dict': {
|
||||||
@ -40,32 +36,21 @@ class FlexTVIE(InfoExtractor):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
stream_data = self._download_json(
|
stream_data = self._download_json(
|
||||||
f'https://api.ttinglive.com/api/channels/{channel_id}/stream',
|
f'https://api.flextv.co.kr/api/channels/{channel_id}/stream',
|
||||||
channel_id, query={'option': 'all'})
|
channel_id, query={'option': 'all'})
|
||||||
except ExtractorError as e:
|
except ExtractorError as e:
|
||||||
if isinstance(e.cause, HTTPError) and e.cause.status == 400:
|
if isinstance(e.cause, HTTPError) and e.cause.status == 400:
|
||||||
raise UserNotLive(video_id=channel_id)
|
raise UserNotLive(video_id=channel_id)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
formats = []
|
playlist_url = stream_data['sources'][0]['url']
|
||||||
for stream in traverse_obj(stream_data, ('sources', ..., {dict})):
|
formats, subtitles = self._extract_m3u8_formats_and_subtitles(
|
||||||
if stream.get('format') == 'ivs' and url_or_none(stream.get('url')):
|
playlist_url, channel_id, 'mp4')
|
||||||
formats.extend(self._extract_m3u8_formats(
|
|
||||||
stream['url'], channel_id, 'mp4', live=True, fatal=False, m3u8_id='ivs'))
|
|
||||||
for format_type in ['hls', 'flv']:
|
|
||||||
for data in traverse_obj(stream, (
|
|
||||||
'urlDetail', format_type, 'resolution', lambda _, v: url_or_none(v['url']))):
|
|
||||||
formats.append({
|
|
||||||
'format_id': join_nonempty(format_type, data.get('suffixName'), delim=''),
|
|
||||||
'url': data['url'],
|
|
||||||
'height': int_or_none(data.get('resolution')),
|
|
||||||
'ext': 'mp4' if format_type == 'hls' else 'flv',
|
|
||||||
'protocol': 'm3u8_native' if format_type == 'hls' else 'http',
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'id': channel_id,
|
'id': channel_id,
|
||||||
'formats': formats,
|
'formats': formats,
|
||||||
|
'subtitles': subtitles,
|
||||||
'is_live': True,
|
'is_live': True,
|
||||||
**traverse_obj(stream_data, {
|
**traverse_obj(stream_data, {
|
||||||
'title': ('stream', 'title', {str}),
|
'title': ('stream', 'title', {str}),
|
||||||
|
|||||||
@ -572,7 +572,7 @@ class VKUserVideosIE(VKBaseIE):
|
|||||||
IE_DESC = "VK - User's Videos"
|
IE_DESC = "VK - User's Videos"
|
||||||
_BASE_URL_RE = r'https?://(?:(?:m|new)\.)?vk(?:video\.ru|\.com/video)'
|
_BASE_URL_RE = r'https?://(?:(?:m|new)\.)?vk(?:video\.ru|\.com/video)'
|
||||||
_VALID_URL = [
|
_VALID_URL = [
|
||||||
rf'{_BASE_URL_RE}/playlist/(?P<id>-?\d+_-?\d+)',
|
rf'{_BASE_URL_RE}/playlist/(?P<id>-?\d+_\d+)',
|
||||||
rf'{_BASE_URL_RE}/(?P<id>@[^/?#]+)(?:/all)?/?(?!\?.*\bz=video)(?:[?#]|$)',
|
rf'{_BASE_URL_RE}/(?P<id>@[^/?#]+)(?:/all)?/?(?!\?.*\bz=video)(?:[?#]|$)',
|
||||||
]
|
]
|
||||||
_TESTS = [{
|
_TESTS = [{
|
||||||
@ -602,9 +602,6 @@ class VKUserVideosIE(VKBaseIE):
|
|||||||
}, {
|
}, {
|
||||||
'url': 'https://vk.com/video/playlist/-174476437_2',
|
'url': 'https://vk.com/video/playlist/-174476437_2',
|
||||||
'only_matching': True,
|
'only_matching': True,
|
||||||
}, {
|
|
||||||
'url': 'https://vkvideo.ru/playlist/-51890028_-2',
|
|
||||||
'only_matching': True,
|
|
||||||
}]
|
}]
|
||||||
_VIDEO = collections.namedtuple('Video', ['owner_id', 'id'])
|
_VIDEO = collections.namedtuple('Video', ['owner_id', 'id'])
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user