1 from __future__
import unicode_literals
3 from .fragment
import FragmentFD
4 from ..compat
import compat_urllib_error
11 class DashSegmentsFD(FragmentFD
):
13 Download segments in a DASH manifest
16 FD_NAME
= 'dashsegments'
18 def real_download(self
, filename
, info_dict
):
19 fragment_base_url
= info_dict
.get('fragment_base_url')
20 fragments
= info_dict
['fragments'][:1] if self
.params
.get(
21 'test', False) else info_dict
['fragments']
25 'total_frags': len(fragments
),
28 self
._prepare
_and
_start
_frag
_download
(ctx
)
30 fragment_retries
= self
.params
.get('fragment_retries', 0)
31 skip_unavailable_fragments
= self
.params
.get('skip_unavailable_fragments', True)
34 for i
, fragment
in enumerate(fragments
):
36 if frag_index
<= ctx
['fragment_index']:
38 # In DASH, the first segment contains necessary headers to
39 # generate a valid MP4 file, so always abort for the first segment
40 fatal
= i
== 0 or not skip_unavailable_fragments
42 while count
<= fragment_retries
:
44 fragment_url
= fragment
.get('url')
46 assert fragment_base_url
47 fragment_url
= urljoin(fragment_base_url
, fragment
['path'])
48 success
, frag_content
= self
._download
_fragment
(ctx
, fragment_url
, info_dict
)
51 self
._append
_fragment
(ctx
, frag_content
)
53 except compat_urllib_error
.HTTPError
as err
:
54 # YouTube may often return 404 HTTP error for a fragment causing the
55 # whole download to fail. However if the same fragment is immediately
56 # retried with the same request data this usually succeeds (1-2 attemps
57 # is usually enough) thus allowing to download the whole file successfully.
58 # To be future-proof we will retry all fragments that fail with any
61 if count
<= fragment_retries
:
62 self
.report_retry_fragment(err
, frag_index
, count
, fragment_retries
)
64 # Don't retry fragment if error occurred during HTTP downloading
65 # itself since it has own retry settings
67 self
.report_skip_fragment(frag_index
)
71 if count
> fragment_retries
:
73 self
.report_skip_fragment(frag_index
)
75 self
.report_error('giving up after %s fragment retries' % fragment_retries
)
78 self
._finish
_frag
_download
(ctx
)