]>
Commit | Line | Data |
---|---|---|
3ca3f77f U |
1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
4 | import re | |
5 | ||
6 | from .common import InfoExtractor | |
7 | from ..utils import js_to_json | |
8 | ||
9 | ||
10 | class LineTVIE(InfoExtractor): | |
11 | _VALID_URL = r'https?://tv\.line\.me/v/(?P<id>\d+)_[^/]+-(?P<segment>ep\d+-\d+)' | |
12 | ||
13 | _TESTS = [{ | |
14 | 'url': 'https://tv.line.me/v/793123_goodbye-mrblack-ep1-1/list/69246', | |
15 | 'info_dict': { | |
16 | 'id': '793123_ep1-1', | |
17 | 'ext': 'mp4', | |
18 | 'title': 'Goodbye Mr.Black | EP.1-1', | |
19 | 'thumbnail': r're:^https?://.*\.jpg$', | |
20 | 'duration': 998.509, | |
21 | 'view_count': int, | |
22 | }, | |
23 | }, { | |
24 | 'url': 'https://tv.line.me/v/2587507_%E6%B4%BE%E9%81%A3%E5%A5%B3%E9%86%ABx-ep1-02/list/185245', | |
25 | 'only_matching': True, | |
26 | }] | |
27 | ||
28 | def _real_extract(self, url): | |
29 | series_id, segment = re.match(self._VALID_URL, url).groups() | |
30 | video_id = '%s_%s' % (series_id, segment) | |
31 | ||
32 | webpage = self._download_webpage(url, video_id) | |
33 | ||
34 | player_params = self._parse_json(self._search_regex( | |
35 | r'naver\.WebPlayer\(({[^}]+})\)', webpage, 'player parameters'), | |
36 | video_id, transform_source=js_to_json) | |
37 | ||
38 | video_info = self._download_json( | |
39 | 'https://global-nvapis.line.me/linetv/rmcnmv/vod_play_videoInfo.json', | |
40 | video_id, query={ | |
41 | 'videoId': player_params['videoId'], | |
42 | 'key': player_params['key'], | |
43 | }) | |
44 | ||
45 | stream = video_info['streams'][0] | |
46 | extra_query = '?__gda__=' + stream['key']['value'] | |
47 | formats = self._extract_m3u8_formats( | |
48 | stream['source'] + extra_query, video_id, ext='mp4', | |
49 | entry_protocol='m3u8_native', m3u8_id='hls') | |
50 | ||
51 | for a_format in formats: | |
52 | a_format['url'] += extra_query | |
53 | ||
54 | duration = None | |
55 | for video in video_info.get('videos', {}).get('list', []): | |
56 | encoding_option = video.get('encodingOption', {}) | |
57 | abr = video['bitrate']['audio'] | |
58 | vbr = video['bitrate']['video'] | |
59 | tbr = abr + vbr | |
60 | formats.append({ | |
61 | 'url': video['source'], | |
62 | 'format_id': 'http-%d' % int(tbr), | |
63 | 'height': encoding_option.get('height'), | |
64 | 'width': encoding_option.get('width'), | |
65 | 'abr': abr, | |
66 | 'vbr': vbr, | |
67 | 'filesize': video.get('size'), | |
68 | }) | |
69 | if video.get('duration') and duration is None: | |
70 | duration = video['duration'] | |
71 | ||
72 | self._sort_formats(formats) | |
73 | ||
74 | if not formats[0].get('width'): | |
75 | formats[0]['vcodec'] = 'none' | |
76 | ||
77 | title = self._og_search_title(webpage) | |
78 | ||
79 | # like_count requires an additional API request https://tv.line.me/api/likeit/getCount | |
80 | ||
81 | return { | |
82 | 'id': video_id, | |
83 | 'title': title, | |
84 | 'formats': formats, | |
85 | 'extra_param_to_segment_url': extra_query[1:], | |
86 | 'duration': duration, | |
87 | 'thumbnails': [{'url': thumbnail['source']} | |
88 | for thumbnail in video_info.get('thumbnails', {}).get('list', [])], | |
89 | 'view_count': video_info.get('meta', {}).get('count'), | |
90 | } |