1
0
mirror of https://github.com/hanxi/xiaomusic.git synced 2025-12-09 15:18:15 +08:00

Compare commits

..

33 Commits

Author SHA1 Message Date
涵曦
aa2992b5d7 bump: version 0.3.41 → 0.3.42 2024-10-24 11:00:00 +08:00
涵曦
7fcd3eeae5 build: update static version 2024-10-24 10:59:59 +08:00
涵曦
30194272d9 Update ci.yml 2024-10-23 19:01:53 +08:00
涵曦
1b71301b06 Update Dockerfile 2024-10-23 18:26:14 +08:00
涵曦
13bbff8d67 Update ci.yml 2024-10-23 17:22:47 +08:00
涵曦
ae3507b811 Update ci.yml 2024-10-23 16:53:37 +08:00
涵曦
bdfb0a4127 ci: update ci 2024-10-23 15:31:04 +08:00
涵曦
3d0a38cbb8 build: 尝试修复 arm 平台的容器下不能启动的问题 2024-10-23 14:08:29 +08:00
涵曦
f469f63d97 fix: 尝试修复缺少 libtiff.so.6 文件的问题 #244 2024-10-23 06:22:00 +08:00
涵曦
6544bb2ff1 fix: 修复默认主题播放歌曲输入框空的情况 2024-10-21 22:59:38 +08:00
涵曦
668237401e fix: 尝试修复停止后自动播放的问题 2024-10-21 22:53:37 +08:00
涵曦
139ebf37c4 Update README.md 2024-10-21 19:40:33 +08:00
涵曦
7146d61fcb Update README.md 2024-10-18 01:14:41 +08:00
涵曦
6033c1a6fc Update README.md 2024-10-18 01:14:02 +08:00
涵曦
e77a4fc10d bump: version 0.3.40 → 0.3.41 2024-10-17 23:49:21 +08:00
涵曦
bf2909d35a build: update static version 2024-10-17 23:49:20 +08:00
涵曦
b3255a17ce fix: 修复获取标签信息报错问题 2024-10-17 23:35:38 +08:00
Gao, Ruiyuan
a3140ff23a fix: remove_id3_tags return None if no id3 tag (#238)
* fix: remove_id3_tags return None if no id3 tag

* Auto-format code 🧹🌟🤖

---------

Co-authored-by: Formatter [BOT] <runner@fv-az885-171.m43iyx0u3v4e1h2pvvlabjukza.cx.internal.cloudapp.net>
2024-10-17 11:36:48 +08:00
Gao, Ruiyuan
becfdbf338 fix: bug in del_music (#237) 2024-10-17 10:25:25 +08:00
涵曦
8b74b664f0 feat: 设置默认时区为东八区 closed #236 2024-10-17 08:18:54 +08:00
涵曦
0daba20885 bump: version 0.3.39 → 0.3.40 2024-10-16 21:44:05 +08:00
涵曦
8ac39af8cd build: update static version 2024-10-16 21:44:04 +08:00
涵曦
d6fb62eb8e feat: 默认主题的播放列表上显示歌曲数量 2024-10-16 13:00:09 +08:00
涵曦
24ac876632 fix: 修复播放卡顿问题(谷歌统计地址无法访问的情况) 2024-10-16 12:42:22 +08:00
涵曦
fcdb7bf035 Update README.md 2024-10-16 01:14:22 +08:00
涵曦
4c927c56c0 bump: version 0.3.38 → 0.3.39 2024-10-15 21:58:42 +08:00
涵曦
3a7672982f build: update static version 2024-10-15 21:58:41 +08:00
涵曦
a3ddca05a3 style: 修改提示 2024-10-15 20:34:39 +08:00
涵曦
e9dba716b7 feat: 固定的播放列表全部初始化 2024-10-15 12:02:19 +08:00
Gao, Ruiyuan
6ed5d0cb5f bug: sort results from keyword search (#232)
* bug: sort results from keyword search

* Auto-format code 🧹🌟🤖

---------

Co-authored-by: Formatter [BOT] <runner@fv-az1538-928.upsp13a5k4ou3ds4kr34xzh2lh.cx.internal.cloudapp.net>
2024-10-15 06:42:11 +08:00
Gao, Ruiyuan
44819de3a5 refactor: 修改默认UI播放提示词 (#233) 2024-10-15 06:41:05 +08:00
52fisher
043ad12dec fix: pure主题 当前设备与远程设备未正确区分的问题 (#234)
feat: 生产环境与开发环境接口分离、关于页面增加返回到主页的链接
update: 支持https页面未及时更新的问题
2024-10-15 06:36:46 +08:00
Gao, Ruiyuan
cc5facdf4f fix: static和doc添加basic auth (#231)
* bug: static和doc添加basic auth

* Auto-format code 🧹🌟🤖

---------

Co-authored-by: Formatter [BOT] <runner@fv-az1114-199.rwkmm4horakexguyojjdchjroh.cx.internal.cloudapp.net>
2024-10-14 14:00:55 +08:00
21 changed files with 302 additions and 118 deletions

View File

@@ -6,6 +6,9 @@ on:
- "*"
workflow_dispatch:
env:
TEST_TAG: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:${{ github.ref_name }}
jobs:
build-image:
runs-on: ubuntu-latest
@@ -14,21 +17,70 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
# We have to build each platform separately because when using multi-arch
# builds, only one platform is being loaded into the cache. This would
# prevent us from testing the other platforms.
- name: Build Docker image (linux/amd64)
uses: docker/build-push-action@v6
with:
platforms: linux/amd64
context: .
push: false
load: true
tags: ${{ env.TEST_TAG }}-linux-amd64
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Build Docker image (linux/arm64)
uses: docker/build-push-action@v6
with:
platforms: linux/arm64
context: .
push: false
load: true
tags: ${{ env.TEST_TAG }}-linux-arm64
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Build Docker image (linux/arm/v7)
uses: docker/build-push-action@v6
with:
platforms: linux/arm/v7
context: .
push: false
load: true
tags: ${{ env.TEST_TAG }}-linux-arm-v7
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
# We test all the images on amd64 host here. This uses QEMU to emulate
# the other platforms.
- run: docker run --rm ${TEST_TAG}-linux-amd64 -h
- run: docker run --rm ${TEST_TAG}-linux-arm64 -h
- run: docker run --rm ${TEST_TAG}-linux-arm-v7 -h
# This will only push the previously built images.
- name: Publish to Docker Hub
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64,linux/arm/v7
context: .
push: true
tags: ${{ secrets.DOCKERHUB_USERNAME }}/xiaomusic:${{ github.ref_name }}
tags: ${{ env.TEST_TAG }}
cache-from: type=local,src=/tmp/.buildx-cache-new
cache-to: type=local,dest=/tmp/.buildx-cache-new
- name: Docker Hub Description
uses: peter-evans/dockerhub-description@v4
with:

View File

@@ -1,3 +1,50 @@
## v0.3.42 (2024-10-24)
### Fix
- 尝试修复缺少 libtiff.so.6 文件的问题 #244
- 修复默认主题播放歌曲输入框空的情况
- 尝试修复停止后自动播放的问题
## v0.3.41 (2024-10-17)
### Feat
- 设置默认时区为东八区 closed #236
### Fix
- 修复获取标签信息报错问题
- remove_id3_tags return None if no id3 tag (#238)
- bug in del_music (#237)
## v0.3.40 (2024-10-16)
### Feat
- 默认主题的播放列表上显示歌曲数量
### Fix
- 修复播放卡顿问题(谷歌统计地址无法访问的情况)
## v0.3.39 (2024-10-15)
### Feat
- 固定的播放列表全部初始化
- 生产环境与开发环境接口分离、关于页面增加返回到主页的链接
update: 支持https页面未及时更新的问题
### Fix
- pure主题 当前设备与远程设备未正确区分的问题 (#234)
- static和doc添加basic auth (#231)
### Refactor
- 修改默认UI播放提示词 (#233)
## v0.3.38 (2024-10-14)
### Feat

View File

@@ -12,6 +12,13 @@ COPY install_dependencies.sh .
RUN bash install_dependencies.sh
FROM python:3.10-slim
RUN apt-get update && apt-get install -y \
libtiff6 \
libopenjp2-7 \
libxcb1 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=builder /app/.venv /app/.venv
COPY --from=builder /app/ffmpeg /app/ffmpeg
@@ -23,5 +30,6 @@ ENV XIAOMUSIC_PORT=8090
VOLUME /app/conf
VOLUME /app/music
EXPOSE 8090
ENV TZ=Asia/Shanghai
ENV PATH=/app/.venv/bin:$PATH
ENTRYPOINT [".venv/bin/python3","xiaomusic.py"]

View File

@@ -24,6 +24,12 @@
docker run -p 8090:8090 -v /xiaomusic/music:/app/music -v /xiaomusic/conf:/app/conf hanxi/xiaomusic
```
🔥 国内:
```bash
docker run -p 8090:8090 -v /xiaomusic/music:/app/music -v /xiaomusic/conf:/app/conf m.daocloud.io/docker.io/hanxi/xiaomusic
```
对应的 docker compose 配置如下:
```yaml
@@ -39,6 +45,21 @@ services:
- /xiaomusic/conf:/app/conf
```
🔥 国内:
```yaml
services:
xiaomusic:
image: m.daocloud.io/docker.io/hanxi/xiaomusic
container_name: xiaomusic
restart: unless-stopped
ports:
- 8090:8090
volumes:
- /xiaomusic/music:/app/music
- /xiaomusic/conf:/app/conf
```
其中 conf 目录为配置文件存放目录music 目录为音乐存放目录,建议分开配置为不同的目录。
> [!NOTE]
@@ -98,8 +119,6 @@ services:
> [!TIP]
> 隐藏玩法: 对小爱同学说播放歌曲小猪佩奇的故事,会先下载小猪佩奇的故事,然后再播放小猪佩奇的故事。
更多功能见 [📝 文档汇总](https://github.com/hanxi/xiaomusic/issues/211)
## 🛠️ pip 方式安装运行
```shell
@@ -281,22 +300,13 @@ docker build -t xiaomusic .
- [微信小程序: XIAO晓音](https://github.com/F-loat/xiaoplayer)
- [pure 主题 xiaomusicUI](https://github.com/52fisher/xiaomusicUI)
- [移动端的播放器主题](https://github.com/52fisher/XMusicPlayer)
- [一个第三方的主题](https://github.com/DarrenWen/xiaomusicui)
- 所有帮忙调试和测试的朋友
- 所有反馈问题和建议的朋友
### 👉 其他教程
> [!NOTE]
> 下面教程可能比较旧,只供参考
- [NAS部署教程](https://post.m.smzdm.com/p/avpe7n99/)
- [群晖部署教程](https://post.m.smzdm.com/p/a7px7dol/)
- [QNAS部署教程](https://post.smzdm.com/p/a5xz5x63/)
- [视频教程](https://www.bilibili.com/video/BV1ZZpweHEtT/)
- [TechHive](https://mp.weixin.qq.com/s/4a41muFtPaFKtHeZYu795w)
- [弹个AI](https://mp.weixin.qq.com/s/sIsKxB7Y8b83AhnvaWiMog)
- [简单免费教你用绿联NAS联动小爱音箱私人音乐库也能语音点播](https://post.m.smzdm.com/p/a8pldgg7/)
- [飞牛教程](https://mp.weixin.qq.com/s?t=pages/image_detail&__biz=MzkxODc1NDMwOA==&mid=2247483725&idx=1&sn=2d615f14733b9bf989557fa766b4e1fc)
更多功能见 [📝 文档汇总](https://github.com/hanxi/xiaomusic/issues/211)
## 🚨 免责声明

View File

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

View File

@@ -1 +1 @@
__version__ = "0.3.38"
__version__ = "0.3.42"

View File

@@ -11,6 +11,7 @@ class Analytics:
self.gtag = None
self.current_date = None
self.log = log
self.task = None
self.init()
def init(self):
@@ -27,16 +28,19 @@ class Analytics:
self.gtag = gtag
self.log.info("analytics init ok")
async def run_with_timeout(self, func, *args, **kwargs):
async def run_with_cancel(self, func, *args, **kwargs):
try:
return await asyncio.wait_for(func(*args, **kwargs), 3)
except asyncio.TimeoutError as e:
self.log.warning(f"analytics run_with_timeout failed {e}")
if self.task:
self.log.warning(f"analytics run_with_cancel old : {self.task}")
self.task.cancel()
self.task = asyncio.create_task(func(*args, **kwargs))
except Exception as e:
self.log.warning(f"analytics run_with_cancel failed {e}")
return None
async def send_startup_event(self):
try:
await self.run_with_timeout(self._send_startup_event)
await self.run_with_cancel(self._send_startup_event)
except Exception as e:
self.log.warning(f"analytics send_startup_event failed {e}")
self.init()
@@ -49,7 +53,7 @@ class Analytics:
async def send_daily_event(self):
try:
await self.run_with_timeout(self._send_daily_event)
await self.run_with_cancel(self._send_daily_event)
except Exception as e:
self.log.warning(f"analytics send_daily_event failed {e}")
self.init()
@@ -68,7 +72,7 @@ class Analytics:
async def send_play_event(self, name, sec):
try:
await self.run_with_timeout(self._send_play_event, name, sec)
await self.run_with_cancel(self._send_play_event, name, sec)
except Exception as e:
self.log.warning(f"analytics send_play_event failed {e}")
self.init()

View File

@@ -24,6 +24,8 @@ from fastapi import (
status,
)
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
from fastapi.openapi.utils import get_openapi
from fastapi.responses import RedirectResponse, StreamingResponse
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from fastapi.staticfiles import StaticFiles
@@ -92,6 +94,9 @@ def no_verification():
app = FastAPI(
lifespan=app_lifespan,
version=__version__,
docs_url=None,
redoc_url=None,
openapi_url=None,
)
app.add_middleware(
@@ -111,6 +116,17 @@ def reset_http_server():
app.dependency_overrides = {}
class AuthStaticFiles(StaticFiles):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
async def __call__(self, scope, receive, send) -> None:
request = Request(scope, receive)
if not config.disable_httpauth:
assert verification(await security(request))
await super().__call__(scope, receive, send)
def HttpInit(_xiaomusic):
global xiaomusic, config, log
xiaomusic = _xiaomusic
@@ -118,7 +134,7 @@ def HttpInit(_xiaomusic):
log = xiaomusic.log
folder = os.path.dirname(__file__)
app.mount("/static", StaticFiles(directory=f"{folder}/static"), name="static")
app.mount("/static", AuthStaticFiles(directory=f"{folder}/static"), name="static")
reset_http_server()
@@ -300,9 +316,9 @@ class MusicItem(BaseModel):
@app.post("/delmusic")
def delmusic(data: MusicItem, Verifcation=Depends(verification)):
async def delmusic(data: MusicItem, Verifcation=Depends(verification)):
log.info(data)
xiaomusic.del_music(data.name)
await xiaomusic.del_music(data.name)
return "success"
@@ -598,3 +614,18 @@ async def get_picture(request: Request, file_path: str, key: str = "", code: str
if mime_type is None:
mime_type = "image/jpeg"
return FileResponse(absolute_file_path, media_type=mime_type)
@app.get("/docs", include_in_schema=False)
async def get_swagger_documentation(Verifcation=Depends(verification)):
return get_swagger_ui_html(openapi_url="/openapi.json", title="docs")
@app.get("/redoc", include_in_schema=False)
async def get_redoc_documentation(Verifcation=Depends(verification)):
return get_redoc_html(openapi_url="/openapi.json", title="docs")
@app.get("/openapi.json", include_in_schema=False)
async def openapi(Verifcation=Depends(verification)):
return get_openapi(title=app.title, version=app.version, routes=app.routes)

View File

@@ -122,7 +122,8 @@ $(function(){
$.get("/musiclist", function(data, status) {
console.log(data, status);
$.each(data, function(key, value) {
$('#music_list').append($('<option></option>').val(key).text(key));
let cnt = value.length;
$('#music_list').append($('<option></option>').val(key).text(`${key} (${cnt})`));
});
$('#music_list').change(function() {
@@ -250,7 +251,13 @@ $(function(){
$("#play").on("click", () => {
var search_key = $("#music-name").val();
if (search_key == null) {
search_key = "";
}
var filename = $("#music-filename").val();
if (filename == null) {
filename = "";
}
let cmd = "播放歌曲" + search_key + "|" + filename;
sendcmd(cmd);
});
@@ -344,7 +351,7 @@ $(function(){
// 添加用户输入作为一个选项
const userOption = document.createElement('option');
userOption.value = query;
userOption.textContent = `使用关键词联网搜索: ${query}`;
userOption.textContent = `使用关键词播放: ${query}`;
musicSelect.appendChild(userOption);
// 提示没找到

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="./style.css?version=1728858679">
<link rel="stylesheet" type="text/css" href="./style.css?version=1729738799">
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
<script src="./jquery-3.7.1.min.js?version=1728858679"></script>
<script src="./jquery-3.7.1.min.js?version=1729738799"></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="./style.css?version=1728858679">
<script src="./jquery-3.7.1.min.js?version=1728858679"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1729738799">
<script src="./jquery-3.7.1.min.js?version=1729738799"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@@ -4,9 +4,9 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width">
<title>小爱音箱操控面板</title>
<script src="./jquery-3.7.1.min.js?version=1728858679"></script>
<script src="./app.js?version=1728858679"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1728858679">
<script src="./jquery-3.7.1.min.js?version=1729738799"></script>
<script src="./app.js?version=1729738799"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1729738799">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

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="./style.css?version=1728858679">
<link rel="stylesheet" type="text/css" href="./style.css?version=1729738799">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>

View File

@@ -4,9 +4,9 @@
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width">
<title>小爱音箱操控面板</title>
<script src="./jquery-3.7.1.min.js?version=1728858679"></script>
<script src="./setting.js?version=1728858679"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1728858679">
<script src="./jquery-3.7.1.min.js?version=1729738799"></script>
<script src="./setting.js?version=1729738799"></script>
<link rel="stylesheet" type="text/css" href="./style.css?version=1729738799">
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
@@ -59,7 +59,7 @@ var vConsole = new window.VConsole();
<option value="false">false</option>
</select>
<label for="group_list">设备分组配置:</label>
<label for="group_list">设备分组配置:<a href="https://github.com/hanxi/xiaomusic/issues/65#issuecomment-2215736529" target="_blank">文档</a></label>
<input id="group_list" type="text" placeholder="did1:组名1,did2:组名1,did3:组名2"></input>
<label for="music_path">音乐目录:</label>
@@ -99,19 +99,19 @@ var vConsole = new window.VConsole();
<label for="proxy">XIAOMUSIC_PROXY(ytsearch需要):</label>
<input id="proxy" type="text" placeholder="http://192.168.2.5:8080"></input>
<label for="remove_id3tag">去除MP3 ID3v2和填充,减少播放前延迟:</label>
<label for="remove_id3tag">去除MP3 ID3v2和填充:</label>
<select id="remove_id3tag">
<option value="true">true</option>
<option value="false" selected>false</option>
</select>
<label for="convert_to_mp3">转换为MP3</label>
<label for="convert_to_mp3">转换为MP3:</label>
<select id="convert_to_mp3">
<option value="true">true</option>
<option value="false" selected>false</option>
</select>
<label for="miio_tts_command">MiIO sst 指令:</label>
<label for="miio_tts_command">MiIO tts 指令(解决部分型号没有提示音的问题):</label>
<input id="miio_tts_command" type="text" placeholder="如5 或者 5-3"></input>
<label for="disable_httpauth">关闭控制台密码验证:</label>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -6,8 +6,8 @@
<link rel="icon" href="/static/pure/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>小爱音箱操控面板</title>
<script type="module" crossorigin src="/static/pure/assets/index-C0SgXQ6G.js"></script>
<link rel="stylesheet" crossorigin href="/static/pure/assets/index-DuznNR7f.css">
<script type="module" crossorigin src="/static/pure/assets/index-B19OeAC1.js"></script>
<link rel="stylesheet" crossorigin href="/static/pure/assets/index-co2Wfzfa.css">
</head>
<body>

View File

@@ -116,12 +116,19 @@ def keyword_detection(user_input, str_list, n):
else:
remains.append(item)
matched = sorted(
matched,
key=lambda s: difflib.SequenceMatcher(None, s, user_input).ratio(),
reverse=True, # 降序排序,越相似的越靠前
)
# 如果 n 是 -1如果 n 大于匹配的数量,返回所有匹配的结果
if n == -1 or n > len(matched):
return matched, remains
# 随机选择 n 个匹配的结果
return random.sample(matched, n), remains
# 选择 n 个匹配的结果
remains = matched[n:] + remains
return matched[:n], remains
def real_search(prompt, candidates, cutoff, n):
@@ -409,6 +416,15 @@ def get_temp_dir(music_path: str):
def remove_id3_tags(input_file: str, config) -> str:
audio = MP3(input_file, ID3=ID3)
# 检查是否存在ID3 v2.3或v2.4标签
if not (
audio.tags
and (audio.tags.version == (2, 3, 0) or audio.tags.version == (2, 4, 0))
):
return None
music_path = config.music_path
temp_dir = get_temp_dir(music_path)
@@ -429,22 +445,15 @@ def remove_id3_tags(input_file: str, config) -> str:
log.info(f"File {out_file_path} already exists. Skipping remove_id3_tags.")
return relative_path
audio = MP3(input_file, ID3=ID3)
# 检查是否存在ID3 v2.3或v2.4标签
if audio.tags and (
audio.tags.version == (2, 3, 0) or audio.tags.version == (2, 4, 0)
):
# 拷贝文件
shutil.copy(input_file, out_file_path)
outaudio = MP3(out_file_path, ID3=ID3)
# 删除ID3标签
outaudio.delete()
# 保存修改后的文件
outaudio.save(padding=no_padding)
log.info(f"File {out_file_path} remove_id3_tags ok.")
return relative_path
# 开始去除(不再需要检查)
# 拷贝文件
shutil.copy(input_file, out_file_path)
outaudio = MP3(out_file_path, ID3=ID3)
# 删除ID3标签
outaudio.delete()
# 保存修改后的文件
outaudio.save(padding=no_padding)
log.info(f"File {out_file_path} remove_id3_tags ok.")
return relative_path
@@ -584,7 +593,7 @@ def _to_utf8(v):
return ts
return old_ts
elif isinstance(v, list):
return "".join(v)
return "".join(str(item) for item in v)
return str(v)

View File

@@ -602,7 +602,17 @@ class XiaoMusic:
# self.log.debug(self.all_music)
self.music_list = OrderedDict({"临时搜索列表": []})
self.music_list = OrderedDict(
{
"临时搜索列表": [],
"所有歌曲": [],
"所有电台": [],
"收藏": [],
"全部": [], # 包含所有歌曲和所有电台
"下载": [], # 下载目录下的
"其他": [], # 主目录下的
}
)
# 全部,所有,自定义歌单(收藏)
self.music_list["全部"] = list(self.all_music.keys())
self.music_list["所有歌曲"] = [
@@ -882,7 +892,7 @@ class XiaoMusic:
self.log.info("gen_music_list ok")
# 删除歌曲
def del_music(self, name):
async def del_music(self, name):
filename = self.get_filename(name)
if filename == "":
self.log.info(f"${name} not exist")
@@ -1177,7 +1187,6 @@ class XiaoMusicDevice:
self._download_proc = None # 下载对象
self._next_timer = None
self._timeout = 0
self._playing = False
# 播放进度
self._start_time = 0
@@ -1667,14 +1676,17 @@ class XiaoMusicDevice:
# 设置下一首歌曲的播放定时器
async def set_next_music_timeout(self, sec):
self.cancel_next_timer()
self._timeout = sec
async def _do_next():
await asyncio.sleep(self._timeout)
await asyncio.sleep(sec)
try:
self.log.info("定时器时间到了")
self._next_timer = None
await self._play_next()
if self._next_timer:
self._next_timer = None
await self._play_next()
else:
self.log.info("定时器时间到了但是不见了")
except Exception as e:
self.log.error(f"Execption {e}")
@@ -1750,13 +1762,17 @@ class XiaoMusicDevice:
await self.do_tts(f"收到,{minute}分钟后将关机")
def cancel_next_timer(self):
self.log.info("cancel_next_timer")
if self._next_timer:
self._next_timer.cancel()
self.log.info(f"下一曲定时器已取消 {self.device_id}")
self._next_timer = None
else:
self.log.info("下一曲定时器不见了")
def cancel_group_next_timer(self):
devices = self.xiaomusic.get_group_devices(self.group_name)
self.log.info(f"cancel_group_next_timer {devices}")
for device in devices.values():
device.cancel_next_timer()