两个树莓派如何通过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

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

相关推荐
夏天拐跑了西瓜4 小时前
一文入门LangChain:从框架认知到构建你的第一个AI Agent
python·langchain·conda·agent
魔猴疯猿5 小时前
从0到1用Python开发第一个智能体
人工智能·python·深度学习·神经网络·机器学习
xiaoqi01956 小时前
机器学习因子分析实战:从量化特征到可视化决策
人工智能·python·机器学习
Escalating_xu6 小时前
【Python】基础语法(1):常量、变量、类型、输入输出与运算符
开发语言·python
happylifetree7 小时前
Python14:核心语法-数据存储与运算-字符串定义
python
hhb_6187 小时前
AIRAGDebug:一键定位RAG链路异常
人工智能·python·算法
小静AI工程实验室7 小时前
asyncio.Queue 有界队列实战:背压、task_done、join 与异常收尾
python
小凡geo7 小时前
本地商家 GEO:用脚本一键生成 FAQPage 结构化数据,让 AI 切片更稳
开发语言·人工智能·python·microsoft·搜索引擎·ai
Zhou1411367 小时前
SpringBoot_03_Web开发
前端·spring boot·python
weixin199701080167 小时前
《1688物流API接口边界:logistics.trace.get 与 freight.template.list 的隐藏约束》(附Python源码)
windows·python·list