4

Using this api I've managed to download stream data, but I can't figure out how to parse it. I've looked at the RMTP format, but it doesn't seem to match.

from livestreamer import Livestreamer

livestreamer = Livestreamer()

# set to a stream that is actually online
plugin = livestreamer.resolve_url("http://twitch.tv/froggen")
streams = plugin.get_streams()
stream = streams['mobile_High']
fd = stream.open()
data = fd.read()

I've uploaded an example of the data here.

Ideally I wouldn't have to parse it as video, I only need the first keyframe as an image. Any help would be greatly appreciated!

Update: Ok, I got OpenCV working, it works for grabbing the first frame of a random video file I had. However, it produced a nonsense image when I used the same code on file with stream data.

doeke
  • 462
  • 5
  • 12
  • I managed to open your file with the OpenCV library (Python code: `capture = cv2.VideoCapture("downloads/( uploadMB.com ) stream.bin")`) I managed to get an image out of it (3 channel, 1280x720), but it looks like a multicolored mess. Are you sure the valid keyframe is in the file? – Igonato Sep 26 '13 at 06:09
  • 1
    I just tried downloading [the first 1 MB of stream data](http://www.uploadmb.com/dw.php?id=1380209204), and using `cv2.VideoCapture`, then `capture.read` but it returns False/None. How did you get an image out of it? – doeke Sep 26 '13 at 15:30

1 Answers1

5

Alright, I figured it out. Made sure to write as binary data, and OpenCV is able to decode the first video frame. The resulting image had R and B channels switched, but that was easily corrected. Downloading about 300 kB seems to be enough to be sure that the full image is there.

import time, Image

import cv2
from livestreamer import Livestreamer

# change to a stream that is actually online
livestreamer = Livestreamer()
plugin = livestreamer.resolve_url("http://twitch.tv/flosd")
streams = plugin.get_streams()
stream = streams['mobile_High']

# download enough data to make sure the first frame is there
fd = stream.open()
data = ''
while len(data) < 3e5:
    data += fd.read()
    time.sleep(0.1)
fd.close()

fname = 'stream.bin'
open(fname, 'wb').write(data)
capture = cv2.VideoCapture(fname)
imgdata = capture.read()[1]
imgdata = imgdata[...,::-1] # BGR -> RGB
img = Image.fromarray(imgdata)
img.save('frame.png')
# img.show()
doeke
  • 462
  • 5
  • 12
  • I'm trying to accomplish the same task but the call to `capture.read()` returns none. I've tried it with your uploaded bin but I get the same None result. Any ideas? – sheitan Nov 19 '13 at 17:45
  • 1
    You can't call read() on the bin file because ffmpeg (the video decoder) is not properly accessible, so opening the file is failing. See http://stackoverflow.com/questions/11699298/opencv-2-4-videocapture-not-working-on-windows and similar. I fixed by downloading and installing opencv from here: http://www.lfd.uci.edu/~gohlke/pythonlibs/ – profesor_tortuga Sep 24 '15 at 16:33