You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Python实现松下DC-FZ82相机WLAN实时画面预览(已解决)

解决松下DC-FZ82相机UDP实时流的Python解析与显示问题

我有一台松下DC-FZ82相机,支持通过自带WLAN传输实时画面。已经能通过Python发送HTTP请求控制相机——比如用http://192.168.54.1/cam.cgi?mode=getstate获取状态,发送http://192.168.54.1/cam.cgi?mode=startstream&value=49152就能启动实时流。启动后,相机从端口65428通过UDP把画面数据发到我的49152端口,但我不知道怎么处理sock.recvfrom(max_length)接收到的数据,没法把它显示成实时视频。

初始代码

这是我一开始写的接收UDP数据的代码:

import socket

UDP_IP = "0.0.0.0"
UDP_PORT = 49152

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))

print(f"Listening for UDP stream on port {UDP_PORT}...")

while True:
    data, addr = sock.recvfrom(65535)  # 最大UDP包长度
    print(f"Received {len(data)} bytes from {addr}")
    # 这里不知道怎么处理data来显示视频

接收数据示例

接收到的UDP包数据是类似这样的分片(十六进制片段):

FF D8 FF E0 00 10 4A 46 49 46 00 01 01 00 00 01 00 01 00 00 FF DB 00 43 00 03 02 02 03 02 02 03 03 03 03 04 03 03 04 05 08 05 05 04 04 05 0A 07 07 06 08 0C 0A 0C 0C 0B 0A 0B 0B 0D 12 0F 0D 11 0E 0F 11 11 10 12 14 15 15 15 0C 0E 17 18 16 14 18 12 14 15 14 FF D9

能看到开头的FF D8和结尾的FF D9——这是JPEG帧的起始和结束标记,但UDP包是分片传输的,单个包可能只包含帧的一部分。

最终解决代码

核心思路:把UDP分片的数据拼接起来,直到凑出完整的JPEG帧(从FF D8开始到FF D9结束),然后用OpenCV解码并显示。

import socket
import cv2
import numpy as np

UDP_IP = "0.0.0.0"
UDP_PORT = 49152

# 初始化UDP套接字
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))

# 用于缓存拼接中的JPEG数据
frame_buffer = b""

print(f"Listening for UDP stream on port {UDP_PORT}...")

while True:
    data, addr = sock.recvfrom(65535)
    frame_buffer += data
    
    # 查找完整的JPEG帧:从FF D8开始,到FF D9结束
    start_idx = frame_buffer.find(b"\xff\xd8")
    end_idx = frame_buffer.find(b"\xff\xd9")
    
    if start_idx != -1 and end_idx != -1:
        # 提取完整的JPEG帧
        jpeg_frame = frame_buffer[start_idx:end_idx+2]
        # 更新缓存,保留当前帧之后的数据(可能包含下一帧的部分数据)
        frame_buffer = frame_buffer[end_idx+2:]
        
        # 解码JPEG帧并显示
        try:
            np_frame = np.frombuffer(jpeg_frame, dtype=np.uint8)
            cv_frame = cv2.imdecode(np_frame, cv2.IMREAD_COLOR)
            if cv_frame is not None:
                cv2.imshow("Panasonic FZ82 Live Stream", cv_frame)
                # 按Q键退出
                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break
        except Exception as e:
            print(f"Failed to decode frame: {e}")

# 清理资源
cv2.destroyAllWindows()
sock.close()

代码说明

  1. 缓存拼接:用frame_buffer持续累加UDP接收到的数据,因为单个UDP包不一定包含完整的JPEG帧。
  2. 帧提取:通过查找JPEG的起始(FF D8)和结束(FF D9)标记,提取完整的帧数据,同时更新缓存,避免重复处理。
  3. 解码显示:用numpy把字节数据转成数组,再通过OpenCV的imdecode解码为图像,最后用imshow实时显示。
  4. 退出逻辑:按下Q键时关闭窗口并终止程序。

内容的提问来源于stack exchange,提问作者Tobias

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:30:54