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