xiaomusic项目新增单曲播放和顺序播放功能的技术解析

xiaomusic项目新增单曲播放和顺序播放功能的技术解析

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

痛点场景:传统播放模式的局限性

你是否曾经遇到过这样的困扰?在使用小爱音箱播放音乐时,只能选择单曲循环随机播放,想要按顺序欣赏整张专辑却无从下手?或者只想听一首歌就停止,而不是无限循环?这正是许多音乐爱好者在使用智能音箱时的共同痛点。

xiaomusic项目最新版本针对这一需求痛点,新增了**单曲播放(PLAY_TYPE_SIN)顺序播放(PLAY_TYPE_SEQ)**两大功能,彻底解决了传统播放模式的局限性。

功能特性对比

播放模式常量值语音口令行为描述
单曲循环PLAY_TYPE_ONE = 0"单曲循环"当前歌曲播放完成后自动重新播放
全部循环PLAY_TYPE_ALL = 1"全部循环"播放完列表后从头开始循环
随机播放PLAY_TYPE_RND = 2"随机播放"随机选择列表中的歌曲播放
单曲播放PLAY_TYPE_SIN = 3"单曲播放"播放当前歌曲后自动停止
顺序播放PLAY_TYPE_SEQ = 4"顺序播放"按列表顺序播放,播完后停止

技术架构解析

核心常量定义

xiaomusic/const.py 中新增了两个播放类型常量:

PLAY_TYPE_SIN = 3  # 单曲播放
PLAY_TYPE_SEQ = 4  # 顺序播放

播放控制逻辑实现

XiaoMusicDevice 类的 set_play_type 方法中,新增了对两种新播放模式的处理:

async def set_play_type(self, play_type, dotts=True):
    if play_type == PLAY_TYPE_ONE:
        # 单曲循环逻辑
        tts_msg = self.xiaomusic.config.XIAOMUSIC_PLAY_TYPE_ONE_TTS_MSG
    elif play_type == PLAY_TYPE_ALL:
        # 全部循环逻辑
        tts_msg = self.xiaomusic.config.XIAOMUSIC_PLAY_TYPE_ALL_TTS_MSG
    elif play_type == PLAY_TYPE_RND:
        # 随机播放逻辑
        tts_msg = self.xiaomusic.config.XIAOMUSIC_PLAY_TYPE_RND_TTS_MSG
    elif play_type == PLAY_TYPE_SIN:
        # 单曲播放逻辑 - 新增
        tts_msg = self.xiaomusic.config.XIAOMUSIC_PLAY_TYPE_SIN_TTS_MSG
    elif play_type == PLAY_TYPE_SEQ:
        # 顺序播放逻辑 - 新增
        tts_msg = self.xiaomusic.config.XIAOMUSIC_PLAY_TYPE_SEQ_TTS_MSG
    
    self.play_type = play_type
    if dotts:
        await self.tts(tts_msg)

播放队列管理

在歌曲播放完成的处理逻辑中,根据不同的播放类型采取不同的行为:

# 在播放完成后的处理逻辑中
if self.device.play_type == PLAY_TYPE_SIN:
    # 单曲播放模式:播放完成后停止
    await self.stop()
elif self.device.play_type == PLAY_TYPE_SEQ:
    # 顺序播放模式:按顺序播放下一首
    if self._current_index < len(self._play_list) - 1:
        self._current_index += 1
        await self.play_music_by_index(self._current_index)
    else:
        # 播放到最后一首后停止
        await self.stop()
elif self.device.play_type == PLAY_TYPE_ALL:
    # 全部循环模式
    self._current_index = (self._current_index + 1) % len(self._play_list)
    await self.play_music_by_index(self._current_index)

语音控制集成

口令映射配置

在配置文件中对语音口令进行映射:

{
  "单曲循环": "set_play_type_one",
  "全部循环": "set_play_type_all", 
  "随机播放": "set_play_type_rnd",
  "单曲播放": "set_play_type_sin",
  "顺序播放": "set_play_type_seq"
}

