I would like to create a function that reads frames from an HTTP stream using requests and returns each frame. But because of the fact that the stream reader is based on an iterator object (if I understand correctly), returning a frame is breaking the stream.
The code I am using (works perfectly fine, from this answer):
import cv2
import requests
import numpy as np
r = requests.get('http://roofcam.warwick.ac.uk/cgi-bin/faststream.jpg', stream=True)
if(r.status_code == 200):
    bytes_buffer = bytes()
    for chunk in r.iter_content(chunk_size=1024):
        bytes += chunk
        a = bytes_buffer.find(b'\xff\xd8')
        b = bytes_buffer.find(b'\xff\xd9')
        if a != -1 and b != -1:
            jpg = bytes_buffer[a:b+2]
            bytes_buffer = bytes_buffer[b+2:]
            i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
            cv2.imshow('i', i)
            if cv2.waitKey(1) == 27:
                exit(0)
else:
    print("Received unexpected status code {}".format(r.status_code))
Concept of what I'd like to do (with the return that I'd like to work if it was a while function instead of a for using iterator):
import cv2
import requests
import numpy as np
r = requests.get('http://roofcam.warwick.ac.uk/cgi-bin/faststream.jpg', stream=True)
def get_frame_from_stream(r):
    if(r.status_code == 200):
        bytes_buffer = bytes()
        for chunk in r.iter_content(chunk_size=1024):
            bytes_buffer += chunk
            a = bytes_buffer.find(b'\xff\xd8')
            b = bytes_buffer.find(b'\xff\xd9')
            if a != -1 and b != -1:
                jpg = bytes_buffer[a:b + 2]
                bytes_buffer = bytes_buffer[b + 2:]
                i = cv2.imdecode(np.fromstring(
                    jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
                return i
    else:
        print("Received unexpected status code {}".format(r.status_code))
        return None
while True:
    if img is not None:
        img = get_frame_from_stream(r)
        cv2.imshow('i', img)
        cv2.waitKey(0)
    else:
        break
So basically I'd like to return each frame where the original code is displaying the frame so that I can perform some processing on it. But I don't understand how exactly is the iter_content allowing the original code to work continuously.
(I didn't know how to name the question - will welcome a better title)
 
    