]> jfr.im git - yt-dlp.git/blame - yt_dlp/downloader/__init__.py
Option to choose different downloader for different protocols
[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,
6)
7
8
9def _get_real_downloader(info_dict, protocol=None, *args, **kwargs):
10 info_copy = info_dict.copy()
11 if protocol:
12 info_copy['protocol'] = protocol
13 return get_suitable_downloader(info_copy, *args, **kwargs)
14
15
16# Some of these require _get_real_downloader
3bc2ddcc 17from .common import FileDownloader
5219cb3e 18from .dash import DashSegmentsFD
222516d9 19from .f4m import F4mFD
3bc2ddcc
JMF
20from .hls import HlsFD
21from .http import HttpFD
3bc2ddcc 22from .rtmp import RtmpFD
be24916a 23from .rtsp import RtspFD
b2758123 24from .ism import IsmFD
fb198a8a 25from .niconico import NiconicoDmcFD
a78e3a57 26from .youtube_live_chat import YoutubeLiveChatReplayFD
12b84ac8 27from .external import (
28 get_external_downloader,
29 FFmpegFD,
30)
3bc2ddcc 31
a055469f
PH
32PROTOCOL_MAP = {
33 'rtmp': RtmpFD,
12b84ac8 34 'm3u8_native': HlsFD,
35 'm3u8': FFmpegFD,
be24916a 36 'mms': RtspFD,
37 'rtsp': RtspFD,
a055469f 38 'f4m': F4mFD,
423d2be5 39 'http_dash_segments': DashSegmentsFD,
b2758123 40 'ism': IsmFD,
fb198a8a 41 'niconico_dmc': NiconicoDmcFD,
a78e3a57 42 'youtube_live_chat_replay': YoutubeLiveChatReplayFD,
a055469f 43}
f89197d7 44
a055469f 45
52a8a1e1 46def shorten_protocol_name(proto, simplify=False):
47 short_protocol_names = {
48 'm3u8_native': 'm3u8_n',
49 'http_dash_segments': 'dash',
50 'niconico_dmc': 'dmc',
51 }
52 if simplify:
53 short_protocol_names.update({
54 'https': 'http',
55 'ftps': 'ftp',
56 'm3u8_native': 'm3u8',
57 'm3u8_frag_urls': 'm3u8',
58 'dash_frag_urls': 'dash',
59 })
60 return short_protocol_names.get(proto, proto)
61
62
5219cb3e 63def get_suitable_downloader(info_dict, params={}, default=HttpFD):
3bc2ddcc 64 """Get the downloader class that can handle the info dict."""
a055469f
PH
65 protocol = determine_protocol(info_dict)
66 info_dict['protocol'] = protocol
67
6ae27bed 68 # 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 69 # return FFmpegFD
12b84ac8 70
52a8a1e1 71 downloaders = params.get('external_downloader')
72 external_downloader = (
73 downloaders if isinstance(downloaders, compat_str)
74 else downloaders.get(shorten_protocol_name(protocol, True), downloaders.get('default')))
75 if external_downloader and external_downloader.lower() == 'native':
76 external_downloader = 'native'
77
78 if external_downloader not in (None, 'native'):
222516d9 79 ed = get_external_downloader(external_downloader)
7f7de7f9 80 if ed.can_download(info_dict, external_downloader):
222516d9
PH
81 return ed
82
5219cb3e 83 if protocol.startswith('m3u8'):
84 if info_dict.get('is_live'):
85 return FFmpegFD
52a8a1e1 86 elif external_downloader == 'native':
87 return HlsFD
5219cb3e 88 elif _get_real_downloader(info_dict, 'frag_urls', params, None):
89 return HlsFD
90 elif params.get('hls_prefer_native') is True:
91 return HlsFD
92 elif params.get('hls_prefer_native') is False:
93 return FFmpegFD
bf09af3a 94
5219cb3e 95 return PROTOCOL_MAP.get(protocol, default)
a055469f 96
14d4e90e
PH
97
98__all__ = [
14d4e90e 99 'FileDownloader',
52a8a1e1 100 'get_suitable_downloader',
101 'shorten_protocol_name',
14d4e90e 102]