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

RPI3的fm_transmitter脚本优化:解决短时间重复播放歌曲问题

Hey there! 作为同样折腾过树莓派音频脚本的家伙,我完全懂你在焊接车间里不想反复听到同一首歌的烦躁——毕竟重复的曲子比焊渣还让人闹心😅

结合你已经有播放日志的基础,我给你两个实用的优化方案,彻底解决短时间内歌曲重复的问题:

方案1:基于播放日志排除最近播放的歌曲

这个方案直接复用你现有的播放日志,通过排除最近N首播过的歌来避免短时间重复,调整灵活,适合歌曲库较大的场景。

优化后的脚本示例

#!/bin/bash

# 请根据你的实际情况修改以下参数
MUSIC_DIR="/home/pi/workshop_music"  # 你的音乐目录
PLAY_LOG="/home/pi/play_history.log" # 已有的播放日志路径
EXCLUDE_LAST_N=10                     # 排除最近播放的10首歌,可按需调整

# 从日志中提取最近N首播放过的歌曲(去重避免重复记录)
recent_played=$(tail -n "$EXCLUDE_LAST_N" "$PLAY_LOG" | awk '{print $NF}' | sort | uniq)

# 生成可用歌曲列表:从音乐目录中排除最近播放的歌
available_songs=()
for track in "$MUSIC_DIR"/*.mp3 "$MUSIC_DIR"/*.wav; do
    # 跳过不存在的文件(比如目录里只有mp3时,wav的通配会保留原字符串)
    [ -f "$track" ] || continue
    if [[ ! " $recent_played " =~ " $track " ]]; then
        available_songs+=("$track")
    fi
done

# 兜底逻辑:如果所有歌都刚播过,就重置为全部歌曲
if [ ${#available_songs[@]} -eq 0 ]; then
    available_songs=($(find "$MUSIC_DIR" -type f \( -name "*.mp3" -o -name "*.wav" \)))
fi

# 随机选一首播放
random_idx=$((RANDOM % ${#available_songs[@]}))
selected_track=${available_songs[$random_idx]}

# 调用fm_transmitter播放(替换成你实际的播放命令参数)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Now transmitting: $selected_track"
fm_transmitter -f 92.1 "$selected_track"

# 记录到播放日志(保持你原有的日志格式即可)
echo "$(date '+%Y-%m-%d %H:%M:%S') $selected_track" >> "$PLAY_LOG"

方案优势

  • 完全复用现有日志,不需要额外维护新的文件
  • 通过调整EXCLUDE_LAST_N可以灵活控制重复间隔(比如设为20,就不会在最近20首里重复)
  • 有兜底逻辑,避免出现无歌可选的情况
方案2:维护洗牌式播放队列(彻底无重复直到一轮播完)

如果你想要绝对避免重复,直到目录里所有歌曲都播完再重新洗牌,这个方案更适合歌曲库不大的场景。

优化后的脚本示例

#!/bin/bash

MUSIC_DIR="/home/pi/workshop_music"
PLAY_LOG="/home/pi/play_history.log"
QUEUE_FILE="/tmp/workshop_music_queue.txt" # 临时队列文件,重启会重置

# 如果队列为空或不存在,生成洗牌后的完整歌曲列表
if [ ! -s "$QUEUE_FILE" ]; then
    find "$MUSIC_DIR" -type f \( -name "*.mp3" -o -name "*.wav" -o -name "*.flac" \) | shuf > "$QUEUE_FILE"
fi

# 读取队列的第一首歌
selected_track=$(head -n 1 "$QUEUE_FILE")

# 播放歌曲
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Now transmitting: $selected_track"
fm_transmitter -f 92.1 "$selected_track"

# 记录日志
echo "$(date '+%Y-%m-%d %H:%M:%S') $selected_track" >> "$PLAY_LOG"

# 从队列中移除已播放的歌曲
sed -i '1d' "$QUEUE_FILE"

方案优势

  • 每一轮播放都会遍历所有歌曲,绝对不会出现短时间重复
  • 实现简单,不需要复杂的过滤逻辑
  • 如果想要保留队列(重启树莓派不重置),可以把QUEUE_FILE放到非临时目录
额外小优化
  • 可以给日志加滚动策略:用logrotate配置定期压缩旧日志,避免日志文件过大影响读取速度
  • 扩展支持的音频格式:在find或for循环里添加.flac、.ogg等你需要的格式
  • 容错处理:在播放前检查文件是否存在,避免因文件损坏导致脚本中断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:21:20