|
@ -1,3 +1,5 @@ |
|
|
|
|
|
from __future__ import unicode_literals |
|
|
|
|
|
|
|
|
import os |
|
|
import os |
|
|
import re |
|
|
import re |
|
|
import subprocess |
|
|
import subprocess |
|
@ -22,7 +24,7 @@ class RtmpFD(FileDownloader): |
|
|
proc_stderr_closed = False |
|
|
proc_stderr_closed = False |
|
|
while not proc_stderr_closed: |
|
|
while not proc_stderr_closed: |
|
|
# read line from stderr |
|
|
# read line from stderr |
|
|
line = u'' |
|
|
|
|
|
|
|
|
line = '' |
|
|
while True: |
|
|
while True: |
|
|
char = proc.stderr.read(1) |
|
|
char = proc.stderr.read(1) |
|
|
if not char: |
|
|
if not char: |
|
@ -46,7 +48,7 @@ class RtmpFD(FileDownloader): |
|
|
data_len = None |
|
|
data_len = None |
|
|
if percent > 0: |
|
|
if percent > 0: |
|
|
data_len = int(downloaded_data_len * 100 / percent) |
|
|
data_len = int(downloaded_data_len * 100 / percent) |
|
|
data_len_str = u'~' + format_bytes(data_len) |
|
|
|
|
|
|
|
|
data_len_str = '~' + format_bytes(data_len) |
|
|
self.report_progress(percent, data_len_str, speed, eta) |
|
|
self.report_progress(percent, data_len_str, speed, eta) |
|
|
cursor_in_new_line = False |
|
|
cursor_in_new_line = False |
|
|
self._hook_progress({ |
|
|
self._hook_progress({ |
|
@ -76,12 +78,12 @@ class RtmpFD(FileDownloader): |
|
|
}) |
|
|
}) |
|
|
elif self.params.get('verbose', False): |
|
|
elif self.params.get('verbose', False): |
|
|
if not cursor_in_new_line: |
|
|
if not cursor_in_new_line: |
|
|
self.to_screen(u'') |
|
|
|
|
|
|
|
|
self.to_screen('') |
|
|
cursor_in_new_line = True |
|
|
cursor_in_new_line = True |
|
|
self.to_screen(u'[rtmpdump] '+line) |
|
|
|
|
|
|
|
|
self.to_screen('[rtmpdump] '+line) |
|
|
proc.wait() |
|
|
proc.wait() |
|
|
if not cursor_in_new_line: |
|
|
if not cursor_in_new_line: |
|
|
self.to_screen(u'') |
|
|
|
|
|
|
|
|
self.to_screen('') |
|
|
return proc.returncode |
|
|
return proc.returncode |
|
|
|
|
|
|
|
|
url = info_dict['url'] |
|
|
url = info_dict['url'] |
|
@ -102,7 +104,7 @@ class RtmpFD(FileDownloader): |
|
|
try: |
|
|
try: |
|
|
subprocess.call(['rtmpdump', '-h'], stdout=(open(os.path.devnull, 'w')), stderr=subprocess.STDOUT) |
|
|
subprocess.call(['rtmpdump', '-h'], stdout=(open(os.path.devnull, 'w')), stderr=subprocess.STDOUT) |
|
|
except (OSError, IOError): |
|
|
except (OSError, IOError): |
|
|
self.report_error(u'RTMP download detected but "rtmpdump" could not be run') |
|
|
|
|
|
|
|
|
self.report_error('RTMP download detected but "rtmpdump" could not be run') |
|
|
return False |
|
|
return False |
|
|
|
|
|
|
|
|
# Download using rtmpdump. rtmpdump returns exit code 2 when |
|
|
# Download using rtmpdump. rtmpdump returns exit code 2 when |
|
@ -150,7 +152,7 @@ class RtmpFD(FileDownloader): |
|
|
shell_quote = lambda args: ' '.join(map(pipes.quote, str_args)) |
|
|
shell_quote = lambda args: ' '.join(map(pipes.quote, str_args)) |
|
|
except ImportError: |
|
|
except ImportError: |
|
|
shell_quote = repr |
|
|
shell_quote = repr |
|
|
self.to_screen(u'[debug] rtmpdump command line: ' + shell_quote(str_args)) |
|
|
|
|
|
|
|
|
self.to_screen('[debug] rtmpdump command line: ' + shell_quote(str_args)) |
|
|
|
|
|
|
|
|
RD_SUCCESS = 0 |
|
|
RD_SUCCESS = 0 |
|
|
RD_FAILED = 1 |
|
|
RD_FAILED = 1 |
|
@ -160,12 +162,12 @@ class RtmpFD(FileDownloader): |
|
|
retval = run_rtmpdump(args) |
|
|
retval = run_rtmpdump(args) |
|
|
|
|
|
|
|
|
if retval == RD_NO_CONNECT: |
|
|
if retval == RD_NO_CONNECT: |
|
|
self.report_error(u'[rtmpdump] Could not connect to RTMP server.') |
|
|
|
|
|
|
|
|
self.report_error('[rtmpdump] Could not connect to RTMP server.') |
|
|
return False |
|
|
return False |
|
|
|
|
|
|
|
|
while (retval == RD_INCOMPLETE or retval == RD_FAILED) and not test: |
|
|
while (retval == RD_INCOMPLETE or retval == RD_FAILED) and not test: |
|
|
prevsize = os.path.getsize(encodeFilename(tmpfilename)) |
|
|
prevsize = os.path.getsize(encodeFilename(tmpfilename)) |
|
|
self.to_screen(u'[rtmpdump] %s bytes' % prevsize) |
|
|
|
|
|
|
|
|
self.to_screen('[rtmpdump] %s bytes' % prevsize) |
|
|
time.sleep(5.0) # This seems to be needed |
|
|
time.sleep(5.0) # This seems to be needed |
|
|
retval = run_rtmpdump(basic_args + ['-e'] + [[], ['-k', '1']][retval == RD_FAILED]) |
|
|
retval = run_rtmpdump(basic_args + ['-e'] + [[], ['-k', '1']][retval == RD_FAILED]) |
|
|
cursize = os.path.getsize(encodeFilename(tmpfilename)) |
|
|
cursize = os.path.getsize(encodeFilename(tmpfilename)) |
|
@ -173,12 +175,12 @@ class RtmpFD(FileDownloader): |
|
|
break |
|
|
break |
|
|
# Some rtmp streams seem abort after ~ 99.8%. Don't complain for those |
|
|
# Some rtmp streams seem abort after ~ 99.8%. Don't complain for those |
|
|
if prevsize == cursize and retval == RD_INCOMPLETE and cursize > 1024: |
|
|
if prevsize == cursize and retval == RD_INCOMPLETE and cursize > 1024: |
|
|
self.to_screen(u'[rtmpdump] Could not download the whole video. This can happen for some advertisements.') |
|
|
|
|
|
|
|
|
self.to_screen('[rtmpdump] Could not download the whole video. This can happen for some advertisements.') |
|
|
retval = RD_SUCCESS |
|
|
retval = RD_SUCCESS |
|
|
break |
|
|
break |
|
|
if retval == RD_SUCCESS or (test and retval == RD_INCOMPLETE): |
|
|
if retval == RD_SUCCESS or (test and retval == RD_INCOMPLETE): |
|
|
fsize = os.path.getsize(encodeFilename(tmpfilename)) |
|
|
fsize = os.path.getsize(encodeFilename(tmpfilename)) |
|
|
self.to_screen(u'[rtmpdump] %s bytes' % fsize) |
|
|
|
|
|
|
|
|
self.to_screen('[rtmpdump] %s bytes' % fsize) |
|
|
self.try_rename(tmpfilename, filename) |
|
|
self.try_rename(tmpfilename, filename) |
|
|
self._hook_progress({ |
|
|
self._hook_progress({ |
|
|
'downloaded_bytes': fsize, |
|
|
'downloaded_bytes': fsize, |
|
@ -188,6 +190,6 @@ class RtmpFD(FileDownloader): |
|
|
}) |
|
|
}) |
|
|
return True |
|
|
return True |
|
|
else: |
|
|
else: |
|
|
self.to_stderr(u"\n") |
|
|
|
|
|
self.report_error(u'rtmpdump exited with code %d' % retval) |
|
|
|
|
|
|
|
|
self.to_stderr('\n') |
|
|
|
|
|
self.report_error('rtmpdump exited with code %d' % retval) |
|
|
return False |
|
|
return False |