]>
Commit | Line | Data |
---|---|---|
6800d337 | 1 | from __future__ import unicode_literals |
adbc4ec4 | 2 | import time |
6800d337 | 3 | |
dbf5416a | 4 | from ..downloader import get_suitable_downloader |
c43fe026 | 5 | from .fragment import FragmentFD |
5219cb3e | 6 | |
4c7853de | 7 | from ..utils import urljoin |
453a1617 | 8 | |
6800d337 | 9 | |
c43fe026 | 10 | class DashSegmentsFD(FragmentFD): |
6800d337 | 11 | """ |
0a473f2f | 12 | Download segments in a DASH manifest. External downloaders can take over |
52a8a1e1 | 13 | the fragment downloads by supporting the 'dash_frag_urls' protocol |
6800d337 | 14 | """ |
6800d337 | 15 | |
c43fe026 | 16 | FD_NAME = 'dashsegments' |
5bf3276e | 17 | |
c43fe026 | 18 | def real_download(self, filename, info_dict): |
adbc4ec4 | 19 | if info_dict.get('is_live') and set(info_dict['protocol'].split('+')) != {'http_dash_segments_generator'}: |
dbf5416a | 20 | self.report_error('Live DASH videos are not supported') |
21 | ||
adbc4ec4 | 22 | real_start = time.time() |
96fccc10 | 23 | real_downloader = get_suitable_downloader( |
a46a815b | 24 | info_dict, self.params, None, protocol='dash_frag_urls', to_stdout=(filename == '-')) |
5219cb3e | 25 | |
adbc4ec4 THD |
26 | requested_formats = [{**info_dict, **fmt} for fmt in info_dict.get('requested_formats', [])] |
27 | args = [] | |
28 | for fmt in requested_formats or [info_dict]: | |
29 | try: | |
30 | fragment_count = 1 if self.params.get('test') else len(fmt['fragments']) | |
31 | except TypeError: | |
32 | fragment_count = None | |
33 | ctx = { | |
34 | 'filename': fmt.get('filepath') or filename, | |
35 | 'live': 'is_from_start' if fmt.get('is_from_start') else fmt.get('is_live'), | |
36 | 'total_frags': fragment_count, | |
37 | } | |
38 | ||
39 | if real_downloader: | |
40 | self._prepare_external_frag_download(ctx) | |
41 | else: | |
42 | self._prepare_and_start_frag_download(ctx, fmt) | |
43 | ctx['start'] = real_start | |
44 | ||
45 | fragments_to_download = self._get_fragments(fmt, ctx) | |
46 | ||
47 | if real_downloader: | |
48 | self.to_screen( | |
49 | '[%s] Fragment downloads will be delegated to %s' % (self.FD_NAME, real_downloader.get_basename())) | |
4273cc77 | 50 | info_dict['fragments'] = list(fragments_to_download) |
adbc4ec4 THD |
51 | fd = real_downloader(self.ydl, self.params) |
52 | return fd.real_download(filename, info_dict) | |
53 | ||
54 | args.append([ctx, fragments_to_download, fmt]) | |
5bf3276e | 55 | |
adbc4ec4 THD |
56 | return self.download_and_append_fragments_multiple(*args) |
57 | ||
58 | def _resolve_fragments(self, fragments, ctx): | |
59 | fragments = fragments(ctx) if callable(fragments) else fragments | |
4ac5b948 | 60 | return [next(iter(fragments))] if self.params.get('test') else fragments |
adbc4ec4 THD |
61 | |
62 | def _get_fragments(self, fmt, ctx): | |
63 | fragment_base_url = fmt.get('fragment_base_url') | |
64 | fragments = self._resolve_fragments(fmt['fragments'], ctx) | |
6800d337 | 65 | |
75a24854 | 66 | frag_index = 0 |
1141e910 | 67 | for i, fragment in enumerate(fragments): |
75a24854 | 68 | frag_index += 1 |
3e0304fe | 69 | if frag_index <= ctx['fragment_index']: |
75a24854 | 70 | continue |
5219cb3e | 71 | fragment_url = fragment.get('url') |
72 | if not fragment_url: | |
73 | assert fragment_base_url | |
74 | fragment_url = urljoin(fragment_base_url, fragment['path']) | |
75 | ||
adbc4ec4 | 76 | yield { |
4cf1e5d2 | 77 | 'frag_index': frag_index, |
78 | 'index': i, | |
79 | 'url': fragment_url, | |
adbc4ec4 | 80 | } |