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

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

相关推荐
monkeyhlj13 小时前
LangChain - V1.0
python·langchain·ai编程
zh路西法13 小时前
【Qwen2.5本地部署】超简单pytorch-gpu部署教程
人工智能·pytorch·python
狐狐生风14 小时前
LangGraph Human-in-the-loop 全解
python·langchain·prompt·langgraph·agentai
倒霉熊dd14 小时前
Python 学习(第二部分:函数、模块与面向对象编程)
前端·数据库·python
铁皮哥14 小时前
【力扣题解】LeetCode 25. K 个一组翻转链表
java·数据结构·windows·python·算法·leetcode·链表
lbb 小魔仙14 小时前
告别腾讯会议40分钟限制:用ToDesk协作版开在线会议,免费不限时远程会议新方案
python·langchain·jenkins
凯瑟琳.奥古斯特14 小时前
PyTorch动态计算图详解
人工智能·pytorch·python·深度学习
一个数据大开发14 小时前
企业知识工程的三条路线:Neo4j 知识中台、Agent + Action 与本体原生 Runtime
大数据·python·neo4j
没有感情的robot14 小时前
网页录制方法总结
python
m0_7381207215 小时前
ctfshow靶场SSRF部分——基础绕过到协议攻击解题思路与技巧(二)
python·网络协议·tcp/ip·安全·网络安全