xiaomusic 定时任务配置指南:基于 Crontab 语法实现小爱音箱的自动播放、关机与语音播报
2026/9/15 11:45:57 网站建设 项目流程

xiaomusic 定时任务配置指南:基于 Crontab 语法实现小爱音箱的自动播放、关机与语音播报

【免费下载链接】xiaomusic使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic

本指南围绕 xiaomusic 项目的定时任务(crontab)配置功能展开,讲解如何用标准 crontab 表达式驱动小爱音箱在指定时刻自动播放歌曲、播放列表、执行关机、文字转语音(TTS)、刷新曲库、调整音量等操作。读完本文,你将掌握定时任务的完整配置格式、所有受支持任务类型的参数语义,以及工作日/休息日限定执行等进阶用法,可直接落地为可运行的配置文件。

定时任务是什么:功能定位与配置入口

在 xiaomusic 中,定时任务是一段 JSON 数组配置,每一条记录描述"在什么时间、对哪台设备、执行什么操作"。系统采用标准 crontab 表达式描述执行时机,由 APScheduler 的AsyncIOScheduler调度器驱动(见 crontab.py 中Crontab类的实现)。

该配置的核心应用场景包括:

  • 工作日早晨定时播放叫醒歌曲,随后自动关机;
  • 每晚固定时间播放指定歌单、播报语音提醒;
  • 每天凌晨自动刷新音乐列表、重新初始化登录态以缓解风控/登录失效问题;
  • 按法定工作日/休息日差异化调度(需结合项目内置的节假日数据)。

配置入口主要有两个:

  • Web 设置页面:在crontab_json文本框中粘贴 JSON 配置(setting.html 中即为该表单项);
  • 环境变量XIAOMUSIC_CRONTAB_JSON,见 config.py 中crontab_json: str = os.getenv("XIAOMUSIC_CRONTAB_JSON", "")的定义。

保存配置后,xiaomusic.update_config_from_setting()会调用self.crontab.reload_config(self)(见 xiaomusic.py),重新加载所有定时任务,无需重启进程即可生效。

配置格式:JSON 数组与核心字段

定时任务整体是一个 JSON 数组,数组中的每个对象代表一条任务。以官方文档 docs/issues/182.md 给出的完整示例为基础,最简任务形如:

[ { "expression": "0 8 * * 0-4", "name": "play", "did": "123456789", "arg1": "周杰伦晴天" } ]

字段语义

字段必填含义
expression标准 crontab 表达式,描述任务的执行时机
name任务类型,目前仅支持下文列出的若干固定值
did视任务而定小爱音箱的设备 ID,即设置页面中"音箱型号"后面的那串数字
arg1视任务而定任务参数,含义随name不同而不同

crontab 表达式说明

expression遵循标准 crontab 五段式格式:分 时 日 月 周。需要注意星期字段的取值约定:

星期一是 0,星期二是 1,星期日是 6。 取值范围为0-6,也支持mon,tue,wed,thu,fri,sat,sun这类英文缩写写法;一周的第一天固定是 Monday。

例如0 8 * * 0-4表示"周一至周五每天 8 点";30 10 * * *表示"每天 10 点 30 分"。

加载与调度流程(源码视角)

从源码看,定时任务从配置到执行的调用链为(crontab.py):

  1. reload_config()读取config.crontab_json,用json.loads解析为任务列表;
  2. 对每条任务调用add_job_cron(),按name动态拼接方法名add_job_{name}并通过getattr分发到对应的任务注册函数;
  3. 每个注册函数内部定义async def job(),再交给add_job()注册到AsyncIOScheduler
  4. add_job()将 crontab 表达式解析为CronTrigger,并设置了三个关键调度参数:
    • coalesce=True:若任务错过多次触发,只补执行一次(适合播放类任务);
    • max_instances=30:同一任务最多允许 30 个并发实例,支持多设备并发;
    • misfire_grace_time=60:任务延迟 60 秒内仍会执行。

此外,若配置开启了enable_auto_clean_temp,系统还会在每次加载时自动附加一个"每日凌晨 3 点清理临时文件"的任务。

支持的任务类型总览

当前支持以下任务类型(对应name取值):

name功能是否需要 didarg1 含义
stop关机
play播放歌曲歌曲名
play_music_list播放列表播放目录名,可用\|追加目录内歌曲名
play_music_tmp_list播放自定义列表临时歌单名称(可选)
tts文字转语音要播报的语音文字
refresh_music_list刷新播放列表
set_volume设置音量音量值(0–100)
set_play_type设置播放类型0–4 的数字
set_pull_ask设置是否拉取对话记录enable/disable
reinit重新初始化

set_play_typearg1取值与播放类型的对应关系:

arg1播放类型
0单曲循环
1全部循环
2随机播放
3单曲播放
4顺序播放

在 crontab.py 中,add_job_set_play_type会执行play_type = int(arg1)后调用xiaomusic.set_play_type(did, play_type, False);播放类型的枚举常量定义于 config.py(PLAY_TYPE_ONE/ALL/RND/SIN/SEQ)。

完整配置示例与逐条解读

官方文档给出的完整示例覆盖了全部任务类型,配置如下:

[ { "expression": "0 8 * * 0-4", "name": "play", "did": "123456789", "arg1": "周杰伦晴天" }, { "expression": "10 8 * * 0-4", "name": "stop", "did": "123456789" }, { "expression": "0 9 * * *", "name": "play", "did": "123456789", "arg1": "周杰伦晴天" }, { "expression": "0 10 * * *", "name": "play_music_list", "did": "123456789", "arg1": "周杰伦" }, { "expression": "30 10 * * *", "name": "play_music_list", "did": "123456789", "arg1": "周杰伦|晴天" }, { "expression": "0 7 * * *", "name": "tts", "did": "123456789", "arg1": "早上好!该起床了!" }, { "expression": "0 3 * * *", "name": "refresh_music_list" }, { "expression": "* * * * *", "name": "set_volume", "did": "123456789", "arg1": "25" }, { "expression": "* * * * *", "name": "set_play_type", "did": "123456789", "arg1": "2" }, { "expression": "0 6 * * *", "name": "set_pull_ask", "arg1": "enable" }, { "expression": "0 0 * * *", "name": "set_pull_ask", "arg1": "disable" }, { "expression": "0 1 * * *", "name": "reinit" }, { "expression": "33 20 * * *", "name": "play_music_tmp_list", "did": "978479727", "arg1": "临时列表1", "music_list": [ "1大青树下的小学", "7听听秋的声音", "11宝葫芦的秘密" ], "first": "11宝葫芦的秘密" } ]

上述配置的逐条含义:

  • 周一至周五每天 8 点播放歌曲"周杰伦晴天";
  • 周一至周五每天 8 点 10 分执行关机指令;
  • 每天 9 点播放歌曲"周杰伦晴天";
  • 每天 10 点播放列表"周杰伦";
  • 每天 10 点 30 分播放列表"周杰伦"里的"晴天"(play_music_listarg1|分隔目录名与歌曲名);
  • 每天 7 点发出语音"早上好!该起床了!";
  • 每天 3 点刷新播放列表,用于自动更新音乐目录下的歌曲到播放列表;
  • 每分钟设置音量为 25;
  • 每分钟设置为随机播放;
  • 每天早上 6 点开启拉取对话记录;
  • 每天晚上 12 点关闭拉取对话记录;
  • 每天 1 点重新初始化;
  • 晚上 8 点 33 分将 3 首歌曲组成名为"临时列表1"的临时歌单,并从"11宝葫芦的秘密"开始播放;其中arg1first均为可选字段。

各任务类型深入解析

play:定时播放歌曲

add_job_play内部调用xiaomusic.play(did, arg1)。从 xiaomusic.py 的实现看,play还支持用|分隔"搜索关键词"和"显示名称":parts = arg1.split("|"),第一个元素作为搜索关键词,第二个元素作为歌曲名称(缺省时名称即关键词)。

play_music_list:定时播放列表

add_job_play_music_list调用xiaomusic.play_music_list(did, arg1)。在 xiaomusic.py 中,arg1|拆分为列表名与可选歌曲名,最终经do_play_music_list校验列表存在性后,交给设备播放器执行;若列表不存在,音箱会 TTS 播报"播放列表xx不存在"。

play_music_tmp_list:定时播放自定义临时歌单

这是把多首歌曲临时拼成一个歌单播放的任务,也是结构最特殊的一条(crontab.py 中add_job_play_music_tmp_list):

  • arg1:临时歌单名称,可选,缺省为crontab_tmp_list
  • music_list:歌曲名数组,必填;
  • first:起始播放的歌曲名,可选。

其执行流程为:先通过music_library.play_list_update_music(name, music_list)以"覆盖"方式写入自定义歌单(歌单不存在则自动新建,见 music_library.py),再调用do_play_music_list(did, name, music_name)从指定歌曲开始播放。

tts:定时语音播报

add_job_tts调用xiaomusic.do_tts(did, arg1),将arg1的文字内容通过小爱音箱播报出来,适合做起床提醒、整点报时等场景。

refresh_music_list:定时刷新曲库

add_job_refresh_music_list调用xiaomusic.gen_music_list(),用于自动更新音乐目录下的歌曲到播放列表。从 music_library.py 看,刷新时会按配置的music_pathmusic_path_depth(目录深度)、exclude_dirs(排除目录)以及SUPPORT_MUSIC_TYPE(支持的音频扩展名)重新遍历音乐目录并重建列表。若设置了enable_file_watch目录监控,新增歌曲可被自动感知,而定时刷新则是一种不依赖监控的兜底方案。

set_volume:定时设置音量

add_job_set_volume调用xiaomusic.set_volume(did, arg1)arg1为 0–100 的整数音量值。示例中* * * * *即每分钟执行一次,可用于持续校正音量。

set_play_type:定时切换播放模式

add_job_set_play_typearg1转为整数后调用xiaomusic.set_play_type(did, play_type, False),第三个参数False表示切换时不做 TTS 语音播报。对应关系见上文表格(0 单曲循环 / 1 全部循环 / 2 随机播放 / 3 单曲播放 / 4 顺序播放)。

set_pull_ask:定时开关对话记录拉取

add_job_set_pull_ask通过arg1enabledisable直接切换config.enable_pull_ask布尔值(其余值一律视为关闭)。该开关控制是否向小爱音箱拉取对话记录,官方文档提示:每天定时关闭可缓解风控问题,因此常见做法是白天开启、夜间关闭(如示例中 6 点 enable、0 点 disable)。

reinit:定时重新初始化

add_job_reinit调用xiaomusic.reinit()。在 xiaomusic.py 中,reinit会重新初始化日志、调用auth_manager.init_all_data()重建登录认证数据,并重新生成音乐列表与播放列表。官方文档建议每天执行一次以缓解登录失效问题。

stop:定时关机

add_job_stop调用xiaomusic.stop(did, "notts")"notts"参数表示关机前不做 TTS 播报。典型组合是"工作日 8 点播放叫醒歌曲 + 8 点 10 分关机",让音箱完成叫醒后自动进入待机。

进阶用法:按工作日/休息日限定执行

针对"工作日执行、休息日不执行"的需求,项目在 crontab.py 中实现了CustomCronTrigger自定义触发器,支持在expression末尾追加特殊注释标记:

  • 末尾加#workday:仅在法定工作日执行;
  • 末尾加#offday:仅在法定休息日执行(含法定节假日与周末)。

示例:

[ { "expression": "0 8 * * * #workday", "name": "play", "did": "123456789", "arg1": "周杰伦晴天" }, { "expression": "0 10 * * * #offday", "name": "play", "did": "123456789", "arg1": "周杰伦晴天" } ]

其实现原理是:CustomCronTrigger.get_next_fire_time()先用基础CronTrigger算出下一个候选触发时间,再根据标记调用 holiday.py 中的is_working_day()is_off_day()校验当天是否满足条件,若不满足则递归寻找下一个候选时间。节假日判断依赖仓库holiday/目录下按年份组织的 JSON 数据(如 holiday/2025.json),数据加载逻辑见load_year_data():优先查表判定法定调休日,表中没有的日期则按周末(周六、周日)判定。因此该功能可直接覆盖春节、国庆等法定节假日以及调休上班日,比单纯用 crontab 的星期字段精确得多。

Crontab.add_job()中会检测expression是否包含workday/offday标记,自动选用CustomCronTrigger还是标准CronTrigger,用户无需手动指定。

配置校验与排障建议

  • JSON 合法性:定时任务是整段 JSON 数组,任何语法错误都会导致reload_config解析失败。建议先用 JSON 校验工具检查配置是否合法后再粘贴到设置页。
  • 表达式合法性:非法 crontab 表达式会在注册时抛出ValueError,日志中输出Invalid crontab expression ...,该任务会被跳过,不影响其他任务注册。
  • name 拼写add_job_cronadd_job_{name}反射调用,name不在支持列表时日志会报object has no attribute 'add_job_xxx',任务不生效。
  • did 归属did必须对应当前设备列表中的音箱 ID,即设置页面"音箱型号"后的那串数字,填写错误会导致任务找不到设备。
  • 日志观察:每次加载成功都会打印crontab reload_config ok及每条任务注册信息(crontab add_job_cron ok. did:... name:... arg1:... expression:...),可据此确认任务是否被正确解析。
  • 运行时状态set_pull_askset_play_type等状态类任务会实时修改运行内存中的配置,配合 Web 设置页可以观察对应开关的实际状态。

小结

xiaomusic 的定时任务功能把标准 crontab 语法与音箱控制命令完整打通:一份 JSON 数组即可编排播放、关机、播报、刷新曲库、调整音量/播放模式、开关对话拉取、重新初始化等全部受支持操作,并可借助#workday/#offday标记叠加法定节假日判断,实现贴近真实生活的作息自动化。相关实现均可对照 crontab.py、holiday.py、xiaomusic.py 与 music_library.py 等源码深入研读。

【免费下载链接】xiaomusic使用小爱音箱播放音乐,音乐使用 yt-dlp 下载。项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询