TTS反馈消息

新增对应的语音反馈配置:

XIAOMUSIC_PLAY_TYPE_SIN_TTS_MSG = "已经设置为单曲播放"
XIAOMUSIC_PLAY_TYPE_SEQ_TTS_MSG = "已经设置为顺序播放"

前端界面适配

播放状态显示

在前端JavaScript代码中新增了对两种新播放模式的识别和显示:

const PLAY_TYPE_SIN = 3; // 单曲播放
const PLAY_TYPE_SEQ = 4; // 顺序播放

function updatePlayTypeDisplay() {
  if (cur_device.play_type == PLAY_TYPE_SIN) {
    $("#play_type").text("单曲播放");
  } else if (cur_device.play_type == PLAY_TYPE_SEQ) {
    $("#play_type").text("顺序播放");
  }
  // ... 其他播放模式
}

技术实现难点与解决方案

难点一:播放状态机管理

问题:需要维护复杂的播放状态转换逻辑,确保各种播放模式之间的平滑切换。

解决方案:采用状态模式(State Pattern)设计,每个播放类型对应一个独立的状态处理类:

class PlayState:
    async def next_song(self, player):
        pass

class SinglePlayState(PlayState):
    async def next_song(self, player):
        await player.stop()

class SequentialPlayState(PlayState):
    async def next_song(self, player):
        if player.current_index < len(player.playlist) - 1:
            player.current_index += 1
            await player.play_by_index(player.current_index)
        else:
            await player.stop()

难点二:异步操作协调

问题:播放控制涉及多个异步操作(网络请求、音频播放、状态更新),需要确保操作顺序正确。

解决方案:使用asyncio的协程和事件循环机制,确保异步操作的顺序执行:

async def handle_playback_completion(self):
    # 获取当前播放状态
    current_state = self.get_play_state()
    
    # 根据状态执行相应的后续操作
    await current_state.next_song(self)
    
    # 更新前端状态
    await self.update_frontend_status()

使用示例与最佳实践

基本使用

# 设置单曲播放模式
await xiaomusic.set_play_type(did, PLAY_TYPE_SIN)

# 设置顺序播放模式  
await xiaomusic.set_play_type(did, PLAY_TYPE_SEQ)

# 播放特定歌曲
await xiaomusic.play("周杰伦-晴天")

语音控制示例

对小爱音箱说:

  • "单曲播放" - 切换到单曲播放模式
  • "顺序播放" - 切换到顺序播放模式
  • "播放歌曲 周杰伦晴天" - 播放指定歌曲

高级应用场景

场景一:睡前音乐定时停止

# 设置单曲播放模式,播放一首助眠音乐后自动停止
await device.set_play_type(PLAY_TYPE_SIN)
await device.play("纯音乐-睡眠曲")

场景二:专辑顺序欣赏

# 设置顺序播放模式,完整欣赏整张专辑
await device.set_play_type(PLAY_TYPE_SEQ)
await device.play_music_list("周杰伦-范特西")

性能优化与注意事项

内存管理

新增播放模式不会增加额外的内存开销,因为:

  • 播放状态使用整型常量存储
  • 状态切换只涉及简单的赋值操作
  • 播放逻辑复用现有的队列管理机制

兼容性考虑

  • 向后兼容所有现有播放模式
  • 支持所有已测试的小爱音箱设备型号
  • 不影响现有的网络歌单和本地音乐功能

错误处理

try:
    await self.set_play_type(did, play_type)
except Exception as e:
    self.log.error(f"设置播放模式失败: {e}")
    # 回退到默认的随机播放模式
    await self.set_play_type(did, PLAY_TYPE_RND)

总结与展望

xiaomusic项目新增的单曲播放和顺序播放功能,填补了智能音箱音乐播放场景的重要空白。通过精心的技术设计和实现,提供了:

  1. 更精准的播放控制:满足不同场景下的音乐播放需求
  2. 完善的语音集成:保持与小爱音箱原生体验的一致性

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

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

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值