拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于树莓派与Python的宠物陪伴智能音箱定时播放方案

很多朋友在后台问我家里养了牡丹鹦鹉之后为什么我特意留了一台天猫精灵给它们用。听起来像是“宠物与智能硬件”的小趣味但背后其实是一套完整的宠物陪伴音频播放方案。本文就把这个项目从需求到落地完整拆开讲清楚如何用“天猫精灵 树莓派 Python 定时任务”打造一个会唱歌、能定时、可远程控制的“鹦鹉陪伴音箱”。如果你是养鸟爱好者或者想给宠物做一套自动音乐播放系统又或者只是对智能音箱的二次开发感兴趣这篇文章都能给你一个可以直接复制运行的参考。1. 背景与场景拆解1.1 牡丹鹦鹉为什么需要“声音陪伴”牡丹鹦鹉是一种非常粘人、感情丰富的鸟类。它们会通过鸣唱表达情绪也会因为孤单、环境变化而出现拔羽、拒食等应激行为。很多人以为只要给足食物和水就可以了但事实上声音环境对鹦鹉的心理健康非常关键。鸟类对声音极其敏感尤其是同类鸟的鸣叫声。一只从小人工喂养的牡丹鹦鹉如果长期听不到同类声音可能会变得沉默、焦虑。反过来如果让它听到舒缓的音乐或者同类清晰、健康的鸣叫声它更容易放松下来并逐渐模仿、学习甚至重新建立起活泼的鸣唱状态。这个项目就是从这个场景出发把天猫精灵当作“会唱歌的陪伴伙伴”通过定时播放音频让牡丹鹦鹉在主人上班时也能感受到“家里有声音、有互动”从而缓解孤独感。很多实践者反馈坚持播放两周后鹦鹉开始主动回应音频里的鸟鸣状态明显变好。1.2 天猫精灵在这个方案中的角色天猫精灵本身可以有多种用法直接让天猫精灵播放音乐但语音点播无法精准控制播放时长和曲目顺序通过天猫精灵App设置闹钟和提醒只能触发简单铃声无法自定义音频包把天猫精灵当作高品质蓝牙音箱由外部设备树莓派/电脑控制播放内容。这个项目采用第三种方案。原因很简单我们需要的不是“在线曲库”而是“可编排的音频计划”。把天猫精灵当作蓝牙音频输出端把树莓派当作“大脑”可以精确到哪天、几点、播放什么声音、播放多久还能自动重连、断网保护、记录日志。最终的效果就是一台看起来普普通通的天猫精灵每天早上九点自动开始播放鸟鸣下午四点再播放一段轻音乐像是一个真正会唱歌的“电子鸟友”。1.3 项目目标与最终效果通过这个项目你将实现树莓派或普通电脑开机后自动连接天猫精灵蓝牙使用 Python 脚本检测当前日期、播放列表和播放时长通过 cron 定时任务触发无需人工干预所有播放记录写入日志方便查看鹦鹉对哪些音频反应更好支持手动远程执行脚本临时决定给鹦鹉播一段声音。这套系统不仅适用于牡丹鹦鹉也可以扩展到其他宠物、绿植环境背景音、白噪音助眠场景。它是一次典型的“语音硬件 物联网 自动化脚本”组合非常适合入门级智能家居项目。2. 方案选型与系统架构2.1 三种方案对比方案优点缺点适合人群天猫精灵App定时播放配置简单无需额外硬件音频源受平台限制无法自定义本地文件定时精度有限不想折腾只要固定闹钟手机蓝牙 手机闹钟不需要额外硬件手机必须一直在旁边播放内容受手机闹钟限制无法自动切换曲目临时使用树莓派 天猫精灵蓝牙 定时任务可编程、可自定义、可扩展需要一定动手能力想真正做一套智能陪伴系统的玩家本项目选择第三种方案因为它把“天猫精灵”变成了一个通用的音频输出终端而不是一个封闭的语音音箱。这样我们既保留天猫精灵的外观和音质又能通过代码完全掌控播放行为。2.2 系统架构整体架构可以用下面这条链路来描述树莓派Python脚本 cron ↓ 蓝牙 A2DP 音频连接 ↓ 天猫精灵蓝牙音箱模式 ↓ 牡丹鹦鹉听到声音整个流程中树莓派负责“什么时候播、播什么、播多久”天猫精灵负责“把数字信号变成实际声音”。二者之间通过蓝牙传递音频。如果后续想扩展还可以在树莓派上接一个摄像头观察鹦鹉对音频的行为反应做成一个“视频 音频”的闭环陪伴系统。这就是后话了。3. 环境准备与硬件清单3.1 硬件准备牡丹鹦鹉一只饲养环境需要保证安全、安静天猫精灵音箱任意型号支持蓝牙即可我用的是常见款树莓派 3B/4B 或者一台运行 Linux 的电脑带蓝牙模块如果没有树莓派也可以用闲置笔记本装 Ubuntu电源线和基础网络局域网即可不需要连接公网也能播放本地音频3.5mm 音频线可选但蓝牙方案更方便。需要说明的是树莓派的具体型号不影响本文的核心逻辑只需要它能正常播放音频、支持蓝牙A2DP协议。3.2 软件环境操作系统Raspberry Pi OSDebian 11/12或 Ubuntu 20.04/22.04Python 版本3.8 及以上依赖软件bluez、pulseaudio或pipewire、mpv、cronPython 依赖无额外第三方库只用了标准库subprocess、logging、datetime版本不需要完全一致因为本文的核心是配置思路和脚本逻辑。不同系统之间的差异我会在常见问题里说明。3.3 项目目录结构建议在树莓派上创建如下目录/home/pi/bird-sound/ ├── audio/ │ ├── bird_morning.mp3 │ ├── bird_afternoon.mp3 │ └── music_relax.mp3 ├── scripts/ │ ├── play_sound.py │ └── bt_connect.sh ├── logs/ └── config.ini其中audio/存放所有音频文件scripts/存放核心脚本logs/存放运行日志config.ini用于配置播放时段和时长。4. 核心配置步骤4.1 准备音频文件音频文件是整套系统的灵魂。对于牡丹鹦鹉来说最好选择以下两类音频同类的牡丹鹦鹉清晰鸣叫声也就是“同类鸟”的声音自然环境音频例如溪流、雨声、轻柔钢琴曲。音频来源需要注意版权问题。不要直接下载来路不明的商业音乐推荐使用公有领域音效、自己录制的鸟叫声或者从正规音效平台购买授权。为了测试你可以先准备两三个3分钟左右的MP3文件。4.2 将天猫精灵切换为蓝牙音箱虽然天猫精灵型号不同菜单会略有差异但基本流程是一致的打开天猫精灵App进入“设备”页面选择你的音箱找到“蓝牙设置”或“蓝牙音箱”开启“蓝牙发现”让天猫精灵进入可被搜索状态保持页面打开等待外部设备连接。这里建议把天猫精灵放得离树莓派近一些避免蓝牙信号不稳。蓝牙连接成功后天猫精灵会语音提示“蓝牙已连接”。4.3 树莓派蓝牙连接天猫精灵在树莓派终端中先打开蓝牙控制界面bluetoothctl然后依次执行power on scan on此时让天猫精灵保持在蓝牙搜索状态在扫描结果中找到类似TmallGenie或音箱名称的设备记下它的 MAC 地址格式是AA:BB:CC:DD:EE:FF。接下来继续执行pair AA:BB:CC:DD:EE:FF trust AA:BB:CC:DD:EE:FF connect AA:BB:CC:DD:EE:FF如果看到Connection successful说明蓝牙已经连上。最后可以用scan off结束扫描并用quit退出。为了后续脚本自动执行我们需要把这组连接命令保存成一个 Shell 脚本。因为蓝牙连接偶尔会断开所以脚本要具备“未连接就重连”的能力。创建scripts/bt_connect.sh#!/bin/bash # 文件路径/home/pi/bird-sound/scripts/bt_connect.sh MACAA:BB:CC:DD:EE:FF # 如果已经连接直接退出 if bluetoothctl info $MAC | grep -q Connected: yes; then echo bluetooth already connected exit 0 fi echo try to connect $MAC bluetoothctl power on bluetoothctl trust $MAC bluetoothctl connect $MAC sleep 2 # 再次确认 if bluetoothctl info $MAC | grep -q Connected: yes; then echo bluetooth connect success else echo bluetooth connect failed fi给脚本加执行权限chmod x /home/pi/bird-sound/scripts/bt_connect.sh4.4 测试蓝牙音频是否正常输出连接好蓝牙后可以先手动播放一次音频确认声音从天猫精灵出来而不是树莓派自带音箱。安装 mpvsudo apt update sudo apt install -y mpv然后手动播放mpv --volume80 /home/pi/bird-sound/audio/bird_morning.mp3如果声音从树莓派发出而不是从蓝牙音箱发出需要检查 PulseAudio/PipeWire 的默认输出设备。不同系统的处理方法差异较大最常见的做法是安装pavucontrol在图形界面的“回放”标签里把音频输出切换到蓝牙设备sudo apt install -y pavucontrol如果没有桌面环境可以用pactl命令列出输出设备pactl list sinks short然后把默认输出设备设置成蓝牙音箱对应的 sink。由于设备名因系统而异这里不写死命令你可以在常见问题里找到排查思路。4.5 编写 Python 播放脚本Python 脚本是整个控制逻辑的核心。它负责以下几个事情读取配置文件中的播放时段和音频路径调用 mpv 播放音频并设置音量和时长把播放记录写入日志在播放结束后输出状态。创建scripts/play_sound.py#!/usr/bin/env python3 # -*- coding: utf-8 -*- # 文件路径/home/pi/bird-sound/scripts/play_sound.py import subprocess import configparser from datetime import datetime import logging import os import argparse # 配置日志 LOG_DIR /home/pi/bird-sound/logs LOG_FILE os.path.join(LOG_DIR, play.log) os.makedirs(LOG_DIR, exist_okTrue) logging.basicConfig( levellogging.INFO, format%(asctime)s [%(levelname)s] %(message)s, handlers[ logging.FileHandler(LOG_FILE, encodingutf-8), logging.StreamHandler() ] ) CFG_FILE /home/pi/bird-sound/config.ini def load_config(): 读取配置文件返回音频列表和播放时长 config configparser.ConfigParser() config.read(CFG_FILE, encodingutf-8) audio_dir config.get(audio, audio_dir, fallback/home/pi/bird-sound/audio) duration config.getint(play, duration_seconds, fallback600) volume config.getint(play, volume, fallback70) # 返回需要播放的文件列表按逗号分隔 files config.get(audio, files, fallbackbird_morning.mp3).split(,) paths [os.path.join(audio_dir, f.strip()) for f in files if f.strip()] return paths, duration, volume def play_audio(file_path, duration, volume): 调用 mpv 播放指定音频duration 单位秒volume 范围 0-100 if not os.path.exists(file_path): logging.error(f音频文件不存在: {file_path}) return False # 使用 timeout 限制播放时长避免脚本卡死 cmd [ timeout, str(duration), mpv, --no-terminal, f--volume{volume}, file_path ] logging.info(f开始播放: {file_path}, 时长: {duration}s, 音量: {volume}) try: result subprocess.run(cmd, stdoutsubprocess.DEVNULL, stderrsubprocess.DEVNULL) logging.info(f播放结束, 返回码: {result.returncode}) return result.returncode 0 except Exception as e: logging.exception(f播放异常: {e}) return False def main(): parser argparse.ArgumentParser(description牡丹鹦鹉陪伴音频播放器) parser.add_argument(--tag, defaultmanual, help本次播放的来源标记方便日志分析) args parser.parse_args() paths, duration, volume load_config() if not paths: logging.error(配置文件中没有可用音频文件) return logging.info(f本次播放标记: {args.tag}, 共 {len(paths)} 个文件) success_count 0 for path in paths: ok play_audio(path, duration, volume) if ok: success_count 1 logging.info(f播放完成成功 {success_count}/{len(paths)}) if __name__ __main__: main()这段脚本用到了标准库没有任何第三方依赖非常稳。timeout命令用来限制每个音频的播放时长防止某个文件异常导致卡住。4.6 配置文件示例创建config.ini# 文件路径/home/pi/bird-sound/config.ini [audio] audio_dir /home/pi/bird-sound/audio files bird_morning.mp3, bird_afternoon.mp3, music_relax.mp3 [play] duration_seconds 900 volume 70这里的duration_seconds 900表示每个文件最多播放 900 秒也就是 15 分钟。你可以根据鹦鹉的状态和家庭作息调整。4.7 设置定时任务定时任务使用 cron 来实现。编辑当前用户的 crontabcrontab -e加入以下内容# 每天 9:00 播放清晨鸟鸣 0 9 * * * /home/pi/bird-sound/scripts/bt_connect.sh /usr/bin/python3 /home/pi/bird-sound/scripts/play_sound.py --tag morning /home/pi/bird-sound/logs/cron.log 21 # 每天 16:00 播放下午音乐 0 16 * * * /home/pi/bird-sound/scripts/bt_connect.sh /usr/bin/python3 /home/pi/bird-sound/scripts/play_sound.py --tag afternoon /home/pi/bird-sound/logs/cron.log 21保存后可以用下面的命令检查定时任务是否生效crontab -l如果系统里没有/usr/bin/python3可以通过which python3查看实际路径并替换。4.8 手动运行验证先不要等定时任务先手动执行一次/home/pi/bird-sound/scripts/bt_connect.sh /usr/bin/python3 /home/pi/bird-sound/scripts/play_sound.py --tag test观察日志输出2025-01-18 09:00:31 [INFO] 本次播放标记: test, 共 3 个文件 2025-01-18 09:00:31 [INFO] 开始播放: /home/pi/bird-sound/audio/bird_morning.mp3, 时长: 900s, 音量: 70同时确认天猫精灵有没有发出声音。如果音箱出声就说明整个链路已经通了。4.9 结果说明整套系统运行后每天会在固定时间触发蓝牙连接确认天猫精灵在线后播放设定好的音频。即使当时蓝牙断开了bt_connect.sh也会自动重连一次避免因为临时信号波动导致播放失败。日志文件logs/play.log会记录每一次播放的开始、结束和返回码。你可以通过查看日志判断音频是否正常、鹦鹉是否喜欢以及哪个时段的播放效果最好。5. 常见问题与排查思路5.1 蓝牙连接失败问题现象常见原因解决思路connect后提示Device not available天猫精灵不在配对模式或距离过远重新开启蓝牙发现把音箱靠近树莓派Pairing failed旧配对信息冲突bluetoothctl remove MAC后重新配对树莓派重启后自动连接失败系统没有 persist 蓝牙连接在 crontab 中加入开机任务或使用 network dispatcher 脚本最常见的原因是天猫精灵一段时间后会自动关闭蓝牙搜索。所以每次重连前要确认天猫精灵还在“蓝牙音箱”页面。如果长时间使用建议把天猫精灵固件升级到最新版蓝牙稳定性会好很多。5.2 音频从树莓派自带音箱输出这是因为默认音频输出设备不是蓝牙音箱。解决方法安装pavucontrol查看“回放”标签页把 mpv 的输出设备切换到天猫精灵或者用pactl set-default-sink设置默认输出设备。在无桌面环境下可以先用pactl list sinks short列出设备名然后pactl set-default-sink 蓝牙设备名由于不同 Linux 发行版的蓝牙音频后端不一样建议把操作步骤固化到bt_connect.sh中每次连接后自动设置默认输出。5.3 定时任务没有执行可能原因crontab 没有保存成功Python 脚本路径或者 mpv 路径不对环境变量缺失比如PATH中没有/usr/bin脚本执行权限不够。排查方法在 crontab 开头临时加一行* * * * * echo test /tmp/test.log看是否每分钟写入。如果写入正常再检查脚本路径。更稳妥的方式是在脚本里使用绝对路径并且不要在 Python 脚本中依赖相对路径。上面示例中已经把所有文件路径都写成了绝对路径可以避免大多数问题。5.4 音量过大或过小mpv 的--volume70只是 mpv 内部音量并不是系统音量的上限。如果觉得声音太小可以调到 90如果担心吓到鹦鹉建议先从 50 开始观察鹦鹉反应后逐步调整。这里特别提醒一句鹦鹉的听觉比人类敏感很多过大的音量会造成强烈应激。不要追求“响”要追求“清晰、柔和、稳定”。5.5 鹦鹉对声音没有反应这是最需要耐心的一点。牡丹鹦鹉不一定立刻对新声音有反应通常需要 3 到 7 天的适应期。如果连续两周都没有任何反应建议换一种音频类型。有些鹦鹉更喜欢同类幼鸟的叫声有些则对轻柔的钢琴曲更感兴趣。你可以通过日志观察播放时段尝试在上午和下午分别播放不同的音频对比鹦鹉的精神状态和鸣叫频率。6. 最佳实践与工程建议6.1 音频选择与版权音频文件的版权很容易被忽略。建议优先使用自己录制的鸟鸣声或者从可商用素材库获取。不要直接传播他人的原创音乐。如果只是自己家里使用不公开传播一般问题不大但养成好习惯总没错。文件格式推荐 MP3码率 128kbps 以上即可。不要使用体积过大的无损格式因为蓝牙传输和树莓派解码都会增加不必要的负担。6.2 定时策略牡丹鹦鹉的作息和人类不同它们通常在清晨和傍晚比较活跃。所以定时播放建议安排在这两个时段。另外播放时长不要过长15 到 30 分钟比较合适。长时间播放会让鹦鹉逐渐适应并忽略声音反而失去陪伴效果。定时任务建议固定时间让鹦鹉形成稳定的生物钟。6.3 日志与可观测性日志是这套系统最重要的“眼睛”。我建议除了play.log再给bt_connect.sh增加输出到独立日志的能力这样连接失败和播放失败可以分开排查。# bt_connect.sh 中可改成 ./bt_connect.sh /home/pi/bird-sound/logs/bt.log 21日志文件要定期清理避免撑满树莓派的存储卡。可以通过 logrotate 实现也可以在 crontab 中加一条清理命令。6.4 安全与法律合规只播放合法获取的音频播放音量控制在安全范围避免损伤鹦鹉听力不要用这一套系统去录制、上传他人音频到公共平台树莓派如果暴露在公网请务必设置防火墙和强密码避免被远程控制后乱播放声音。本项目没有接入任何外部 API也不需要公网端口整体安全性较高。6.5 代码健壮性建议上面的 Python 脚本已经处理了“文件不存在”和“播放异常”的情况。在实际项目中还可以增加以下能力检测蓝牙连接状态断开时重试根据星期几播放不同音频通过 MQTT 或 HTTP 接口远程触发播放在配置中支持多个播放列表。例如要为工作日和周末设置不同音频可以在play_sound.py中读取datetime.now().weekday()根据结果选择不同的files。这部分作为扩展方向实现起来并不复杂。7. 总结与下一步扩展到目前为止我们已经完成了一套从零到一的“牡丹鹦鹉陪伴音频播放系统”。它不仅让天猫精灵变得“会唱歌”更重要的是让播放行为变得可控、可计划、可观察。你可以通过修改config.ini调整音频列表通过 cron 调整播放时段通过日志判断效果。下一步有三个扩展方向第一接入运动传感器或摄像头当鹦鹉靠近天猫精灵时自动播放距离远时停止形成更智能的交互。第二接入语音识别让天猫精灵通过 App 技能或第三方平台识别“播放鸟鸣”“停止播放”等指令把野生玩法升级成完整语音交互方案。第三把音频播放与智能照明联动比如傍晚播放音乐时同步调暗灯光模拟日落环境帮助鹦鹉稳定情绪。如果你也养了一只牡丹鹦鹉不妨从最基础的蓝牙连接和定时播放开始试。先连续运行一周记录鹦鹉的行为变化再根据实际情况迭代。技术只是工具真正让宠物感受到“被陪伴”的是我们愿意为它花的心思。希望这篇文章能给你带来一些灵感。动手搭建过程中遇到问题欢迎在评论区留言我会尽量根据实际经验给出建议。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门