X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;ds=sidebyside;f=youtube_dl%2Fdownloader%2Fexternal.py;h=3a73cee1c7c09f6e9350e13b9a041edfdd4a517a;hb=0a5685b26fae0940f14cb063a6e4fc6986f9c124;hp=a4fdf1af8053a2d3215cdbcc2f2333ba61d7807c;hpb=f34294fa0c0097cea7f6388d5d691d5a54950491;p=youtube-dl diff --git a/youtube_dl/downloader/external.py b/youtube_dl/downloader/external.py index a4fdf1af8..3a73cee1c 100644 --- a/youtube_dl/downloader/external.py +++ b/youtube_dl/downloader/external.py @@ -6,8 +6,8 @@ import sys import re from .common import FileDownloader -from ..postprocessor.ffmpeg import FFmpegPostProcessor -from ..compat import compat_str +from ..compat import compat_setenv +from ..postprocessor.ffmpeg import FFmpegPostProcessor, EXT_TO_OUT_FORMATS from ..utils import ( cli_option, cli_valueless_option, @@ -53,12 +53,16 @@ class ExternalFD(FileDownloader): @classmethod def available(cls): - return check_executable(cls.get_basename(), cls.available_opt) + return check_executable(cls.get_basename(), [cls.AVAILABLE_OPT]) @classmethod def supports(cls, info_dict): return info_dict['protocol'] in ('http', 'https', 'ftp', 'ftps') + @classmethod + def can_download(cls, info_dict): + return cls.available() and cls.supports(info_dict) + def _option(self, command_option, param): return cli_option(self.params, command_option, param) @@ -86,7 +90,7 @@ class ExternalFD(FileDownloader): class CurlFD(ExternalFD): - available_opt = ['-V'] + AVAILABLE_OPT = '-V' def _make_cmd(self, tmpfilename, info_dict): cmd = [self.exe, '--location', '-o', tmpfilename] @@ -101,7 +105,7 @@ class CurlFD(ExternalFD): class AxelFD(ExternalFD): - available_opt = ['-V'] + AVAILABLE_OPT = '-V' def _make_cmd(self, tmpfilename, info_dict): cmd = [self.exe, '-o', tmpfilename] @@ -113,7 +117,7 @@ class AxelFD(ExternalFD): class WgetFD(ExternalFD): - available_opt = ['--version'] + AVAILABLE_OPT = '--version' def _make_cmd(self, tmpfilename, info_dict): cmd = [self.exe, '-O', tmpfilename, '-nv', '--no-cookies'] @@ -128,7 +132,7 @@ class WgetFD(ExternalFD): class Aria2cFD(ExternalFD): - available_opt = ['-v'] + AVAILABLE_OPT = '-v' def _make_cmd(self, tmpfilename, info_dict): cmd = [self.exe, '-c'] @@ -171,16 +175,21 @@ class FFmpegFD(ExternalFD): def _call_downloader(self, tmpfilename, info_dict): url = info_dict['url'] ffpp = FFmpegPostProcessor(downloader=self) + if not ffpp.available: + self.report_error('m3u8 download detected but ffmpeg or avconv could not be found. Please install one.') + return False ffpp.check_version() args = [ffpp.executable, '-y'] - start_time = info_dict.get('start_time') or 0 - if start_time: - args += ['-ss', compat_str(start_time)] - end_time = info_dict.get('end_time') - if end_time: - args += ['-t', compat_str(end_time - start_time)] + args += self._configuration_args() + + # start_time = info_dict.get('start_time') or 0 + # if start_time: + # args += ['-ss', compat_str(start_time)] + # end_time = info_dict.get('end_time') + # if end_time: + # args += ['-t', compat_str(end_time - start_time)] if info_dict['http_headers'] and re.match(r'^https?://', url): # Trailing \r\n after each HTTP header is important to prevent warning from ffmpeg/avconv: @@ -190,21 +199,60 @@ class FFmpegFD(ExternalFD): '-headers', ''.join('%s: %s\r\n' % (key, val) for key, val in headers.items())] + env = None + proxy = self.params.get('proxy') + if proxy: + if not re.match(r'^[\da-zA-Z]+://', proxy): + proxy = 'http://%s' % proxy + # Since December 2015 ffmpeg supports -http_proxy option (see + # http://git.videolan.org/?p=ffmpeg.git;a=commit;h=b4eb1f29ebddd60c41a2eb39f5af701e38e0d3fd) + # We could switch to the following code if we are able to detect version properly + # args += ['-http_proxy', proxy] + env = os.environ.copy() + compat_setenv('HTTP_PROXY', proxy, env=env) + + protocol = info_dict.get('protocol') + + if protocol == 'rtmp': + player_url = info_dict.get('player_url') + page_url = info_dict.get('page_url') + app = info_dict.get('app') + play_path = info_dict.get('play_path') + tc_url = info_dict.get('tc_url') + flash_version = info_dict.get('flash_version') + live = info_dict.get('rtmp_live', False) + if player_url is not None: + args += ['-rtmp_swfverify', player_url] + if page_url is not None: + args += ['-rtmp_pageurl', page_url] + if app is not None: + args += ['-rtmp_app', app] + if play_path is not None: + args += ['-rtmp_playpath', play_path] + if tc_url is not None: + args += ['-rtmp_tcurl', tc_url] + if flash_version is not None: + args += ['-rtmp_flashver', flash_version] + if live: + args += ['-rtmp_live', 'live'] + args += ['-i', url, '-c', 'copy'] - if info_dict.get('protocol') == 'm3u8': - if self.params.get('hls_use_mpegts', False): + if protocol in ('m3u8', 'm3u8_native'): + if self.params.get('hls_use_mpegts', False) or tmpfilename == '-': args += ['-f', 'mpegts'] else: args += ['-f', 'mp4', '-bsf:a', 'aac_adtstoasc'] + elif protocol == 'rtmp': + args += ['-f', 'flv'] else: - args += ['-f', info_dict['ext']] + args += ['-f', EXT_TO_OUT_FORMATS.get(info_dict['ext'], info_dict['ext'])] args = [encodeArgument(opt) for opt in args] args.append(encodeFilename(ffpp._ffmpeg_filename_argument(tmpfilename), True)) self._debug_cmd(args) - proc = subprocess.Popen(args, stdin=subprocess.PIPE) + proc = subprocess.Popen(args, stdin=subprocess.PIPE, env=env) try: retval = proc.wait() except KeyboardInterrupt: