1 from .common
import InfoExtractor
2 from .youtube
import YoutubeIE
12 class AirTVIE(InfoExtractor
):
13 _VALID_URL
= r
'https?://www\.air\.tv/watch\?v=(?P<id>\w+)'
16 'url': 'https://www.air.tv/watch?v=W87jcWleSn2hXZN47zJZsQ',
18 'id': 'W87jcWleSn2hXZN47zJZsQ',
20 'release_date': '20221003',
21 'release_timestamp': 1664792603,
22 'channel_id': 'vgfManQlRQKgoFQ8i8peFQ',
23 'title': 'md5:c12d49ed367c3dadaa67659aff43494c',
24 'upload_date': '20221003',
27 'thumbnail': 'https://cdn-sp-gcs.air.tv/videos/W/8/W87jcWleSn2hXZN47zJZsQ/b13fc56464f47d9d62a36d110b9b5a72-4096x2160_9.jpg',
28 'timestamp': 1664792603,
32 'url': 'https://www.air.tv/watch?v=sv57EC8tRXG6h8dNXFUU1Q',
38 'channel_follower_count': int,
40 'uploader': 'Newsflare',
41 'thumbnail': 'https://i.ytimg.com/vi_webp/2ZTqmpee-bQ/maxresdefault.webp',
42 'availability': 'public',
43 'title': 'Geese Chase Alligator Across Golf Course',
44 'uploader_id': 'NewsflareBreaking',
45 'channel_url': 'https://www.youtube.com/channel/UCzSSoloGEz10HALUAbYhngQ',
46 'description': 'md5:99b21d9cea59330149efbd9706e208f5',
48 'channel_id': 'UCzSSoloGEz10HALUAbYhngQ',
49 'uploader_url': 'http://www.youtube.com/user/NewsflareBreaking',
51 'categories': ['News & Politics'],
52 'live_status': 'not_live',
53 'playable_in_embed': True,
54 'channel': 'Newsflare',
56 'upload_date': '20180511',
60 def _get_formats_and_subtitle(self
, json_data
, video_id
):
61 formats
, subtitles
= [], {}
62 for source
in traverse_obj(json_data
, 'sources', 'sources_desktop', ...):
63 ext
= determine_ext(source
.get('src'), mimetype2ext(source
.get('type')))
65 fmts
, subs
= self
._extract
_m
3u8_formats
_and
_subtitles
(source
.get('src'), video_id
)
67 self
._merge
_subtitles
(subs
, target
=subtitles
)
69 formats
.append({'url': source
.get('src'), 'ext': ext
})
70 return formats
, subtitles
72 def _real_extract(self
, url
):
73 display_id
= self
._match
_id
(url
)
74 webpage
= self
._download
_webpage
(url
, display_id
)
76 nextjs_json
= self
._search
_nextjs
_data
(webpage
, display_id
)['props']['pageProps']['initialState']['videos'][display_id
]
77 if nextjs_json
.get('youtube_id'):
78 return self
.url_result(
79 f
'https://www.youtube.com/watch?v={nextjs_json.get("youtube_id")}', YoutubeIE
)
81 formats
, subtitles
= self
._get
_formats
_and
_subtitle
(nextjs_json
, display_id
)
84 'title': nextjs_json
.get('title') or self
._html
_search
_meta
('og:title', webpage
),
86 'subtitles': subtitles
,
87 'description': nextjs_json
.get('description') or None,
88 'duration': int_or_none(nextjs_json
.get('duration')),
91 for thumbnail
in traverse_obj(nextjs_json
, ('default_thumbnails', ...))],
92 'channel_id': traverse_obj(nextjs_json
, 'channel', 'channel_slug'),
93 'timestamp': parse_iso8601(nextjs_json
.get('created')),
94 'release_timestamp': parse_iso8601(nextjs_json
.get('published')),
95 'view_count': int_or_none(nextjs_json
.get('views')),