]>
Commit | Line | Data |
---|---|---|
295fbb3a M |
1 | from .common import InfoExtractor |
2 | from ..utils import ( | |
3 | ExtractorError, | |
4 | try_call, | |
5 | unified_timestamp, | |
6 | ) | |
7 | ||
8 | ||
9 | class EplusIbIE(InfoExtractor): | |
10 | IE_NAME = 'eplus:inbound' | |
11 | IE_DESC = 'e+ (イープラス) overseas' | |
12 | _VALID_URL = r'https?://live\.eplus\.jp/ex/player\?ib=(?P<id>(?:\w|%2B|%2F){86}%3D%3D)' | |
13 | _TESTS = [{ | |
14 | 'url': 'https://live.eplus.jp/ex/player?ib=YEFxb3Vyc2Dombnjg7blkrLlrablnJLjgrnjgq%2Fjg7zjg6vjgqLjgqTjg4njg6vlkIzlpb3kvJpgTGllbGxhIQ%3D%3D', | |
15 | 'info_dict': { | |
16 | 'id': '354502-0001-002', | |
17 | 'title': 'LoveLive!Series Presents COUNTDOWN LoveLive! 2021→2022~LIVE with a smile!~【Streaming+(配信)】', | |
18 | 'live_status': 'was_live', | |
19 | 'release_date': '20211231', | |
20 | 'release_timestamp': 1640952000, | |
21 | 'description': str, | |
22 | }, | |
23 | 'params': { | |
24 | 'skip_download': True, | |
25 | 'ignore_no_formats_error': True, | |
26 | }, | |
27 | 'expected_warnings': [ | |
28 | 'Could not find the playlist URL. This event may not be accessible', | |
29 | 'No video formats found!', | |
30 | 'Requested format is not available', | |
31 | ], | |
32 | }] | |
33 | ||
34 | def _real_extract(self, url): | |
35 | video_id = self._match_id(url) | |
36 | webpage = self._download_webpage(url, video_id) | |
37 | ||
38 | data_json = self._search_json(r'<script>\s*var app\s*=', webpage, 'data json', video_id) | |
39 | ||
40 | delivery_status = data_json.get('delivery_status') | |
41 | archive_mode = data_json.get('archive_mode') | |
42 | release_timestamp = try_call(lambda: unified_timestamp(data_json['event_datetime']) - 32400) | |
43 | release_timestamp_str = data_json.get('event_datetime_text') # JST | |
44 | ||
45 | self.write_debug(f'delivery_status = {delivery_status}, archive_mode = {archive_mode}') | |
46 | ||
47 | if delivery_status == 'PREPARING': | |
48 | live_status = 'is_upcoming' | |
49 | elif delivery_status == 'STARTED': | |
50 | live_status = 'is_live' | |
51 | elif delivery_status == 'STOPPED': | |
52 | if archive_mode != 'ON': | |
53 | raise ExtractorError( | |
54 | 'This event has ended and there is no archive for this event', expected=True) | |
55 | live_status = 'post_live' | |
56 | elif delivery_status == 'WAIT_CONFIRM_ARCHIVED': | |
57 | live_status = 'post_live' | |
58 | elif delivery_status == 'CONFIRMED_ARCHIVE': | |
59 | live_status = 'was_live' | |
60 | else: | |
61 | self.report_warning(f'Unknown delivery_status {delivery_status}, treat it as a live') | |
62 | live_status = 'is_live' | |
63 | ||
64 | formats = [] | |
65 | ||
66 | m3u8_playlist_urls = self._search_json( | |
67 | r'var listChannels\s*=', webpage, 'hls URLs', video_id, contains_pattern=r'\[.+\]', default=[]) | |
68 | if not m3u8_playlist_urls: | |
69 | if live_status == 'is_upcoming': | |
70 | self.raise_no_formats( | |
71 | f'Could not find the playlist URL. This live event will begin at {release_timestamp_str} JST', expected=True) | |
72 | else: | |
73 | self.raise_no_formats( | |
74 | 'Could not find the playlist URL. This event may not be accessible', expected=True) | |
75 | elif live_status == 'is_upcoming': | |
76 | self.raise_no_formats(f'This live event will begin at {release_timestamp_str} JST', expected=True) | |
77 | elif live_status == 'post_live': | |
78 | self.raise_no_formats('This event has ended, and the archive will be available shortly', expected=True) | |
79 | else: | |
80 | for m3u8_playlist_url in m3u8_playlist_urls: | |
81 | formats.extend(self._extract_m3u8_formats(m3u8_playlist_url, video_id)) | |
82 | # FIXME: HTTP request headers need to be updated to continue download | |
83 | warning = 'Due to technical limitations, the download will be interrupted after one hour' | |
84 | if live_status == 'is_live': | |
85 | self.report_warning(warning) | |
86 | elif live_status == 'was_live': | |
87 | self.report_warning(f'{warning}. You can restart to continue the download') | |
88 | ||
89 | return { | |
90 | 'id': data_json['app_id'], | |
91 | 'title': data_json.get('app_name'), | |
92 | 'formats': formats, | |
93 | 'live_status': live_status, | |
94 | 'description': data_json.get('content'), | |
95 | 'release_timestamp': release_timestamp, | |
96 | } |