diff --git a/youtube_dl/downloader/__init__.py b/youtube_dl/downloader/__init__.py index daa5498d4..0b65aa3e2 100644 --- a/youtube_dl/downloader/__init__.py +++ b/youtube_dl/downloader/__init__.py @@ -6,6 +6,7 @@ from .hls import HlsFD from .http import HttpFD from .rtmp import RtmpFD from .dash import DashSegmentsFD +from .rtsp import RtspFD from .external import ( get_external_downloader, FFmpegFD, @@ -19,8 +20,8 @@ PROTOCOL_MAP = { 'rtmp': RtmpFD, 'm3u8_native': HlsFD, 'm3u8': FFmpegFD, - 'mms': FFmpegFD, - 'rtsp': FFmpegFD, + 'mms': RtspFD, + 'rtsp': RtspFD, 'f4m': F4mFD, 'http_dash_segments': DashSegmentsFD, } diff --git a/youtube_dl/downloader/rtsp.py b/youtube_dl/downloader/rtsp.py new file mode 100644 index 000000000..3eb29526c --- /dev/null +++ b/youtube_dl/downloader/rtsp.py @@ -0,0 +1,45 @@ +from __future__ import unicode_literals + +import os +import subprocess + +from .common import FileDownloader +from ..utils import ( + check_executable, + encodeFilename, +) + + +class RtspFD(FileDownloader): + def real_download(self, filename, info_dict): + url = info_dict['url'] + self.report_destination(filename) + tmpfilename = self.temp_name(filename) + + if check_executable('mplayer', ['-h']): + args = [ + 'mplayer', '-really-quiet', '-vo', 'null', '-vc', 'dummy', + '-dumpstream', '-dumpfile', tmpfilename, url] + elif check_executable('mpv', ['-h']): + args = [ + 'mpv', '-really-quiet', '--vo=null', '--stream-dump=' + tmpfilename, url] + else: + self.report_error('MMS or RTSP download detected but neither "mplayer" nor "mpv" could be run. Please install any.') + return False + + retval = subprocess.call(args) + if retval == 0: + fsize = os.path.getsize(encodeFilename(tmpfilename)) + self.to_screen('\r[%s] %s bytes' % (args[0], fsize)) + self.try_rename(tmpfilename, filename) + self._hook_progress({ + 'downloaded_bytes': fsize, + 'total_bytes': fsize, + 'filename': filename, + 'status': 'finished', + }) + return True + else: + self.to_stderr('\n') + self.report_error('%s exited with code %d' % (args[0], retval)) + return False