]>
Commit | Line | Data |
---|---|---|
1 | from .common import InfoExtractor | |
2 | from ..utils import ExtractorError, try_get | |
3 | ||
4 | ||
5 | class SaitosanIE(InfoExtractor): | |
6 | _WORKING = False | |
7 | IE_NAME = 'Saitosan' | |
8 | _VALID_URL = r'https?://(?:www\.)?saitosan\.net/bview.html\?id=(?P<id>[0-9]+)' | |
9 | _TESTS = [{ | |
10 | 'url': 'http://www.saitosan.net/bview.html?id=10031846', | |
11 | 'info_dict': { | |
12 | 'id': '10031846', | |
13 | 'ext': 'mp4', | |
14 | 'title': '井下原 和弥', | |
15 | 'uploader': '井下原 和弥', | |
16 | 'thumbnail': 'http://111.171.196.85:8088/921f916f-7f55-4c97-b92e-5d9d0fef8f5f/thumb', | |
17 | 'is_live': True, | |
18 | }, | |
19 | 'params': { | |
20 | # m3u8 download | |
21 | 'skip_download': True, | |
22 | }, | |
23 | 'skip': 'Broadcasts are ephemeral', | |
24 | }, | |
25 | { | |
26 | 'url': 'http://www.saitosan.net/bview.html?id=10031795', | |
27 | 'info_dict': { | |
28 | 'id': '10031795', | |
29 | 'ext': 'mp4', | |
30 | 'title': '橋本', | |
31 | 'uploader': '橋本', | |
32 | 'thumbnail': 'http://111.171.196.85:8088/1a3933e1-a01a-483b-8931-af15f37f8082/thumb', | |
33 | 'is_live': True, | |
34 | }, | |
35 | 'params': { | |
36 | # m3u8 download | |
37 | 'skip_download': True, | |
38 | }, | |
39 | 'skip': 'Broadcasts are ephemeral', | |
40 | }] | |
41 | ||
42 | def _real_extract(self, url): | |
43 | b_id = self._match_id(url) | |
44 | ||
45 | base = 'http://hankachi.saitosan-api.net:8002/socket.io/?transport=polling&EIO=3' | |
46 | sid = self._download_socket_json(base, b_id, note='Opening socket').get('sid') | |
47 | base += '&sid=' + sid | |
48 | ||
49 | self._download_webpage(base, b_id, note='Polling socket') | |
50 | payload = f'420["room_start_join",{{"room_id":"{b_id}"}}]' | |
51 | payload = f'{len(payload)}:{payload}' | |
52 | ||
53 | self._download_webpage(base, b_id, data=payload, note='Polling socket with payload') | |
54 | response = self._download_socket_json(base, b_id, note='Polling socket') | |
55 | if not response.get('ok'): | |
56 | err = response.get('error') or {} | |
57 | raise ExtractorError( | |
58 | '{} said: {} - {}'.format(self.IE_NAME, err.get('code', '?'), err.get('msg', 'Unknown')) if err | |
59 | else 'The socket reported that the broadcast could not be joined. Maybe it\'s offline or the URL is incorrect', | |
60 | expected=True, video_id=b_id) | |
61 | ||
62 | self._download_webpage(base, b_id, data='26:421["room_finish_join",{}]', note='Polling socket') | |
63 | b_data = self._download_socket_json(base, b_id, note='Getting broadcast metadata from socket') | |
64 | m3u8_url = b_data.get('url') | |
65 | ||
66 | self._download_webpage(base, b_id, data='1:1', note='Closing socket', fatal=False) | |
67 | ||
68 | return { | |
69 | 'id': b_id, | |
70 | 'title': b_data.get('name'), | |
71 | 'formats': self._extract_m3u8_formats(m3u8_url, b_id, 'mp4', live=True), | |
72 | 'thumbnail': m3u8_url.replace('av.m3u8', 'thumb'), | |
73 | 'uploader': try_get(b_data, lambda x: x['broadcast_user']['name']), # same as title | |
74 | 'is_live': True, | |
75 | } |