使用 FFMPEG Python 解码实时流 [已关闭]

decoding live stream using ffmpeg python [closed]

提问人:Anurag Mishra 提问时间:11/8/2023 最后编辑:user16217248Anurag Mishra 更新时间:11/19/2023 访问量:54

问:


这个问题似乎与特定的编程问题、软件算法或程序员主要使用的软件工具无关。如果您认为该问题在另一个 Stack Exchange 站点上是主题,您可以发表评论以解释在哪里可以回答该问题。

14天前关闭。

这篇文章在 5 天前被编辑并提交审核,未能重新打开帖子:

原始关闭原因未解决

我正在尝试使用 ffmpeg python 解码 H264 视频流。我的代码正在解码并显示第一帧(关键帧),但对于后续帧,它给出了异常:“打开输入时出错:处理输入时发现无效数据

打开输入文件 pipe:0 时出错。

打开输入文件时出错:处理输入时发现无效数据”

这是我接收编码数据和解码的代码:

import socket
import struct
import cv2
import numpy as np
import os
import subprocess
import ffmpeg
import select


def display_h264_from_bytes(h264_data,sps,pps):
    ffmpeg_cmd = [
        'ffmpeg',
        '-probesize', '1000000',  # Increase probesize for more accurate analysis
        '-analyzeduration', '10000',
        '-c:v', 'h264',
        '-i', 'pipe:0',
        '-c:v', 'mjpeg',
        '-f', 'image2pipe',
        'pipe:1'
    ]


    process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)

    try:
        print("sps is : ",sps)
        print("pps is : ",pps)
        # Provide SPS and PPS along with the H.264 data to the FFmpeg subprocess
        input_data = sps + pps + h264_data
        output, _ = process.communicate(input=input_data)
        nparr = np.frombuffer(output, dtype=np.uint8)
        frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
        cv2.imshow('H.264 Video', frame)
        print("frame has been displayed :",frame)
        cv2.waitKey(1)
        print("after wait key")
        #cv2.destroyAllWindows()
        print("destroyed windows")
    except Exception as e:
        print("exception is ", e)


def extract_headers(h264_data,sequence_number):
    print("sequence_number  :: ",sequence_number)
    headers = {'SPS': b'', 'PPS': b''}
    start = 0
    end = 0  # Initialize end variable

    while start < len(h264_data):
        start_code = h264_data.find(b'\x00\x00\x00\x01', start)
        if start_code == -1:
            break

        end = h264_data.find(b'\x00\x00\x00\x01', start_code + 1)
        if end == -1:
            end = len(h264_data)

        nal_type = h264_data[start_code + 4] & 0x1F
        if nal_type == 7:  # SPS NAL unit
            print("SPS NAL unit")
            headers['SPS'] = h264_data[start_code:end]
        elif nal_type == 8:  # PPS NAL unit
            print("PPS NAL unit")
            headers['PPS'] = h264_data[start_code:end]
        elif nal_type == 5:
            print("IDR Frame (I-frame)")
        elif nal_type == 1:
            print("Non-IDR Frame (P-frame)")
        elif nal_type == 6:
            print("SEI NAL Unit")
        elif nal_type == 9:
            print("AUD NAL Unit")


        start = end

    return headers

def receive_image_data():
    # Configuration
    server_host = '0.0.0.0'  # Listen on all available network interfaces
    server_port = 33333  # Replace with the desired port number
    # Specify the output directory for JPEG images

    # Socket configuration
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server_socket.bind((server_host, server_port))

    # Timeout for incomplete sequences (in seconds)
    sequence_timeout = 30
    SPS = ""
    PPS = ""
    # Variables to keep track of received chunks
    sequence_number = -1
    received_chunks = {}


    try:
#        print("udp server starting")
        while True:
            data, client_address = server_socket.recvfrom(65536)  # Adjust the buffer size as needed
            header_size = 12  # Size of the header (3 integers, each 4 bytes)

            # Unpack the header
            sequence_number, chunk_number, total_chunks = struct.unpack('!III', data[:header_size])

            # Extract the data part (chunk) from the received packet
            chunk_data = data[header_size:]

            if sequence_number not in received_chunks:
                received_chunks[sequence_number] = {}

            received_chunks[sequence_number][chunk_number] = chunk_data

            # Check if we have received all chunks for the current sequence
            if len(received_chunks[sequence_number]) == total_chunks:
                # Reconstruct the complete data from received chunks
                complete_data = b''.join(received_chunks[sequence_number][i] for i in range(total_chunks))
                print("complete data is : ",complete_data)
                if sequence_number == 1:
                    try:
                        extracted_headers = extract_headers(complete_data,sequence_number)
                        SPS = extracted_headers['SPS']
                        PPS = extracted_headers['PPS']
                    except Exception as e:
                        print("exception is : ",e)
                else:
                    display_h264_from_bytes(complete_data,SPS,PPS)

    except Exception as e:
        print("exception is as eee : ",e)

    finally:
        # Release resources
        server_socket.close()
        cv2.destroyAllWindows()

if __name__ == '__main__':
    receive_image_data()
FFMPEG 视频 H.264 实时流 编解码器

评论


答: 暂无答案