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

基于CLI在Raspberry Pi 3上实现骑行速度联动VLC视频播放的技术求助

解决方案

一、使用python-vlc实现可靠的播放控制与事件监听

python-vlc是Python整合VLC的最优选择,你之前的问题大概率是未正确利用其事件回调机制捕获播放状态,或是未适配CLI环境的VLC初始化参数。

核心代码片段:

import vlc
import time
from threading import Thread, Lock
from gpiozero import HallEffectSensor  # 也可替换为RPi.GPIO实现

# 初始化CLI环境下的VLC实例
instance = vlc.Instance('--no-xlib', '--fullscreen', '--quiet')
player = instance.media_player_new()

# 速度统计线程安全变量
lock = Lock()
cycle_timestamps = []
last_cycle_time = None
stop_threshold = 10  # 超过10秒无踩踏判定为停止

# 霍尔传感器监听线程
def sensor_monitor(sensor_pin):
    global last_cycle_time
    sensor = HallEffectSensor(sensor_pin)
    while True:
        sensor.wait_for_active()
        with lock:
            current_time = time.time()
            cycle_timestamps.append(current_time)
            last_cycle_time = current_time
        time.sleep(0.1)  # 去抖动,避免重复计数

# 启动传感器线程
sensor_thread = Thread(target=sensor_monitor, args=(17,))  # 替换你的GPIO引脚
sensor_thread.daemon = True
sensor_thread.start()

# 计算平均速度(圈/分钟)
def calculate_avg_speed():
    with lock:
        if len(cycle_timestamps) < 2:
            return 0
        # 取最近30秒内的圈数计算实时平均速度
        cutoff_time = time.time() - 30
        recent_timestamps = [t for t in cycle_timestamps if t >= cutoff_time]
        if len(recent_timestamps) < 2:
            return 0
        total_time = recent_timestamps[-1] - recent_timestamps[0]
        total_cycles = len(recent_timestamps) - 1
        return round((total_cycles / total_time) * 60, 1)

# 通用视频播放函数
def play_video(video_path):
    media = instance.media_new(video_path)
    player.set_media(media)
    player.play()
    # 监听播放状态,同时检测是否停止踩踏
    while player.is_playing():
        with lock:
            if last_cycle_time and (time.time() - last_cycle_time) > stop_threshold:
                player.stop()
                break
        time.sleep(0.5)
    # 清空当前周期的时间戳,避免干扰下一次计算
    with lock:
        cycle_timestamps.clear()

二、完整流程逻辑实现

整合欢迎视频、开场视频、速度分级视频的切换逻辑:

import os
import random

# 视频路径配置
WELCOME_VIDEO = "/home/pi/videos/welcome.mp4"
OPENING_VIDEO = "/home/pi/videos/opening.mp4"
END_VIDEO = "/home/pi/videos/end.mp4"
SPEED_FOLDERS = {
    "high": "/home/pi/videos/High Speed",
    "medium": "/home/pi/videos/Medium Speed",
    "low": "/home/pi/videos/Low Speed"
}
SPEED_THRESHOLDS = {"high": 60, "medium": 30}  # 速度分级阈值(圈/分钟)

def get_random_video(folder):
    videos = [f for f in os.listdir(folder) if f.endswith(('.mp4', '.mov', '.avi'))]
    if not videos:
        return None
    return os.path.join(folder, random.choice(videos))

def main():
    # 播放欢迎视频
    play_video(WELCOME_VIDEO)
    
    # 等待3-5圈踩踏触发启动
    print("等待启动踩踏...")
    while True:
        with lock:
            if len(cycle_timestamps) >= 3:
                break
        time.sleep(0.5)
    
    # 播放开场视频
    play_video(OPENING_VIDEO)
    
    # 循环速度匹配视频逻辑
    while True:
        # 检测是否停止踩踏
        with lock:
            if last_cycle_time and (time.time() - last_cycle_time) > stop_threshold:
                break
        
        # 计算当前平均速度并匹配视频文件夹
        avg_speed = calculate_avg_speed()
        if avg_speed >= SPEED_THRESHOLDS["high"]:
            video_path = get_random_video(SPEED_FOLDERS["high"])
        elif avg_speed >= SPEED_THRESHOLDS["medium"]:
            video_path = get_random_video(SPEED_FOLDERS["medium"])
        else:
            video_path = get_random_video(SPEED_FOLDERS["low"])
        
        if not video_path:
            break  # 对应文件夹无视频,触发结束流程
        
        play_video(video_path)
    
    # 播放结束视频后回到初始状态
    play_video(END_VIDEO)
    main()

if __name__ == "__main__":
    main()

三、开机自动启动配置

创建systemd服务文件/etc/systemd/system/bike-video.service:

[Unit]
Description=Bike Video Controller
After=multi-user.target

[Service]
Type=simple
User=pi
ExecStart=/usr/bin/python3 /home/pi/bike_video_controller.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

执行以下命令启用服务:

sudo systemctl daemon-reload
sudo systemctl enable bike-video.service
sudo systemctl start bike-video.service

关键注意事项

  • CLI环境适配:VLC必须添加--no-xlib参数,否则无桌面环境下无法启动;--fullscreen确保视频全屏播放;--quiet减少冗余日志。
  • 线程安全:所有访问cycle_timestamps和last_cycle_time的操作必须加锁,避免多线程竞争导致数据错误。
  • 速度计算逻辑:采用最近30秒的圈数计算平均速度,比整个播放周期更能反映实时踩踏状态,提升交互体验。
  • 异常处理:可自行添加视频文件不存在、传感器故障等异常捕获逻辑,提升稳定性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 05:45:39