refactor: 处理 code review 问题'
This commit is contained in:
parent
4ab3c5cbee
commit
e72ae973bc
@ -12,9 +12,6 @@ COPY install_dependencies.sh .
|
|||||||
RUN bash install_dependencies.sh
|
RUN bash install_dependencies.sh
|
||||||
|
|
||||||
FROM python:3.10-slim
|
FROM python:3.10-slim
|
||||||
RUN pip install pydub
|
|
||||||
RUN python3 -m venv /app/.venv
|
|
||||||
RUN /app/.venv/bin/pip install pydub
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=builder /app/.venv /app/.venv
|
COPY --from=builder /app/.venv /app/.venv
|
||||||
COPY --from=builder /app/ffmpeg /app/ffmpeg
|
COPY --from=builder /app/ffmpeg /app/ffmpeg
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
"public_port": 0,
|
"public_port": 0,
|
||||||
"proxy": null,
|
"proxy": null,
|
||||||
"search_prefix": "bilisearch:",
|
"search_prefix": "bilisearch:",
|
||||||
"ffmpeg_location": "./ffmpeg/bin/ffmpeg",
|
"ffmpeg_location": "./ffmpeg/bin",
|
||||||
"active_cmd": "play,set_random_play,playlocal,play_music_list,stop",
|
"active_cmd": "play,set_random_play,playlocal,play_music_list,stop",
|
||||||
"exclude_dirs": "@eaDir",
|
"exclude_dirs": "@eaDir",
|
||||||
"music_path_depth": 10,
|
"music_path_depth": 10,
|
||||||
|
@ -3,7 +3,6 @@ import argparse
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import subprocess
|
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ class Config:
|
|||||||
search_prefix: str = os.getenv(
|
search_prefix: str = os.getenv(
|
||||||
"XIAOMUSIC_SEARCH", "bilisearch:"
|
"XIAOMUSIC_SEARCH", "bilisearch:"
|
||||||
) # "bilisearch:" or "ytsearch:"
|
) # "bilisearch:" or "ytsearch:"
|
||||||
ffmpeg_location: str = os.getenv("XIAOMUSIC_FFMPEG_LOCATION", "./ffmpeg/bin/ffmpeg")
|
ffmpeg_location: str = os.getenv("XIAOMUSIC_FFMPEG_LOCATION", "./ffmpeg/bin")
|
||||||
active_cmd: str = os.getenv(
|
active_cmd: str = os.getenv(
|
||||||
"XIAOMUSIC_ACTIVE_CMD", "play,set_random_play,playlocal,play_music_list,stop"
|
"XIAOMUSIC_ACTIVE_CMD", "play,set_random_play,playlocal,play_music_list,stop"
|
||||||
)
|
)
|
||||||
@ -136,9 +136,7 @@ class Config:
|
|||||||
remove_id3tag: bool = (
|
remove_id3tag: bool = (
|
||||||
os.getenv("XIAOMUSIC_REMOVE_ID3TAG", "false").lower() == "true"
|
os.getenv("XIAOMUSIC_REMOVE_ID3TAG", "false").lower() == "true"
|
||||||
)
|
)
|
||||||
convert_to_mp3: bool = (
|
convert_to_mp3: bool = os.getenv("CONVERT_TO_MP3", "false").lower() == "true"
|
||||||
os.getenv("CONVERT_TO_MP3", "false").lower() == "true"
|
|
||||||
)
|
|
||||||
delay_sec: int = int(os.getenv("XIAOMUSIC_DELAY_SEC", 3)) # 下一首歌延迟播放秒数
|
delay_sec: int = int(os.getenv("XIAOMUSIC_DELAY_SEC", 3)) # 下一首歌延迟播放秒数
|
||||||
|
|
||||||
def append_keyword(self, keys, action):
|
def append_keyword(self, keys, action):
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
# convert_to_mp3.py
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import tempfile
|
|
||||||
from pydub import AudioSegment
|
|
||||||
from pydub.playback import play
|
|
||||||
from xiaomusic.config import Config
|
|
||||||
|
|
||||||
class Convert_To_MP3:
|
|
||||||
def __init__(self, config: Config):
|
|
||||||
self.config = config
|
|
||||||
self.music_path = self.config.music_path
|
|
||||||
self.ffmpeg_location = self.config.ffmpeg_location
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def convert_to_mp3(input_file: str, ffmpeg_location: str, music_path: str) -> str:
|
|
||||||
"""
|
|
||||||
Convert the music file to MP3 format and return the path of the temporary MP3 file.
|
|
||||||
"""
|
|
||||||
# 指定临时文件的目录为 music_path 目录下的 tmp 文件夹
|
|
||||||
temp_dir = os.path.join(music_path, 'tmp')
|
|
||||||
if not os.path.exists(temp_dir):
|
|
||||||
os.makedirs(temp_dir) # 确保目录存在
|
|
||||||
|
|
||||||
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.mp3', dir=temp_dir)
|
|
||||||
temp_file.close()
|
|
||||||
temp_file_path = temp_file.name
|
|
||||||
|
|
||||||
command = [
|
|
||||||
ffmpeg_location,
|
|
||||||
'-i', input_file,
|
|
||||||
'-f', 'mp3',
|
|
||||||
'-y',
|
|
||||||
temp_file_path
|
|
||||||
]
|
|
||||||
|
|
||||||
try:
|
|
||||||
subprocess.run(command, check=True)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print(f"Error during conversion: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
return temp_file_path
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def convert_and_play(cls, input_file: str, ffmpeg_location: str):
|
|
||||||
"""
|
|
||||||
将音乐文件转码为 MP3 格式,播放,然后不删除临时文件,依赖于 xiaomusic 启动时的清理逻辑。
|
|
||||||
"""
|
|
||||||
temp_mp3_file = cls.convert_to_mp3(input_file, ffmpeg_location, cls.music_path)
|
|
||||||
if temp_mp3_file:
|
|
||||||
try:
|
|
||||||
# 假设 xiaomusic_playmusic 是一个播放 MP3 文件的函数
|
|
||||||
cls.xiaomusic.xiaomusic_playmusic(temp_mp3_file)
|
|
||||||
finally:
|
|
||||||
# 此处不再删除临时文件,依赖 xiaomusic 的清理逻辑
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print("Conversion failed")
|
|
@ -11,8 +11,8 @@ import random
|
|||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import string
|
import string
|
||||||
import tempfile
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import tempfile
|
||||||
from collections.abc import AsyncIterator
|
from collections.abc import AsyncIterator
|
||||||
from http.cookies import SimpleCookie
|
from http.cookies import SimpleCookie
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
@ -331,3 +331,35 @@ def remove_id3_tags(file_path):
|
|||||||
change = True
|
change = True
|
||||||
|
|
||||||
return change
|
return change
|
||||||
|
|
||||||
|
|
||||||
|
def convert_file_to_mp3(input_file: str, ffmpeg_location: str, music_path: str) -> str:
|
||||||
|
"""
|
||||||
|
Convert the music file to MP3 format and return the path of the temporary MP3 file.
|
||||||
|
"""
|
||||||
|
# 指定临时文件的目录为 music_path 目录下的 tmp 文件夹
|
||||||
|
temp_dir = os.path.join(music_path, "tmp")
|
||||||
|
if not os.path.exists(temp_dir):
|
||||||
|
os.makedirs(temp_dir) # 确保目录存在
|
||||||
|
|
||||||
|
out_file_name = os.path.splitext(os.path.basename(input_file))[0]
|
||||||
|
out_file_path = os.path.join(temp_dir, f"{out_file_name}.mp3")
|
||||||
|
|
||||||
|
command = [
|
||||||
|
os.path.join(ffmpeg_location, "ffmpeg"),
|
||||||
|
"-i",
|
||||||
|
input_file,
|
||||||
|
"-f",
|
||||||
|
"mp3",
|
||||||
|
"-y",
|
||||||
|
out_file_path,
|
||||||
|
]
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.run(command, check=True)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Error during conversion: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
relative_path = os.path.relpath(out_file_path, music_path)
|
||||||
|
return relative_path
|
||||||
|
@ -32,6 +32,7 @@ from xiaomusic.const import (
|
|||||||
)
|
)
|
||||||
from xiaomusic.plugin import PluginManager
|
from xiaomusic.plugin import PluginManager
|
||||||
from xiaomusic.utils import (
|
from xiaomusic.utils import (
|
||||||
|
convert_file_to_mp3,
|
||||||
custom_sort_key,
|
custom_sort_key,
|
||||||
deepcopy_data_no_sensitive_info,
|
deepcopy_data_no_sensitive_info,
|
||||||
find_best_match,
|
find_best_match,
|
||||||
@ -45,8 +46,6 @@ from xiaomusic.utils import (
|
|||||||
traverse_music_directory,
|
traverse_music_directory,
|
||||||
)
|
)
|
||||||
|
|
||||||
from xiaomusic.convert_to_mp3 import Convert_To_MP3
|
|
||||||
|
|
||||||
|
|
||||||
class XiaoMusic:
|
class XiaoMusic:
|
||||||
def __init__(self, config: Config):
|
def __init__(self, config: Config):
|
||||||
@ -66,12 +65,6 @@ class XiaoMusic:
|
|||||||
self.devices = {} # key 为 did
|
self.devices = {} # key 为 did
|
||||||
self.running_task = []
|
self.running_task = []
|
||||||
|
|
||||||
# 在程序启动时调用清理函数
|
|
||||||
self.cleanup_old_temp_files()
|
|
||||||
|
|
||||||
self.convert_to_mp3 = self.config.convert_to_mp3
|
|
||||||
self.ffmpeg_location = self.config.ffmpeg_location
|
|
||||||
self.music_path = self.config.music_path
|
|
||||||
# 初始化配置
|
# 初始化配置
|
||||||
self.init_config()
|
self.init_config()
|
||||||
|
|
||||||
@ -327,23 +320,6 @@ class XiaoMusic:
|
|||||||
return filename
|
return filename
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def cleanup_old_temp_files(self):
|
|
||||||
"""
|
|
||||||
清理在 /tmp 目录下旧的临时 MP3 文件。
|
|
||||||
"""
|
|
||||||
temp_dir = '/tmp' # 临时文件存储的目录
|
|
||||||
file_ext = '.mp3' # 临时文件的扩展名
|
|
||||||
try:
|
|
||||||
for filename in os.listdir(temp_dir):
|
|
||||||
if filename.endswith(file_ext):
|
|
||||||
file_path = os.path.join(temp_dir, filename)
|
|
||||||
# 如果文件是超过一天的旧文件,则删除它
|
|
||||||
if (time.time() - os.path.getmtime(file_path)) > 86400:
|
|
||||||
os.remove(file_path)
|
|
||||||
self.log.info(f"Deleted old temporary file: {file_path}")
|
|
||||||
except Exception as e:
|
|
||||||
self.log.error(f"Failed to cleanup old temp files: {e}")
|
|
||||||
|
|
||||||
# 判断本地音乐是否存在,网络歌曲不判断
|
# 判断本地音乐是否存在,网络歌曲不判断
|
||||||
def is_music_exist(self, name):
|
def is_music_exist(self, name):
|
||||||
if name not in self.all_music:
|
if name not in self.all_music:
|
||||||
@ -410,34 +386,27 @@ class XiaoMusic:
|
|||||||
# 如果开启了MP3转换功能,且文件不是MP3格式,则进行转换
|
# 如果开启了MP3转换功能,且文件不是MP3格式,则进行转换
|
||||||
if self.convert_to_mp3 and not is_mp3(filename):
|
if self.convert_to_mp3 and not is_mp3(filename):
|
||||||
self.log.info(f"convert_to_mp3 is enabled. Checking file: {filename}")
|
self.log.info(f"convert_to_mp3 is enabled. Checking file: {filename}")
|
||||||
temp_mp3_file = self.convert_file_to_mp3(filename)
|
temp_mp3_file = convert_file_to_mp3(
|
||||||
|
filename, self.config.ffmpeg_location, self.config.music_path
|
||||||
|
)
|
||||||
if temp_mp3_file:
|
if temp_mp3_file:
|
||||||
# 转换成功后,修改文件名为music_path/tmp下的相对路径
|
self.log.info(f"Converted file: {filename} to {temp_mp3_file}")
|
||||||
relative_path = os.path.relpath(temp_mp3_file, self.config.music_path)
|
filename = temp_mp3_file
|
||||||
self.log.info(f"Converted file: {temp_mp3_file} to {relative_path}")
|
|
||||||
filename = relative_path
|
|
||||||
else:
|
else:
|
||||||
self.log.warning(f"Failed to convert file to MP3 format: {filename}")
|
self.log.warning(f"Failed to convert file to MP3 format: {filename}")
|
||||||
return "" # 转换失败,返回空字符串表示无法获取播放URL
|
|
||||||
|
|
||||||
# 构造音乐文件的URL
|
# 构造音乐文件的URL
|
||||||
filename = filename.replace("\\", "/")
|
filename = filename.replace("\\", "/")
|
||||||
if filename.startswith(self.config.music_path):
|
if filename.startswith(self.config.music_path):
|
||||||
filename = filename[len(self.config.music_path):]
|
filename = filename[len(self.config.music_path) :]
|
||||||
if filename.startswith("/"):
|
if filename.startswith("/"):
|
||||||
filename = filename[1:]
|
filename = filename[1:]
|
||||||
|
|
||||||
|
self.log.info(f"get_music_url local music. name:{name}, filename:{filename}")
|
||||||
|
|
||||||
encoded_name = urllib.parse.quote(filename)
|
encoded_name = urllib.parse.quote(filename)
|
||||||
return f"http://{self.hostname}:{self.public_port}/music/{encoded_name}"
|
return f"http://{self.hostname}:{self.public_port}/music/{encoded_name}"
|
||||||
|
|
||||||
def convert_file_to_mp3(self, input_file):
|
|
||||||
"""
|
|
||||||
Convert the file to MP3 format using convert_to_mp3.py.
|
|
||||||
"""
|
|
||||||
# 创建 Convert_To_MP3 类的实例,只传递 config 对象
|
|
||||||
converter = Convert_To_MP3(self.config)
|
|
||||||
# 调用静态方法 convert_to_mp3,并传递所需的文件路径和 ffmpeg 位置
|
|
||||||
return converter.convert_to_mp3(input_file, self.ffmpeg_location, self.music_path)
|
|
||||||
|
|
||||||
# 获取目录下所有歌曲,生成随机播放列表
|
# 获取目录下所有歌曲,生成随机播放列表
|
||||||
def _gen_all_music_list(self):
|
def _gen_all_music_list(self):
|
||||||
self.all_music = {}
|
self.all_music = {}
|
||||||
@ -452,7 +421,7 @@ class XiaoMusic:
|
|||||||
if len(files) == 0:
|
if len(files) == 0:
|
||||||
continue
|
continue
|
||||||
if dir_name == os.path.basename(self.music_path):
|
if dir_name == os.path.basename(self.music_path):
|
||||||
dir_name = "默认"
|
dir_name = "其他"
|
||||||
if self.music_path != self.download_path and dir_name == os.path.basename(
|
if self.music_path != self.download_path and dir_name == os.path.basename(
|
||||||
self.download_path
|
self.download_path
|
||||||
):
|
):
|
||||||
|
Loading…
Reference in New Issue
Block a user