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

树莓派开机运行代码时无法加载USB设备歌曲至GUI的解决方法

解决树莓派开机运行时无法读取U盘MP3的问题

首先,咱们先拆解下你遇到的核心问题:通过/etc/profile启动的脚本,大概率赶不上系统自动挂载U盘的节奏——/etc/profile是用户登录流程早期执行的,而U盘的自动挂载通常要等到桌面环境启动后,由udisks这类服务完成,这时候你的代码已经跑完了,自然读不到U盘里的文件。另外,你的代码里还有个小细节错误,先一起给你修正。

一、先修正代码里的小bug

看你第二个os.walk('/home/pi/')的循环里,有一行os.path.join(media, filename),这里的media是第一个循环的变量,到第二个循环时已经没有意义了,而且这行代码也没被使用,直接删掉就行。另外加个.lower()兼容大写后缀的情况,更严谨一点。修正后的代码片段:

def music_file(self):
    # 遍历U盘目录
    for media, dirs, files in os.walk('/media/pi/'):
        for filename in files:
            if os.path.splitext(filename)[1].lower() == ".mp3":
                full_path = os.path.join(media, filename)
                self.filename1.append(full_path)
                self.filename2.append(filename)
    # 遍历本地目录
    for home, dirs, files in os.walk('/home/pi/'):
        for filename in files:
            if os.path.splitext(filename)[1].lower() == ".mp3":
                full_path = os.path.join(home, filename)
                self.filename1.append(full_path)
                self.filename2.append(filename)
    return self.filename2

二、解决U盘挂载时机的问题

方案1:等待U盘挂载完成后再执行代码

在脚本开头添加等待逻辑,检查/media/pi/下是否有U盘挂载目录,最多等待一段时间,避免脚本卡住:

import time
import os

# 等待U盘挂载,最多等30秒
wait_time = 0
max_wait = 30
# 检查/media/pi下是否有子目录(U盘挂载后会生成卷名目录)
while not any(os.path.isdir(os.path.join('/media/pi/', d)) for d in os.listdir('/media/pi/')) and wait_time < max_wait:
    time.sleep(1)
    wait_time += 1

if wait_time >= max_wait:
    print("等待U盘超时,跳过U盘文件加载")
else:
    print("U盘已挂载,开始加载歌曲")
    # 这里调用你的music_file方法

方案2:用systemd服务替代/etc/profile(更可靠)

systemd可以设置服务依赖,确保在U盘挂载完成后再启动你的脚本,步骤如下:

  1. 创建一个systemd服务文件,比如~/music-player.service:
[Unit]
Description=Music Player GUI Service
After=multi-user.target udisks2.service
Wants=udisks2.service

[Service]
User=pi
Environment=DISPLAY=:0
Environment=XAUTHORITY=/home/pi/.Xauthority
ExecStart=/usr/bin/python3 /path/to/your/script.py
WorkingDirectory=/path/to/script/directory
Restart=on-failure

[Install]
WantedBy=graphical.target
  • After=...:确保在多用户环境和udisks2服务(负责自动挂载)启动后再运行脚本
  • Environment:设置桌面环境的环境变量,保证GUI能正常显示
  • 把/path/to/your/script.py替换成你实际的脚本路径
  1. 复制服务文件到系统目录并启用:
sudo cp ~/music-player.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable music-player.service
sudo systemctl start music-player.service

方案3:监听U盘挂载事件(进阶,支持实时刷新)

如果需要插拔U盘时自动刷新歌曲列表,可以用pyudev库监听挂载事件:

  1. 安装依赖:
pip install pyudev
  1. 添加监听逻辑:
import pyudev
from threading import Thread

def on_usb_mount(action, device):
    if action == 'add' and device.device_type == 'partition' and 'ID_FS_TYPE' in device:
        mount_point = device.get('ID_FS_MOUNTPOINT')
        if mount_point and mount_point.startswith('/media/pi/'):
            print(f"U盘已挂载到{mount_point},刷新歌曲列表")
            # 清空原列表,重新加载
            self.filename1.clear()
            self.filename2.clear()
            self.music_file()

# 初始化监听器并启动线程
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='block', device_type='partition')

monitor_thread = Thread(target=lambda: [on_usb_mount(action, dev) for action, dev in monitor], daemon=True)
monitor_thread.start()

三、检查U盘权限(兜底排查)

如果上述方法还是不行,检查U盘的挂载权限:

  1. 挂载U盘后查看权限:
ls -ld /media/pi/你的U盘卷名

确保pi用户有读取权限(至少r-x)。

  1. 若权限异常,可修改/etc/fstab指定挂载权限:
    先查U盘UUID:
blkid

然后在/etc/fstab添加一行(FAT32替换ntfs-3g为vfat):

UUID=你的U盘UUID /media/pi/自定义挂载点 ntfs-3g defaults,uid=pi,gid=pi,umask=0022 0 0

内容的提问来源于stack exchange,提问作者Abhishek Taori

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:14:05