我使用python和opencv-python从视频中捕获帧,然后使用ffmpeg命令使用管道推送rtsp流。我可以通过gstreamer和vlc播放rtsp流。然而,显示设备不能解码和播放rtsp流,因为它不能接收SPS和PPS帧。使用wireshark捕获流,发现它不发送sps和pps帧,只发送IDR帧。
关键代码如下。
# ffmpeg command
command = ['ffmpeg',
           '-re',
           '-y',
           '-f', 'rawvideo',
           '-vcodec', 'rawvideo',
           '-pix_fmt', 'bgr24',
           '-s', "{}x{}".format(width, height),
           '-r', str(fps),
           '-i', '-',
           '-c:v', 'libx264',
           '-preset', 'ultrafast',
           '-f', 'rtsp',
           '-flags', 'local_headers', 
           '-rtsp_transport', 'tcp',
           '-muxdelay', '0.1', 
           rtsp_url]
 
p = sp.Popen(command, stdin=sp.PIPE)
 
 
while (cap.isOpened()):
    ret, frame = cap.read()
    if not ret:
        cap = cv2.VideoCapture(video_path)
        continue
    p.stdin.write(frame.tobytes()我可能错过了一些选择吗?
发布于 2021-11-30 21:32:19
尝试添加参数'-bsf:v', 'dump_extra'。
dump_extra 将数据外添加到过滤后的分组的开头,除非所述分组已经完全以拟添加的数据开始。
过滤器应该添加SPS和PPS NAL单元与每一个关键帧。
下面是一个完整的代码示例:
import subprocess as sp
import cv2
rtsp_url = 'rtsp://localhost:31415/live.stream'
video_path = 'input.mp4'
# We have to start the server up first, before the sending client (when using TCP). See: https://trac.ffmpeg.org/wiki/StreamingGuide#Pointtopointstreaming
ffplay_process = sp.Popen(['ffplay', '-rtsp_flags', 'listen', rtsp_url])  # Use FFplay sub-process for receiving the RTSP video.
cap = cv2.VideoCapture(video_path)
width  = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))  # Get video frames width
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # Get video frames height
fps = int(cap.get(cv2.CAP_PROP_FPS))  # Get video framerate
    
# FFmpeg command
command = ['ffmpeg',
           '-re',
           '-y',
           '-f', 'rawvideo',
           '-vcodec', 'rawvideo',
           '-pix_fmt', 'bgr24',
           '-s', "{}x{}".format(width, height),
           '-r', str(fps),
           '-i', '-',
           '-c:v', 'libx264',
           '-preset', 'ultrafast',
           '-f', 'rtsp',
           #'-flags', 'local_headers', 
           '-rtsp_transport', 'tcp',
           '-muxdelay', '0.1',
           '-bsf:v', 'dump_extra',
           rtsp_url]
p = sp.Popen(command, stdin=sp.PIPE)
while (cap.isOpened()):
    ret, frame = cap.read()
    if not ret:
        break
    p.stdin.write(frame.tobytes())
p.stdin.close()  # Close stdin pipe
p.wait()  # Wait for FFmpeg sub-process to finish
ffplay_process.kill()  # Forcefully close FFplay sub-process备注:
'-flags', 'local_headers'在我的FFmpeg版本中不是有效的参数。https://stackoverflow.com/questions/70168829
复制相似问题