]> jfr.im git - yt-dlp.git/blame - yt_dlp/downloader/__init__.py
[ondemandkorea] Update `jw_config` regex (#2056)
[yt-dlp.git] / yt_dlp / downloader / __init__.py
CommitLineData
db1f3888
PH
1from __future__ import unicode_literals
2
52a8a1e1 3from ..compat import compat_str
5219cb3e 4from ..utils import (
5 determine_protocol,
dbf5416a 6 NO_DEFAULT
5219cb3e 7)
8
9
96fccc10 10def get_suitable_downloader(info_dict, params={}, default=NO_DEFAULT, protocol=None, to_stdout=False):
dbf5416a 11 info_dict['protocol'] = determine_protocol(info_dict)
5219cb3e 12 info_copy = info_dict.copy()
96fccc10 13 info_copy['to_stdout'] = to_stdout
c111cefa 14
15 downloaders = [_get_suitable_downloader(info_copy, proto, params, default)
16 for proto in (protocol or info_copy['protocol']).split('+')]
17 if set(downloaders) == {FFmpegFD} and FFmpegFD.can_merge_formats(info_copy, params):
18 return FFmpegFD
19 elif len(downloaders) == 1:
20 return downloaders[0]
21 return None
5219cb3e 22
23
dbf5416a 24# Some of these require get_suitable_downloader
3bc2ddcc 25from .common import FileDownloader
5219cb3e 26from .dash import DashSegmentsFD
222516d9 27from .f4m import F4mFD
3bc2ddcc
JMF
28from .hls import HlsFD
29from .http import HttpFD
3bc2ddcc 30from .rtmp import RtmpFD
be24916a 31from .rtsp import RtspFD
b2758123 32from .ism import IsmFD
cdb19aa4 33from .mhtml import MhtmlFD
fb198a8a 34from .niconico import NiconicoDmcFD
e36d50c5 35from .websocket import WebSocketFragmentFD
c60ee3a2 36from .youtube_live_chat import YoutubeLiveChatFD
12b84ac8 37from .external import (
38 get_external_downloader,
39 FFmpegFD,
40)
3bc2ddcc 41
a055469f
PH
42PROTOCOL_MAP = {
43 'rtmp': RtmpFD,
f304da8a 44 'rtmpe': RtmpFD,
0fa9a1e2 45 'rtmp_ffmpeg': FFmpegFD,
12b84ac8 46 'm3u8_native': HlsFD,
47 'm3u8': FFmpegFD,
be24916a 48 'mms': RtspFD,
49 'rtsp': RtspFD,
a055469f 50 'f4m': F4mFD,
423d2be5 51 'http_dash_segments': DashSegmentsFD,
b2758123 52 'ism': IsmFD,
cdb19aa4 53 'mhtml': MhtmlFD,
fb198a8a 54 'niconico_dmc': NiconicoDmcFD,
e36d50c5 55 'websocket_frag': WebSocketFragmentFD,
c60ee3a2 56 'youtube_live_chat': YoutubeLiveChatFD,
57 'youtube_live_chat_replay': YoutubeLiveChatFD,
a055469f 58}
f89197d7 59
a055469f 60
52a8a1e1 61def shorten_protocol_name(proto, simplify=False):
62 short_protocol_names = {
63 'm3u8_native': 'm3u8_n',
0fa9a1e2 64 'rtmp_ffmpeg': 'rtmp_f',
52a8a1e1 65 'http_dash_segments': 'dash',
66 'niconico_dmc': 'dmc',
e36d50c5 67 'websocket_frag': 'WSfrag',
52a8a1e1 68 }
69 if simplify:
70 short_protocol_names.update({
71 'https': 'http',
72 'ftps': 'ftp',
73 'm3u8_native': 'm3u8',
0fa9a1e2 74 'rtmp_ffmpeg': 'rtmp',
52a8a1e1 75 'm3u8_frag_urls': 'm3u8',
76 'dash_frag_urls': 'dash',
77 })
78 return short_protocol_names.get(proto, proto)
79
80
c111cefa 81def _get_suitable_downloader(info_dict, protocol, params, default):
3bc2ddcc 82 """Get the downloader class that can handle the info dict."""
dbf5416a 83 if default is NO_DEFAULT:
84 default = HttpFD
a055469f 85
6ae27bed 86 # 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):
da1973a0 87 # return FFmpegFD
12b84ac8 88
c111cefa 89 info_dict['protocol'] = protocol
52a8a1e1 90 downloaders = params.get('external_downloader')
91 external_downloader = (
68379de5 92 downloaders if isinstance(downloaders, compat_str) or downloaders is None
52a8a1e1 93 else downloaders.get(shorten_protocol_name(protocol, True), downloaders.get('default')))
52a8a1e1 94
96fccc10 95 if external_downloader is None:
96 if info_dict['to_stdout'] and FFmpegFD.can_merge_formats(info_dict, params):
97 return FFmpegFD
98 elif external_downloader.lower() != 'native':
222516d9 99 ed = get_external_downloader(external_downloader)
7f7de7f9 100 if ed.can_download(info_dict, external_downloader):
222516d9
PH
101 return ed
102
6251555f 103 if protocol == 'http_dash_segments':
45842107 104 if info_dict.get('is_live') and (external_downloader or '').lower() != 'native':
6251555f 105 return FFmpegFD
106
72e1fe96 107 if protocol in ('m3u8', 'm3u8_native'):
5219cb3e 108 if info_dict.get('is_live'):
109 return FFmpegFD
96fccc10 110 elif (external_downloader or '').lower() == 'native':
52a8a1e1 111 return HlsFD
96fccc10 112 elif get_suitable_downloader(
113 info_dict, params, None, protocol='m3u8_frag_urls', to_stdout=info_dict['to_stdout']):
5219cb3e 114 return HlsFD
115 elif params.get('hls_prefer_native') is True:
116 return HlsFD
117 elif params.get('hls_prefer_native') is False:
118 return FFmpegFD
bf09af3a 119
5219cb3e 120 return PROTOCOL_MAP.get(protocol, default)
a055469f 121
14d4e90e
PH
122
123__all__ = [
14d4e90e 124 'FileDownloader',
52a8a1e1 125 'get_suitable_downloader',
126 'shorten_protocol_name',
14d4e90e 127]