79461313

Date: 2025-02-23 13:43:11
Score: 1.5
Natty:
Report link

If anyone is trying to use @Rotem's answer for h.265 security camera LAN video and needs low latency, this might help (although it might be better to use Qt6, because apparently ffmpeg has already been incorporated into the multimedia backend):

import cv2
import numpy as np
import subprocess
import json

# Use local RTSP Stream for testing
in_stream = 'rtsp://user:[email protected]:554/live/0/main' + '.h265'

# "ffplay -loglevel error -hide_banner -af \"volume=0.0\" -flags low_delay -vf setpts=0 -tune zerolatency
# -probesize 32 -rtsp_transport tcp rtsp://user:[email protected]:554/live/0/main -left 0 -top 50 -x 400 -y 225"

probe_command = ['ffprobe.exe',
                 '-loglevel', 'error',      # Log level
                 '-rtsp_transport', 'tcp',  # Force TCP (for testing)]
                 '-select_streams', 'v:0',  # Select only video stream 0.
                 '-show_entries', 'stream=width,height', # Select only width and height entries
                 '-of', 'json',             # Get output in JSON format
                 in_stream]

# Read video width, height using FFprobe:
p0 = subprocess.Popen(probe_command, stdout=subprocess.PIPE)
probe_str = p0.communicate()[0] # Reading content of p0.stdout (output of FFprobe) as string
p0.wait()
probe_dct = json.loads(probe_str) # Convert string from JSON format to dictonary.

# Get width and height from the dictonary
width = probe_dct['streams'][0]['width']
height = probe_dct['streams'][0]['height']

# if False:
#     # Read video width, height and framerate using OpenCV (use it if you don't know the size of the video frames).

#     # Use public RTSP Streaming for testing:
#     cap = cv2.VideoCapture(in_stream)

#     framerate = cap.get(5) #frame rate

#     # Get resolution of input video
#     width  = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
#     height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

#     # Release VideoCapture - it was used just for getting video resolution
#     cap.release()
# else:
#     # Set the size here, if video frame size is known
#     width = 240
#     height = 160

command = ['ffmpeg.exe', # Using absolute path for example (in Linux replacing 'C:/ffmpeg/bin/ffmpeg.exe' with 'ffmpeg' supposes to work).
           '-hide_banner',             # Hide banner
           '-rtsp_transport', 'tcp',   # Force TCP (for testing)
           '-flags', 'low_delay',      # Low delay is needed for real-time video streaming.
           '-analyzeduration', '0',    # No analysis is needed for real-time video streaming.
           #'-fflags', 'nobuffer',     # No buffer is needed for real-time video streaming.
           #'-max_delay', '30000000',  # 30 seconds (sometimes needed because the stream is from the web).
           '-i', in_stream,            # '-i', 'input.h265',
           '-f', 'rawvideo',           # Video format is raw video
           '-pix_fmt', 'bgr24',        # bgr24 pixel format matches OpenCV default pixels format.
           '-an', 'pipe:'
           ]               # Drop frames if the consuming process is too slow.

# Open sub-process that gets in_stream as input and uses stdout as an output PIPE.
ffmpeg_process = subprocess.Popen(command, stdout=subprocess.PIPE)

while True:
    # Read width*height*3 bytes from stdout (1 frame)
    raw_frame = ffmpeg_process.stdout.read(width*height*3)

    if len(raw_frame) != (width*height*3):
        print('Error reading frame!!!')  # Break the loop in case of an error (too few bytes were read).
        break

    # Convert the bytes read into a NumPy array, and reshape it to video frame dimensions
    frame = np.frombuffer(raw_frame, np.uint8).reshape((height, width, 3))

    # Show the video frame
    cv2.imshow('image', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

ffmpeg_process.stdout.close()  # Closing stdout terminates FFmpeg sub-process.
ffmpeg_process.wait()  # Wait for FFmpeg sub-process to finish

cv2.destroyAllWindows()
Reasons:
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Rotem's
  • Low reputation (1):
Posted by: R R