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 .fc2
import FC2LiveFD
34 from .hls
import HlsFD
35 from .http
import HttpFD
36 from .rtmp
import RtmpFD
37 from .rtsp
import RtspFD
38 from .ism
import IsmFD
39 from .mhtml
import MhtmlFD
40 from .niconico
import NiconicoDmcFD
41 from .websocket
import WebSocketFragmentFD
42 from .youtube_live_chat
import YoutubeLiveChatFD
43 from .external
import (
44 get_external_downloader
,
51 'rtmp_ffmpeg': FFmpegFD
,
57 'http_dash_segments': DashSegmentsFD
,
58 'http_dash_segments_generator': DashSegmentsFD
,
61 'niconico_dmc': NiconicoDmcFD
,
62 'fc2_live': FC2LiveFD
,
63 'websocket_frag': WebSocketFragmentFD
,
64 'youtube_live_chat': YoutubeLiveChatFD
,
65 'youtube_live_chat_replay': YoutubeLiveChatFD
,
69 def shorten_protocol_name(proto
, simplify
=False):
70 short_protocol_names
= {
71 'm3u8_native': 'm3u8_n',
72 'rtmp_ffmpeg': 'rtmp_f',
73 'http_dash_segments': 'dash',
74 'http_dash_segments_generator': 'dash_g',
75 'niconico_dmc': 'dmc',
76 'websocket_frag': 'WSfrag',
79 short_protocol_names
.update({
82 'm3u8_native': 'm3u8',
83 'http_dash_segments_generator': 'dash',
84 'rtmp_ffmpeg': 'rtmp',
85 'm3u8_frag_urls': 'm3u8',
86 'dash_frag_urls': 'dash',
88 return short_protocol_names
.get(proto
, proto
)
91 def _get_suitable_downloader(info_dict
, protocol
, params
, default
):
92 """Get the downloader class that can handle the info dict."""
93 if default
is NO_DEFAULT
:
96 # 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):
99 info_dict
['protocol'] = protocol
100 downloaders
= params
.get('external_downloader')
101 external_downloader
= (
102 downloaders
if isinstance(downloaders
, compat_str
) or downloaders
is None
103 else downloaders
.get(shorten_protocol_name(protocol
, True), downloaders
.get('default')))
105 if external_downloader
is None:
106 if info_dict
['to_stdout'] and FFmpegFD
.can_merge_formats(info_dict
, params
):
108 elif external_downloader
.lower() != 'native':
109 ed
= get_external_downloader(external_downloader
)
110 if ed
.can_download(info_dict
, external_downloader
):
113 if protocol
== 'http_dash_segments':
114 if info_dict
.get('is_live') and (external_downloader
or '').lower() != 'native':
117 if protocol
in ('m3u8', 'm3u8_native'):
118 if info_dict
.get('is_live'):
120 elif (external_downloader
or '').lower() == 'native':
122 elif protocol
== 'm3u8_native' and get_suitable_downloader(
123 info_dict
, params
, None, protocol
='m3u8_frag_urls', to_stdout
=info_dict
['to_stdout']):
125 elif params
.get('hls_prefer_native') is True:
127 elif params
.get('hls_prefer_native') is False:
130 return PROTOCOL_MAP
.get(protocol
, default
)
135 'get_suitable_downloader',
136 'shorten_protocol_name',