1 from __future__
import unicode_literals
3 from ..compat
import compat_str
10 def get_suitable_downloader(info_dict
, params
={}, default
=NO_DEFAULT
, protocol
=None, to_stdout
=False):
11 info_dict
['protocol'] = determine_protocol(info_dict
)
12 info_copy
= info_dict
.copy()
13 info_copy
['to_stdout'] = to_stdout
15 protocols
= (protocol
or info_copy
['protocol']).split('+')
16 downloaders
= [_get_suitable_downloader(info_copy
, proto
, params
, default
) for proto
in protocols
]
18 if set(downloaders
) == {FFmpegFD}
and FFmpegFD
.can_merge_formats(info_copy
, params
):
20 elif (set(downloaders
) == {DashSegmentsFD}
21 and not (to_stdout
and len(protocols
) > 1)
22 and set(protocols
) == {'http_dash_segments_generator'}
):
24 elif len(downloaders
) == 1:
29 # Some of these require get_suitable_downloader
30 from .common
import FileDownloader
31 from .dash
import DashSegmentsFD
32 from .f4m
import F4mFD
33 from .hls
import HlsFD
34 from .http
import HttpFD
35 from .rtmp
import RtmpFD
36 from .rtsp
import RtspFD
37 from .ism
import IsmFD
38 from .mhtml
import MhtmlFD
39 from .niconico
import NiconicoDmcFD
40 from .websocket
import WebSocketFragmentFD
41 from .youtube_live_chat
import YoutubeLiveChatFD
42 from .external
import (
43 get_external_downloader
,
50 'rtmp_ffmpeg': FFmpegFD
,
56 'http_dash_segments': DashSegmentsFD
,
57 'http_dash_segments_generator': DashSegmentsFD
,
60 'niconico_dmc': NiconicoDmcFD
,
61 'websocket_frag': WebSocketFragmentFD
,
62 'youtube_live_chat': YoutubeLiveChatFD
,
63 'youtube_live_chat_replay': YoutubeLiveChatFD
,
67 def shorten_protocol_name(proto
, simplify
=False):
68 short_protocol_names
= {
69 'm3u8_native': 'm3u8_n',
70 'rtmp_ffmpeg': 'rtmp_f',
71 'http_dash_segments': 'dash',
72 'http_dash_segments_generator': 'dash_g',
73 'niconico_dmc': 'dmc',
74 'websocket_frag': 'WSfrag',
77 short_protocol_names
.update({
80 'm3u8_native': 'm3u8',
81 'http_dash_segments_generator': 'dash',
82 'rtmp_ffmpeg': 'rtmp',
83 'm3u8_frag_urls': 'm3u8',
84 'dash_frag_urls': 'dash',
86 return short_protocol_names
.get(proto
, proto
)
89 def _get_suitable_downloader(info_dict
, protocol
, params
, default
):
90 """Get the downloader class that can handle the info dict."""
91 if default
is NO_DEFAULT
:
94 # if (info_dict.get('start_time') or info_dict.get('end_time')) and not info_dict.get('requested_formats') and FFmpegFD.can_download(info_dict):
97 info_dict
['protocol'] = protocol
98 downloaders
= params
.get('external_downloader')
99 external_downloader
= (
100 downloaders
if isinstance(downloaders
, compat_str
) or downloaders
is None
101 else downloaders
.get(shorten_protocol_name(protocol
, True), downloaders
.get('default')))
103 if external_downloader
is None:
104 if info_dict
['to_stdout'] and FFmpegFD
.can_merge_formats(info_dict
, params
):
106 elif external_downloader
.lower() != 'native':
107 ed
= get_external_downloader(external_downloader
)
108 if ed
.can_download(info_dict
, external_downloader
):
111 if protocol
== 'http_dash_segments':
112 if info_dict
.get('is_live') and (external_downloader
or '').lower() != 'native':
115 if protocol
in ('m3u8', 'm3u8_native'):
116 if info_dict
.get('is_live'):
118 elif (external_downloader
or '').lower() == 'native':
120 elif get_suitable_downloader(
121 info_dict
, params
, None, protocol
='m3u8_frag_urls', to_stdout
=info_dict
['to_stdout']):
123 elif params
.get('hls_prefer_native') is True:
125 elif params
.get('hls_prefer_native') is False:
128 return PROTOCOL_MAP
.get(protocol
, default
)
133 'get_suitable_downloader',
134 'shorten_protocol_name',