简体   繁体   中英

Speed up video playback from a networked device with camera or IP camera

I'm trying to stream video from my raspberry pi using flask api in python. So that I may process individual frames on my workstation. It is working fine as far as data delivery is concerned. However on client side the process of reading frames introduces a lag of 1-3 seconds that is undesirable in a real time application. I can view the video playback in my web browser without any latency that proves that my raspberry pi and network are innocent . The problem is with the method of reading individual frames from byte stream . Any thoughts about eliminating latency in such an application. Below is my code for client side application. Complete source to a sample application can be found here: https://github.com/shehzi-khan/video-streaming

import cv2
import urllib
import numpy as np

stream = urllib.urlopen('http://192.168.100.128:5000/video_feed')
bytes = ''
while True:
    bytes += stream.read(1024)
    a = bytes.find(b'\xff\xd8')
    b = bytes.find(b'\xff\xd9')
    if a != -1 and b != -1:
        jpg = bytes[a:b+2]
        bytes = bytes[b+2:]
        img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
        cv2.imshow('Video', img)
        if cv2.waitKey(1) == 27:
            exit(0)

Main suggestions:

  • Search end-mark and then search start-mark

  • read more data (eg 64kb)

  • drop other frames and show only last

I can't test it, but here is general code:

import cv2
import urllib
import numpy as np

stream = urllib.urlopen('http://192.168.100.128:5000/video_feed')
bytes = ''
while True:
    buff = stream.read(64 * 1024)
    bytes += buff
    if buff.rfind(b'\xff\xd9') != -1: # buff is smaller than bytes
        endmark = bytes.rfind(b'\xff\xd9') + 2
        startmark = bytes[:endmark - 2].rfind(b'\xff\xd8')

        jpg = bytes[startmark:endmark] # please, check indexes! I could mess up with them.
        bytes = bytes[endmark:]

        img = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
        cv2.imshow('Video', img)
        if cv2.waitKey(1) == 27:
            exit(0)

I can't find how stream.read behave. If he wait until buffer be full, than you need to decrease buffer size. If he just read N bytes OR until end of stream, than it will work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM