1
0
mirror of https://github.com/hanxi/xiaomusic.git synced 2025-12-06 14:52:50 +08:00

Compare commits

...

12 Commits

Author SHA1 Message Date
涵曦
bb0cf943ef bump: version 0.3.79 → 0.3.80 2025-05-18 14:30:10 +08:00
涵曦
9f520eac11 build: update static version 2025-05-18 14:30:09 +08:00
Issues Docs [BOT]
d9301dce23 Auto-Generate docs 🤖 2025-05-18 06:29:07 +00:00
涵曦
609fc9f661 Update README.md 2025-05-18 14:27:16 +08:00
涵曦
22704e15fd feat: 新增 OH2 型号的支持 2025-05-18 14:25:35 +08:00
Issues Docs [BOT]
eead12643d Auto-Generate docs 🤖 2025-05-18 04:40:00 +00:00
Issues Docs [BOT]
4838070f50 Auto-Generate docs 🤖 2025-05-15 04:19:50 +00:00
lucas
9e03c26f3f fix: 修复获取在线歌曲长度 (#469)
修复获取歌长度
2025-05-11 21:52:41 +08:00
Issues Docs [BOT]
c7c54e9446 Auto-Generate docs 🤖 2025-05-08 04:36:50 +00:00
涵曦
0690f4846e feat: 支持配置最大搜索歌曲数量 see #462 2025-05-07 22:05:52 +08:00
Issues Docs [BOT]
eb39281eb7 Auto-Generate docs 🤖 2025-05-07 13:42:13 +00:00
Issues Docs [BOT]
f12af9b8e8 Auto-Generate docs 🤖 2025-04-29 15:42:51 +00:00
19 changed files with 136 additions and 27 deletions

View File

@@ -1,3 +1,14 @@
## v0.3.80 (2025-05-18)
### Feat
- 新增 OH2 型号的支持
- 支持配置最大搜索歌曲数量 see #462
### Fix
- 修复获取在线歌曲长度 (#469)
## v0.3.79 (2025-04-29)
### Fix

View File

@@ -208,6 +208,7 @@ docker build -t xiaomusic .
| X08C X08E X8F | 已经不需要设置了. ~需要设置【型号兼容模式】选项为 true~ |
| M01/XMYX01JY | 小米小爱音箱HD 需要设置【特殊型号获取对话记录】选项为 true 才能语音播放|
| OH2P | XIAOMI 智能音箱 Pro |
| OH2 | XIAOMI 智能音箱 |
型号与产品名称对照可以在这里查询 <https://home.miot-spec.com/s/xiaomi.wifispeaker>

View File

@@ -77,7 +77,7 @@ docker tag m.daocloud.io/docker.io/hanxi/xiaomusic:latest hanxi/xiaomusic:latest
---
### 评论 4 - ginitaimeiyty
### 评论 4 - SenyFish
如果手头上有能科学上网的机器直接把群辉的代理服务器IP填写成可以科学上网的机器IP+端口,翻墙软件打开允许局域网连接就可以

View File

@@ -70,5 +70,40 @@ docker compose down
## 评论
没有评论。
### 评论 1 - tiger326
我用这个是可以正常启动和搭建好xiaomusic, 一切都OK.
不过我的NAS是qnap, 已禁用默认的admin用户, 使用自建的管理员账户登录.
但这个配置会默认使用admin用户执行, 导致一旦产生tmp和download目录以及相关文件, 都归属于admin用户.
结果我自建的用户在NAS上无法删除和编辑这些下载的文件.
xiaomusic是否支持创建时指定用户和用户组?
---
### 评论 2 - hanxi
@tiger326 把下面的 username 换成普通的用户名即可,换成 uid 数字也行,一般是 1000
```shell
mkdir -p /xiaomusic
cat <<EOF > /xiaomusic/docker-compose.yml
services:
xiaomusic:
image: docker.hanxi.cc/hanxi/xiaomusic
container_name: xiaomusic
restart: unless-stopped
user: username
ports:
- 58090:8090
environment:
XIAOMUSIC_PUBLIC_PORT: 58090
volumes:
- /xiaomusic_conf:/app/conf
- /xiaomusic_music:/app/music
EOF
```
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/360)

View File

@@ -4,7 +4,7 @@ title: 微信交流群二维码
# 微信交流群二维码
![Image](https://gproxy.hanxi.cc/proxy/user-attachments/assets/63ac02ae-2051-46cf-9865-a81b5acde65d)
![Image](https://gproxy.hanxi.cc/proxy/user-attachments/assets/2c9f4708-8564-44e1-854b-17426e638923)
如果你刚好在买流量卡,可以在我的微信卡店里看看有没有合适的。
![mmexportc6bd050862507d2806a2da710a82cb28_1735878113870](https://gproxy.hanxi.cc/proxy/user-attachments/assets/ca5a86e0-f753-42d3-8dcb-8583d50d64aa)

View File

@@ -1639,5 +1639,23 @@ ZZZZZZ最后发现是没刷新页面, 收藏没刷新出来. 语音命令是有
部署在我台式机上,关闭了防火墙,台式机与小爱音箱连接了同一个热点
---
### 评论 105 - ocean412257013
请教 在build的时候报错是哪个意思
![Image](https://gproxy.hanxi.cc/proxy/user-attachments/assets/8e6df9f7-0dd1-4bea-b584-c271073a7411)
---
### 评论 106 - hanxi
> 请教 在build的时候报错是哪个意思
>
> ![Image](https://gproxy.hanxi.cc/proxy/user-attachments/assets/8e6df9f7-0dd1-4bea-b584-c271073a7411)
换个国内的镜像。
---
[链接到 GitHub Issue](https://github.com/hanxi/xiaomusic/issues/99)

View File

@@ -1,5 +1,11 @@
# 版本日志
## v0.3.79 (2025-04-29)
### Fix
- 修复型号LX05不能播放问题
## v0.3.78 (2025-04-09)
### Feat

View File

@@ -208,6 +208,7 @@ docker build -t xiaomusic .
| X08C X08E X8F | 已经不需要设置了. ~需要设置【型号兼容模式】选项为 true~ |
| M01/XMYX01JY | 小米小爱音箱HD 需要设置【特殊型号获取对话记录】选项为 true 才能语音播放|
| OH2P | XIAOMI 智能音箱 Pro |
| OH2 | XIAOMI 智能音箱 |
型号与产品名称对照可以在这里查询 <https://home.miot-spec.com/s/xiaomi.wifispeaker>

View File

@@ -1,6 +1,6 @@
[project]
name = "xiaomusic"
version = "0.3.79"
version = "0.3.80"
description = "Play Music with xiaomi AI speaker"
authors = [
{name = "涵曦", email = "im.hanxi@gmail.com"},

View File

@@ -1 +1 @@
__version__ = "0.3.79"
__version__ = "0.3.80"

View File

@@ -216,6 +216,8 @@ class Config:
enable_cmd_del_music: bool = (
os.getenv("XIAOMUSIC_ENABLE_CMD_DEL_MUSIC", "false").lower() == "true"
)
# 搜索歌曲数量
search_music_count: int = int(os.getenv("XIAOMUSIC_SEARCH_MUSIC_COUNT", "100"))
def append_keyword(self, keys, action):
for key in keys.split(","):

View File

@@ -29,10 +29,13 @@ NEED_USE_PLAY_MUSIC_API = [
"X8F",
"X4B",
"LX05",
"OH2",
"OH2P",
]
# 有 tts command 的设备型号
TTS_COMMAND = {
"OH2": "5-3",
"OH2P": "7-3",
"LX06": "5-1",
"S12": "5-1",

View File

@@ -6,9 +6,9 @@
<meta name="viewport" content="width=device-width">
<title>Debug For XiaoMusic</title>
<link rel="stylesheet" type="text/css" href="./main.css?version=1745941221">
<link rel="stylesheet" type="text/css" href="./main.css?version=1747549809">
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script src="./jquery-3.7.1.min.js?version=1745941221"></script>
<script src="./jquery-3.7.1.min.js?version=1747549809"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@@ -4,8 +4,8 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<title>歌曲下载工具</title>
<link rel="stylesheet" type="text/css" href="./main.css?version=1745941221">
<script src="./jquery-3.7.1.min.js?version=1745941221"></script>
<link rel="stylesheet" type="text/css" href="./main.css?version=1747549809">
<script src="./jquery-3.7.1.min.js?version=1747549809"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@@ -6,8 +6,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小爱音箱操控面板</title>
<link href="https://fonts.googleapis.com/css?family=Material+Icons|Material+Icons+Outlined" rel="stylesheet">
<script src="./jquery-3.7.1.min.js?version=1745941221"></script>
<link rel="stylesheet" href="./main.css?version=1745941221">
<script src="./jquery-3.7.1.min.js?version=1747549809"></script>
<link rel="stylesheet" href="./main.css?version=1747549809">
<link rel="icon" href="./favicon.ico">
<!-- Google tag (gtag.js) -->
@@ -219,7 +219,7 @@
Powered by XiaoMusic
</div>
<script src="./md.js?version=1745941221">
<script src="./md.js?version=1747549809">
</script>
</body>

View File

@@ -5,7 +5,7 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width">
<title>M3U to JSON Converter</title>
<link rel="stylesheet" type="text/css" href="./main.css?version=1745941221">
<link rel="stylesheet" type="text/css" href="./main.css?version=1747549809">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@@ -5,9 +5,9 @@
<meta name="viewport" content="width=device-width">
<title>小爱音箱操控面板</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="./jquery-3.7.1.min.js?version=1745941221"></script>
<script src="./setting.js?version=1745941221"></script>
<link rel="stylesheet" type="text/css" href="./main.css?version=1745941221">
<script src="./jquery-3.7.1.min.js?version=1747549809"></script>
<script src="./setting.js?version=1747549809"></script>
<link rel="stylesheet" type="text/css" href="./main.css?version=1747549809">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
@@ -120,6 +120,9 @@ var vConsole = new window.VConsole();
<label for="music_path_depth">目录深度:</label>
<input id="music_path_depth" type="number" value="10" />
<label for="search_music_count">搜索歌曲数量:</label>
<input id="search_music_count" type="number" value="100" />
<label for="search_prefix">XIAOMUSIC_SEARCH(歌曲下载方式):</label>
<select id="search_prefix">
<option value="bilisearch:">bilisearch:</option>

View File

@@ -292,16 +292,41 @@ def is_m4a(url):
async def _get_web_music_duration(session, url, config, start=0, end=500):
"""
异步获取网络音乐文件的部分内容并估算其时长。
通过请求 URL 的前几个字节(默认 0-500下载部分文件
写入临时文件后调用本地工具(如 ffprobe获取音频时长。
:param session: aiohttp.ClientSession 实例
:param url: 音乐文件的 URL 地址
:param config: 包含配置信息的对象(如 ffmpeg 路径)
:param start: 请求的起始字节位置
:param end: 请求的结束字节位置
:return: 返回音频的持续时间(秒),如果失败则返回 0
"""
duration = 0
# 设置请求头 Range只请求部分内容用于快速获取元数据
headers = {"Range": f"bytes={start}-{end}"}
# 使用 aiohttp 异步发起 GET 请求,获取部分音频内容
async with session.get(url, headers=headers) as response:
array_buffer = await response.read()
with tempfile.NamedTemporaryFile() as tmp:
tmp.write(array_buffer)
try:
duration = await get_local_music_duration(tmp, config)
except Exception as e:
log.error(f"Error _get_web_music_duration: {e}")
array_buffer = await response.read() # 读取响应的二进制内容
# 创建一个命名的临时文件,并禁用自动删除(以便后续读取)
with tempfile.NamedTemporaryFile(delete=False) as tmp:
tmp.write(array_buffer) # 将下载的部分内容写入临时文件
tmp_path = tmp.name # 获取该临时文件的真实路径
try:
# 调用 get_local_music_duration 并传入文件路径,而不是文件对象
duration = await get_local_music_duration(tmp_path, config)
except Exception as e:
log.error(f"Error _get_web_music_duration: {e}")
finally:
# 手动删除临时文件,避免残留
os.unlink(tmp_path)
return duration

View File

@@ -956,7 +956,7 @@ class XiaoMusic:
self.log.info(f"未匹配到指令 {query} {ctrl_panel}")
return (None, None)
def find_real_music_name(self, name, n=100):
def find_real_music_name(self, name, n):
if not self.config.enable_fuzzy_match:
self.log.debug("没开启模糊匹配")
return []
@@ -1572,7 +1572,9 @@ class XiaoMusicDevice:
if exact:
names = self.xiaomusic.find_real_music_name(name, n=1)
else:
names = self.xiaomusic.find_real_music_name(name)
names = self.xiaomusic.find_real_music_name(
name, n=self.config.search_music_count
)
if len(names) > 0:
if not exact:
if len(names) > 1: # 大于一首歌才更新
@@ -1659,7 +1661,9 @@ class XiaoMusicDevice:
if exact:
names = self.xiaomusic.find_real_music_name(name, n=1)
else:
names = self.xiaomusic.find_real_music_name(name)
names = self.xiaomusic.find_real_music_name(
name, n=self.config.search_music_count
)
if len(names) > 0:
if not exact:
if len(names) > 1: # 大于一首歌才更新
@@ -1931,7 +1935,7 @@ class XiaoMusicDevice:
# 有 tts command 优先使用 tts command 说话
if self.hardware in TTS_COMMAND:
tts_cmd = TTS_COMMAND[self.hardware]
self.log.debug("Call MiIOService tts.")
self.log.info("Call MiIOService tts.")
value = value.replace(" ", ",") # 不能有空格
await miio_command(
self.xiaomusic.miio_service,