树莓派开机运行代码时无法加载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盘挂载完成后再启动你的脚本,步骤如下:
- 创建一个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替换成你实际的脚本路径
- 复制服务文件到系统目录并启用:
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库监听挂载事件:
- 安装依赖:
pip install pyudev
- 添加监听逻辑:
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盘的挂载权限:
- 挂载U盘后查看权限:
ls -ld /media/pi/你的U盘卷名
确保pi用户有读取权限(至少r-x)。
- 若权限异常,可修改
/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
相关产品推荐
相关产品推荐

