aboutsummaryrefslogtreecommitdiffstats
path: root/yt_dlp/downloader
diff options
context:
space:
mode:
Diffstat (limited to 'yt_dlp/downloader')
-rw-r--r--yt_dlp/downloader/__init__.py33
-rw-r--r--yt_dlp/downloader/dash.py4
-rw-r--r--yt_dlp/downloader/external.py19
-rw-r--r--yt_dlp/downloader/hls.py4
4 files changed, 47 insertions, 13 deletions
diff --git a/yt_dlp/downloader/__init__.py b/yt_dlp/downloader/__init__.py
index c2e155c0a..ceb075472 100644
--- a/yt_dlp/downloader/__init__.py
+++ b/yt_dlp/downloader/__init__.py
@@ -1,5 +1,6 @@
from __future__ import unicode_literals
+from ..compat import compat_str
from ..utils import (
determine_protocol,
)
@@ -42,6 +43,23 @@ PROTOCOL_MAP = {
}
+def shorten_protocol_name(proto, simplify=False):
+ short_protocol_names = {
+ 'm3u8_native': 'm3u8_n',
+ 'http_dash_segments': 'dash',
+ 'niconico_dmc': 'dmc',
+ }
+ if simplify:
+ short_protocol_names.update({
+ 'https': 'http',
+ 'ftps': 'ftp',
+ 'm3u8_native': 'm3u8',
+ 'm3u8_frag_urls': 'm3u8',
+ 'dash_frag_urls': 'dash',
+ })
+ return short_protocol_names.get(proto, proto)
+
+
def get_suitable_downloader(info_dict, params={}, default=HttpFD):
"""Get the downloader class that can handle the info dict."""
protocol = determine_protocol(info_dict)
@@ -50,8 +68,14 @@ def get_suitable_downloader(info_dict, params={}, default=HttpFD):
# 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):
# return FFmpegFD
- external_downloader = params.get('external_downloader')
- if external_downloader is not None:
+ downloaders = params.get('external_downloader')
+ external_downloader = (
+ downloaders if isinstance(downloaders, compat_str)
+ else downloaders.get(shorten_protocol_name(protocol, True), downloaders.get('default')))
+ if external_downloader and external_downloader.lower() == 'native':
+ external_downloader = 'native'
+
+ if external_downloader not in (None, 'native'):
ed = get_external_downloader(external_downloader)
if ed.can_download(info_dict, external_downloader):
return ed
@@ -59,6 +83,8 @@ def get_suitable_downloader(info_dict, params={}, default=HttpFD):
if protocol.startswith('m3u8'):
if info_dict.get('is_live'):
return FFmpegFD
+ elif external_downloader == 'native':
+ return HlsFD
elif _get_real_downloader(info_dict, 'frag_urls', params, None):
return HlsFD
elif params.get('hls_prefer_native') is True:
@@ -70,6 +96,7 @@ def get_suitable_downloader(info_dict, params={}, default=HttpFD):
__all__ = [
- 'get_suitable_downloader',
'FileDownloader',
+ 'get_suitable_downloader',
+ 'shorten_protocol_name',
]
diff --git a/yt_dlp/downloader/dash.py b/yt_dlp/downloader/dash.py
index 2f29ff8f2..65dc69f7e 100644
--- a/yt_dlp/downloader/dash.py
+++ b/yt_dlp/downloader/dash.py
@@ -20,7 +20,7 @@ from ..utils import (
class DashSegmentsFD(FragmentFD):
"""
Download segments in a DASH manifest. External downloaders can take over
- the fragment downloads by supporting the 'frag_urls' protocol
+ the fragment downloads by supporting the 'dash_frag_urls' protocol
"""
FD_NAME = 'dashsegments'
@@ -30,7 +30,7 @@ class DashSegmentsFD(FragmentFD):
fragments = info_dict['fragments'][:1] if self.params.get(
'test', False) else info_dict['fragments']
- real_downloader = _get_real_downloader(info_dict, 'frag_urls', self.params, None)
+ real_downloader = _get_real_downloader(info_dict, 'dash_frag_urls', self.params, None)
ctx = {
'filename': filename,
diff --git a/yt_dlp/downloader/external.py b/yt_dlp/downloader/external.py
index 63e430ac9..ea2e6eb12 100644
--- a/yt_dlp/downloader/external.py
+++ b/yt_dlp/downloader/external.py
@@ -81,11 +81,15 @@ class ExternalFD(FileDownloader):
@property
def exe(self):
- return self.params.get('external_downloader')
+ return self.get_basename()
@classmethod
def available(cls, path=None):
- return check_executable(path or cls.get_basename(), [cls.AVAILABLE_OPT])
+ path = check_executable(path or cls.get_basename(), [cls.AVAILABLE_OPT])
+ if path:
+ cls.exe = path
+ return path
+ return False
@classmethod
def supports(cls, info_dict):
@@ -259,7 +263,7 @@ class WgetFD(ExternalFD):
class Aria2cFD(ExternalFD):
AVAILABLE_OPT = '-v'
- SUPPORTED_PROTOCOLS = ('http', 'https', 'ftp', 'ftps', 'frag_urls')
+ SUPPORTED_PROTOCOLS = ('http', 'https', 'ftp', 'ftps', 'dash_frag_urls', 'm3u8_frag_urls')
@staticmethod
def supports_manifest(manifest):
@@ -310,9 +314,11 @@ class Aria2cFD(ExternalFD):
class HttpieFD(ExternalFD):
+ AVAILABLE_OPT = '--version'
+
@classmethod
def available(cls, path=None):
- return check_executable(path or 'http', ['--version'])
+ return ExternalFD.available(cls, path or 'http')
def _make_cmd(self, tmpfilename, info_dict):
cmd = ['http', '--download', '--output', tmpfilename, info_dict['url']]
@@ -327,7 +333,8 @@ class FFmpegFD(ExternalFD):
SUPPORTED_PROTOCOLS = ('http', 'https', 'ftp', 'ftps', 'm3u8', 'rtsp', 'rtmp', 'mms')
@classmethod
- def available(cls, path=None): # path is ignored for ffmpeg
+ def available(cls, path=None):
+ # TODO: Fix path for ffmpeg
return FFmpegPostProcessor().available
def _call_downloader(self, tmpfilename, info_dict):
@@ -484,4 +491,4 @@ def get_external_downloader(external_downloader):
downloader . """
# Drop .exe extension on Windows
bn = os.path.splitext(os.path.basename(external_downloader))[0]
- return _BY_NAME[bn]
+ return _BY_NAME.get(bn)
diff --git a/yt_dlp/downloader/hls.py b/yt_dlp/downloader/hls.py
index d09bfa3aa..67b09144d 100644
--- a/yt_dlp/downloader/hls.py
+++ b/yt_dlp/downloader/hls.py
@@ -32,7 +32,7 @@ from ..utils import (
class HlsFD(FragmentFD):
"""
Download segments in a m3u8 manifest. External downloaders can take over
- the fragment downloads by supporting the 'frag_urls' protocol and
+ the fragment downloads by supporting the 'm3u8_frag_urls' protocol and
re-defining 'supports_manifest' function
"""
@@ -95,7 +95,7 @@ class HlsFD(FragmentFD):
# fd.add_progress_hook(ph)
return fd.real_download(filename, info_dict)
- real_downloader = _get_real_downloader(info_dict, 'frag_urls', self.params, None)
+ real_downloader = _get_real_downloader(info_dict, 'm3u8_frag_urls', self.params, None)
if real_downloader and not real_downloader.supports_manifest(s):
real_downloader = None
if real_downloader: