I`m trying to handle stream as individual frames using streamlink
args = ['streamlink', stream_url, "best", "-O"]
process = subprocess.Popen(args, stdout=subprocess.PIPE)
while True:
frame_size = width * height * 3
in_frame = streamlink.stdout.read(frame_size)
if in_frame is None:
break
#cv2.imwrite(f'frames/{i}.jpg', in_frame)
#do anything with in_frame
But getting images that looks like white noise. I think it because stream also contain audio in bytes. Then i try to pipe it to ffmpeg but cant get decoded bytes out of ffmpeg
args = (
ffmpeg.input('pipe:')
.filter('fps', fps=1)
.output('pipe:', vframes=1, format='image2', vcodec='mjpeg')
.compile()
)
process2 = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=None)
buff = process1.stdout.read(n)
process2.stdin.write(buff)
frame = process2.stdout.read(n)
When i try to smt like that all my script hang and waiting something. How to properly handle stream from streamlink as individual frames. To get frame as bytes or else? Thank you.
Instead of piping the data to FFmpeg, you may pass the URL as input argument to FFmpeg.
Get the stream URL from the WEB site URL:
Use FFprobe for getting the video resolution (if required):
Execute FFmpeg sub-process with URL as input and raw (BGR) output format:
Read frames from PIPE, convert to NumPy array, reshape and display:
Complete code sample:
There is a simpler solution using
cv2.VideoCapture
:Update:
Piping from Streamlink sub-process to FFmpeg sub-process:
Assume you have to read the stream from stdout pipe of Streamlink and write it to stdin pipe of FFmpeg:
Start Streamlink sub-process (use
-O
argument for piping):Implement a thread that read chunks from stdout pipe of Streamlink and write to FFmpeg stdin pipe:
Execute FFmpeg sub-process with input pipe and output pipe:
Create and start the thread:
Complete code sample:
Notes:
r'c:\Program Files (x86)\Streamlink\bin\streamlink.exe'
after installing Streamlink).