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

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

相关推荐
io_T_T29 分钟前
(dify)如何使用dify自定义知识库【dify外部链接知识库】
python
xuefeiniao1 小时前
【django.db.utils.OperationalError: unable to open database file】
数据库·python·django·持续部署
??? Meggie1 小时前
【Python】让Selenium 像Beautifulsoup一样,用解析HTML 结构的方式提取元素!
python·selenium·beautifulsoup
灏瀚星空2 小时前
深度学习之LSTM时序预测:策略原理深度解析及可视化实现
python·深度学习·神经网络·算法·机器学习·数学建模·lstm
正经教主2 小时前
【基础】Python包管理工具uv使用全教程
python·uv·包管理工具
zm-v-159304339863 小时前
ChatGPT-4o:临床医学科研与工作的创新引擎
人工智能·python·医学
学地理的小胖砸3 小时前
【Python 模块】
开发语言·python
jie188945758664 小时前
python--------修改桌面文件内容
java·数据库·python
一起喝芬达20104 小时前
【Agent】使用 Python 结合 OpenAI 的 API 实现一个支持 Function Call 的程序,修改本机的 txt 文件
windows·python·microsoft
一个天蝎座 白勺 程序猿4 小时前
Python爬虫(20)Python爬虫数据存储技巧:二进制格式(Pickle/Parquet)性能优化实战
开发语言·爬虫·python