两个树莓派如何通过wifi direct传输视频并显示

这里写自定义目录标题

系统架构概述
发送端树莓派:捕获视频(摄像头或视频文件)→ 编码 → 通过Wi-Fi Direct传输

接收端树莓派:接收数据 → 解码 → 在ST7789 LCD屏上显示

准备工作

硬件需求

两个树莓派(建议3B+/4B)

摄像头模块(发送端)

ST7789 LCD屏(接收端)

电源供应

软件需求

bash

复制

在两台设备上安装必要软件

python 复制代码
sudo apt update
sudo apt install -y ffmpeg python3-pip git
pip3 install numpy gpiozero spidev st7789

第一部分:配置Wi-Fi Direct连接

  1. 在两台树莓派上配置Wi-Fi Direct
    编辑网络配置文件:

bash

复制

python 复制代码
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

添加以下内容(两台设备配置相同):

复制

python 复制代码
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=US

network={
    ssid="DIRECT-RPi"
    mode=1
    frequency=2412
    key_mgmt=WPA-PSK
    psk="raspberry"
}

重启网络服务:

bash

复制

python 复制代码
sudo systemctl restart networking

或者

python 复制代码
sudo systemctl restart NetworkManager

或者

python 复制代码
sudo systemctl restart systemd-networkd

不同发行版使用的网络服务不同,具体使用哪条指令,可以先通过以下指令确认当前使用的是哪个网络管理工具:

python 复制代码
sudo systemctl list-units --type=service | grep -E '(network|NetworkManager)'
  1. 验证连接
    在两台设备上执行:

bash

复制

python 复制代码
sudo iw dev wlan0 scan | grep "DIRECT-RPi"

应该能看到彼此的设备。

第二部分:发送端设置(视频采集和传输)

  1. 视频采集脚本 sender.py
    python
    复制
python 复制代码
import subprocess
import socket
import time

Wi-Fi Direct接收端IP(自动发现或静态设置)

python 复制代码
RECEIVER_IP = "192.168.4.2"  # 典型Wi-Fi Direct IP
PORT = 5000

设置摄像头参数

python 复制代码
WIDTH, HEIGHT = 640, 480
FPS = 24
BITRATE = "500k"

def start_stream():
    # 使用FFmpeg捕获摄像头并编码为H.264
    ffmpeg_cmd = [
        'ffmpeg',
        '-f', 'v4l2',
        '-input_format', 'h264',
        '-video_size', f'{WIDTH}x{HEIGHT}',
        '-framerate', str(FPS),
        '-i', '/dev/video0',
        '-c:v', 'copy',  # 直接使用摄像头硬件编码
        '-f', 'h264',
        '-'
    ]
    
    # 网络传输设置
    soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    # 启动FFmpeg进程
    process = subprocess.Popen(ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    
    try:
        while True:
            # 读取FFmpeg输出并发送
            data = process.stdout.read(1024)
            if not data:
                break
            soc.sendto(data, (RECEIVER_IP, PORT))
    except KeyboardInterrupt:
        process.terminate()
        soc.close()

if __name__ == "__main__":
    start_stream()

第三部分:接收端设置(接收和显示)

  1. 安装显示驱动库
    bash
    复制
python 复制代码
git clone https://github.com/pimoroni/st7789-python
cd st7789-python
sudo python3 setup.py install
  1. 接收和显示脚本 receiver.py
python 复制代码
python
复制
import socket
import subprocess
import threading
from PIL import Image
import st7789
import numpy as np

显示初始化

python 复制代码
disp = st7789.ST7789(
    height=240,
    width=240,
    rotation=90,
    port=0,
    cs=8,
    dc=24,
    rst=25,
    spi_speed_hz=80 * 1000 * 000
)

网络设置

python 复制代码
PORT = 5000
BUFFER_SIZE = 1024 * 8  # 8KB缓冲区

def display_frame(frame_data):
    """将接收到的帧数据显示在LCD上"""
    try:
        # 转换为PIL图像(假设是RGB格式)
        img = Image.frombytes('RGB', (240, 240), frame_data)
        disp.display(img)
    except Exception as e:
        print(f"显示错误: {e}")

def receive_stream():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(('0.0.0.0', PORT))
    
    # 使用FFmpeg解码
    ffmpeg_cmd = [
        'ffmpeg',
        '-i', '-',          # 从stdin读取
        '-f', 'rawvideo',   # 输出原始视频帧
        '-pix_fmt', 'rgb24',
        '-s', '240x240',    # 调整为屏幕分辨率
        '-'
    ]
    process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    
    while True:
        data, _ = sock.recvfrom(BUFFER_SIZE)
        if data:
            process.stdin.write(data)
            # 从FFmpeg读取解码后的帧
            frame = process.stdout.read(240*240*3)  # RGB 240x240
            if frame:
                display_frame(frame)

if __name__ == "__main__":
    receive_stream()

优化方案

  1. 降低延迟技巧
    发送端:

python

复制

python 复制代码
ffmpeg_cmd = [
    'ffmpeg',
    '-fflags', 'nobuffer',  # 减少输入缓冲
    '-flags', 'low_delay',  # 低延迟模式
    '-tune', 'zerolatency', # 零延迟调优
    # ...其他参数
]
接收端:

python
复制
disp = st7789.ST7789(
    # ...其他参数
    spi_speed_hz=120 * 1000 * 1000  # 提高SPI速度
)
  1. 自动发现IP地址
    在两台设备上添加:

python

复制

python 复制代码
import netifaces

def get_wifi_direct_ip():
    try:
        return netifaces.ifaddresses('p2p-wlan0-0')[netifaces.AF_INET][0]['addr']
    except:
        return None

常见问题解决

连接不稳定:

缩短设备间距离

尝试不同频道:sudo iwconfig wlan0 channel 6

视频卡顿:

降低分辨率:改为320x240

降低帧率:15FPS

减少比特率:"300k"

显示异常:

检查SPI连接

确认ST7789初始化参数正确

降低SPI速度测试

最终启动流程

发送端:

bash

复制

python3 sender.py

接收端:

bash

复制

python3 receiver.py

这个方案实现了从摄像头采集到无线传输再到屏幕显示的全流程,你可以根据需要调整视频参数和显示设置。

相关推荐
Python×CATIA工业智造1 小时前
Pycaita二次开发基础代码解析:几何体重命名与参数提取技术
python·pycharm·pycatia
你的电影很有趣1 小时前
lesson30:Python迭代三剑客:可迭代对象、迭代器与生成器深度解析
开发语言·python
成成成成成成果3 小时前
揭秘动态测试:软件质量的实战防线
python·功能测试·测试工具·测试用例·可用性测试
天天进步20154 小时前
Python游戏开发引擎设计与实现
开发语言·python·pygame
数据狐(DataFox)5 小时前
CTE公用表表达式的可读性与性能优化
经验分享·python·sql
蹦蹦跳跳真可爱5895 小时前
Python----MCP(MCP 简介、uv工具、创建MCP流程、MCP客户端接入Qwen、MCP客户端接入vLLM)
开发语言·人工智能·python·语言模型
No0d1es5 小时前
第13届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2022年1月22日真题
python·青少年编程·蓝桥杯·选拔赛
MediaTea5 小时前
Python 库手册:getopt Unix 风格参数解析模块
服务器·开发语言·python·unix
王尼莫啊5 小时前
【立体标定】圆形标定板标定python实现
开发语言·python·opencv
cosX+sinY6 小时前
10 卷积神经网络
python·深度学习·cnn