Closed mic159 closed 9 years ago
You could try passing the timeout
argument to librtmp.RTMP().
connection = librtmp.RTMP(host, playpath=file, swfurl=SWF_URL, timeout=60)
timeout – int, Timeout the session after num seconds without receiving any data from the server. The default is 30.
EDIT:
librtmp returns FLV data, so video.mp4
should be video.flv
.
with open('video.flv, 'wb') as fle:
size = 0
for block in download_video():
size += len(block)
fle.write(block)
sys.stdout.write('{} \r'.format(size))
@norwack Thanks, increasing the timeout does help and it will now download the whole video. But, it takes ages! running the rtmpdump command is much faster. What can I do to the script to make it just as fast?
I have updated the gist with the timeout increased.
Python:
real 22m13.594s
user 0m2.697s
sys 0m0.852s
rtmpdump:
real 1m49.613s
user 0m0.863s
sys 0m0.789s
The filename on the 'playpath' ends with 'mp4', but you are correct, the container is actually 'flv'. The append option is for when opening the file multiple times, not for every write call.
@mic159 What did you set the timeout to? Try playing around with it a little.
@norwack I set it to 60 like you suggested (check the gist). It seems like it gets a burst of 5MB at the start, then it pauses for 40 seconds then just starts drip feeding the rest of the content at a very slow speed. But with rtmpdump it goes at the full speed the whole time.
@norwack I looked over rtmpdump and my theory is that i need to tell the server to send the whole video in the "buffer" using setBufferTimeMS just like rtmpdump does.
@mic159 Try setting the buffer parameter in librtmp.RTMP().
Something like this:
connection = librtmp.RTMP(host, playpath=file, swfurl=SWF_URL, buffer=30000)
Note that 30000 is the default value, try to play around with it.
@norwack Yes! That works!
But unfortunately it does not seem to let you change it after the stream has started, like what rtmpdump does.
I want to:
def download_video(file, host):
connection = librtmp.RTMP(host, playpath=file)
connection.connect()
stream = connection.create_stream()
# Grab first chunk
data = stream.read(1024 * 2)
yield data
connection.set_option('buffer', int(stream.duration * 1000))
# Read rest of file...
But it has no effect. It seems to have to be set before the create_stream
method is called. like this:
def download_video(file, host):
connection = librtmp.RTMP(host, playpath=file)
connection.connect()
connection.set_option('buffer', 1372137)
stream = connection.create_stream()
# Grab first chunk
data = stream.read(1024 * 2)
yield data
# Read rest of file...
Is there a way to get the duration before reading the first chunk, or to be able to set the option after starting the stream?
I'm unsure, hopefully @chrippa can help out on this.
I've added a option (enabled by default) to RTMP.create_stream
which toggles the same buffer hack used by rtmpdump. You can also set the buffer manually with RTMPStream.update_buffer(ms)
now.
Hi there, i've been trying to download an RTMP stream using librtmp, but it seems to only download the first ~5MB then pauses for a bit and returns success. The same command using
rtmpdump
works just fine.Reproduce: https://gist.github.com/mic159/b71a8efdad7f67916ff0 The
rtmpdump
command will be printed to test with.OS: Ubuntu 14.10 24bit
Could you tell me if I'm doing something wrong?