1. FFmpeg安装完成后
测试ffmpeg
1 2 3 4 5 |
# 查看版本 ffmpeg -version # 查看硬件加速器,看是不是显示cuda ffmpeg -hwaccels |
2. 本地将USB摄像头编码成RTSP视频流(有安防相机可忽略这一步)
1 2 3 |
# libx265好于libx264 ffmpeg -f dshow -i video="HIK 1080P Camera" -vcodec libx265 -preset:v ultrafast -tune:v zerolatency -s 1920x1080 -rtsp_transport udp -max_delay 500000 -f rtsp rtsp://127.0.0.1/test1 |
3. ffmpeg-python解码
https://github.com/kkroening/ffmpeg-python
Conda环境安装ffmpeg-python
增加参数hwaccel=’nvdec’实现硬件解码
单路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import ffmpeg import numpy as np import cv2 url = "rtsp://127.0.0.1/test1" def read_video(): input_args = { "hwaccel": "nvdec", # "vcodec": "h264_cuvid", # "c:v": "h264_cuvid" } output_args = { # "vcodec": "hevc_nvenc", # "c:v": "hevc_nvenc", } out = ( ffmpeg .input(url, rtsp_transport='udp', **input_args) .output('pipe:', format='rawvideo', pix_fmt='bgr24', loglevel="warning", r=25, **output_args) .run_async(pipe_stdout=True) ) print(out) while True: in_bytes = out.stdout.read(height * width * 3) # print(in_bytes) if not in_bytes: break tmp_frame = np.frombuffer(in_bytes, dtype=np.uint8) print(len(tmp_frame)) if tmp_frame.shape[0] != 0: frame = tmp_frame.reshape(height, width, 3) cv2.imshow('test', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break return -1 # ffmpeg read camera probe = ffmpeg.probe(url) print(probe) video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) print(video_stream) width = int(video_stream['width']) height = int(video_stream['height']) print(width) print(height) ret = read_video() |
多路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
import ffmpeg import numpy as np import cv2 import threading # 你的26个RTSP URL列表 urls = [ "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", "rtsp://127.0.0.1/test1", ] def read_video(url, width, height, window_name): out = ( ffmpeg .input(url, rtsp_transport='udp', hwaccel='nvdec', flags2='+export_mvs') .output('pipe:', format='rawvideo', pix_fmt='bgr24', loglevel="warning", r=25) .run_async(pipe_stdout=True) ) while True: in_bytes = out.stdout.read(height * width * 3) if not in_bytes: break frame = np.frombuffer(in_bytes, dtype=np.uint8).reshape(height, width, 3) # print(len(frame)) cv2.imshow(window_name, frame) if cv2.waitKey(1) & 0xFF == ord('q'): break out.stdout.close() out.wait() cv2.destroyAllWindows() def get_video_info(url): probe = ffmpeg.probe(url) video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None) if video_stream: width = int(video_stream['width']) height = int(video_stream['height']) return width, height else: raise ValueError("No video stream found") def process_stream(url, window_name): try: width, height = get_video_info(url) read_video(url, width, height, window_name) except Exception as e: print(f"Error processing {url}: {e}") threads = [] for i, url in enumerate(urls): window_name = f"Stream {i + 1}" thread = threading.Thread(target=process_stream, args=(url, window_name)) threads.append(thread) thread.start() for thread in threads: thread.join() |