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