2023-10-14 11:50:32 +00:00
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import json
|
|
|
|
|
import os
|
2024-06-14 01:58:10 +00:00
|
|
|
|
from dataclasses import dataclass
|
2023-10-14 11:50:32 +00:00
|
|
|
|
|
|
|
|
|
from xiaomusic.utils import validate_proxy
|
|
|
|
|
|
|
|
|
|
LATEST_ASK_API = "https://userprofile.mina.mi.com/device_profile/v2/conversation?source=dialogu&hardware={hardware}×tamp={timestamp}&limit=2"
|
|
|
|
|
COOKIE_TEMPLATE = "deviceId={device_id}; serviceToken={service_token}; userId={user_id}"
|
|
|
|
|
HARDWARE_COMMAND_DICT = {
|
2024-01-29 15:10:16 +00:00
|
|
|
|
# hardware: (tts_command, wakeup_command, volume_command)
|
|
|
|
|
"LX06": ("5-1", "5-5", "2-1"),
|
2024-06-14 01:58:10 +00:00
|
|
|
|
"L05B": ("5-3", "5-4", "2-1"),
|
2024-05-15 13:45:24 +00:00
|
|
|
|
"S12": ("5-1", "5-5", "2-1"), # 第一代小爱,型号MDZ-25-DA
|
2024-01-29 15:10:16 +00:00
|
|
|
|
"S12A": ("5-1", "5-5", "2-1"),
|
|
|
|
|
"LX01": ("5-1", "5-5", "2-1"),
|
|
|
|
|
"L06A": ("5-1", "5-5", "2-1"),
|
|
|
|
|
"LX04": ("5-1", "5-4", "2-1"),
|
|
|
|
|
"L05C": ("5-3", "5-4", "2-1"),
|
|
|
|
|
"L17A": ("7-3", "7-4", "2-1"),
|
|
|
|
|
"X08E": ("7-3", "7-4", "2-1"),
|
|
|
|
|
"LX05A": ("5-1", "5-5", "2-1"), # 小爱红外版
|
|
|
|
|
"LX5A": ("5-1", "5-5", "2-1"), # 小爱红外版
|
|
|
|
|
"L07A": ("5-1", "5-5", "2-1"), # Redmi小爱音箱Play(l7a)
|
|
|
|
|
"L15A": ("7-3", "7-4", "2-1"),
|
|
|
|
|
"X6A": ("7-3", "7-4", "2-1"), # 小米智能家庭屏6
|
|
|
|
|
"X10A": ("7-3", "7-4", "2-1"), # 小米智能家庭屏10
|
2023-10-14 11:50:32 +00:00
|
|
|
|
# add more here
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-30 00:21:31 +00:00
|
|
|
|
DEFAULT_COMMAND = ("5-1", "5-5", "2-1")
|
2023-10-14 11:50:32 +00:00
|
|
|
|
|
|
|
|
|
KEY_WORD_DICT = {
|
|
|
|
|
"播放歌曲": "play",
|
|
|
|
|
"放歌曲": "play",
|
|
|
|
|
"下一首": "play_next",
|
2024-01-27 12:56:07 +00:00
|
|
|
|
"单曲循环": "set_play_type_one",
|
|
|
|
|
"全部循环": "set_play_type_all",
|
2024-01-27 15:00:17 +00:00
|
|
|
|
"随机播放": "random_play",
|
2024-01-27 12:56:07 +00:00
|
|
|
|
"关机": "stop",
|
|
|
|
|
"停止播放": "stop",
|
2024-01-28 10:17:45 +00:00
|
|
|
|
"分钟后关机": "stop_after_minute",
|
2024-06-12 17:12:07 +00:00
|
|
|
|
"播放列表": "play_music_list",
|
2024-06-12 17:21:09 +00:00
|
|
|
|
"刷新列表": "gen_music_list",
|
2024-01-29 15:10:16 +00:00
|
|
|
|
"set_volume#": "set_volume",
|
2024-05-16 22:39:05 +00:00
|
|
|
|
"get_volume#": "get_volume",
|
2023-10-14 11:50:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-28 10:17:45 +00:00
|
|
|
|
# 命令参数在前面
|
|
|
|
|
KEY_WORD_ARG_BEFORE_DICT = {
|
|
|
|
|
"分钟后关机": True,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 匹配优先级
|
|
|
|
|
KEY_MATCH_ORDER = [
|
2024-01-29 15:10:16 +00:00
|
|
|
|
"set_volume#",
|
2024-05-16 22:39:05 +00:00
|
|
|
|
"get_volume#",
|
2024-01-28 10:17:45 +00:00
|
|
|
|
"分钟后关机",
|
|
|
|
|
"播放歌曲",
|
|
|
|
|
"放歌曲",
|
|
|
|
|
"下一首",
|
|
|
|
|
"单曲循环",
|
|
|
|
|
"全部循环",
|
|
|
|
|
"随机播放",
|
|
|
|
|
"关机",
|
|
|
|
|
"停止播放",
|
2024-06-12 17:21:09 +00:00
|
|
|
|
"刷新列表",
|
2024-06-12 17:12:07 +00:00
|
|
|
|
"播放列表",
|
2024-01-28 10:17:45 +00:00
|
|
|
|
]
|
|
|
|
|
|
2024-01-27 12:56:07 +00:00
|
|
|
|
SUPPORT_MUSIC_TYPE = [
|
2024-02-24 04:41:26 +00:00
|
|
|
|
".mp3",
|
|
|
|
|
".flac",
|
2024-01-27 12:56:07 +00:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
2023-10-14 11:50:32 +00:00
|
|
|
|
@dataclass
|
|
|
|
|
class Config:
|
2023-10-16 10:07:07 +00:00
|
|
|
|
hardware: str = os.getenv("MI_HARDWARE", "L07A")
|
2023-10-14 11:50:32 +00:00
|
|
|
|
account: str = os.getenv("MI_USER", "")
|
|
|
|
|
password: str = os.getenv("MI_PASS", "")
|
|
|
|
|
mi_did: str = os.getenv("MI_DID", "")
|
|
|
|
|
mute_xiaoai: bool = True
|
|
|
|
|
cookie: str = ""
|
2024-01-30 00:21:31 +00:00
|
|
|
|
use_command: bool = False
|
2024-06-14 15:46:47 +00:00
|
|
|
|
verbose: bool = os.getenv("XIAOMUSIC_VERBOSE", "").lower() == "true"
|
2023-10-15 02:58:53 +00:00
|
|
|
|
music_path: str = os.getenv("XIAOMUSIC_MUSIC_PATH", "music")
|
2024-06-23 02:49:13 +00:00
|
|
|
|
conf_path: str = os.getenv("XIAOMUSIC_CONF_PATH", None)
|
2023-10-15 02:58:53 +00:00
|
|
|
|
hostname: str = os.getenv("XIAOMUSIC_HOSTNAME", "192.168.2.5")
|
|
|
|
|
port: int = int(os.getenv("XIAOMUSIC_PORT", "8090"))
|
2023-10-16 14:40:21 +00:00
|
|
|
|
proxy: str | None = os.getenv("XIAOMUSIC_PROXY", None)
|
2024-02-02 12:55:51 +00:00
|
|
|
|
search_prefix: str = os.getenv(
|
|
|
|
|
"XIAOMUSIC_SEARCH", "ytsearch:"
|
|
|
|
|
) # "bilisearch:" or "ytsearch:"
|
2024-02-24 04:49:17 +00:00
|
|
|
|
ffmpeg_location: str = os.getenv("XIAOMUSIC_FFMPEG_LOCATION", "./ffmpeg/bin")
|
2024-05-08 14:15:10 +00:00
|
|
|
|
active_cmd: str = os.getenv("XIAOMUSIC_ACTIVE_CMD", "play,random_play")
|
2024-06-16 06:14:33 +00:00
|
|
|
|
exclude_dirs: str = os.getenv("XIAOMUSIC_EXCLUDE_DIRS", "@eaDir")
|
2023-10-15 02:58:53 +00:00
|
|
|
|
|
|
|
|
|
def __post_init__(self) -> None:
|
|
|
|
|
if self.proxy:
|
|
|
|
|
validate_proxy(self.proxy)
|
2023-10-14 11:50:32 +00:00
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def tts_command(self) -> str:
|
|
|
|
|
return HARDWARE_COMMAND_DICT.get(self.hardware, DEFAULT_COMMAND)[0]
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def wakeup_command(self) -> str:
|
|
|
|
|
return HARDWARE_COMMAND_DICT.get(self.hardware, DEFAULT_COMMAND)[1]
|
|
|
|
|
|
2024-01-29 15:10:16 +00:00
|
|
|
|
@property
|
|
|
|
|
def volume_command(self) -> str:
|
|
|
|
|
return HARDWARE_COMMAND_DICT.get(self.hardware, DEFAULT_COMMAND)[2]
|
|
|
|
|
|
2023-10-14 11:50:32 +00:00
|
|
|
|
@classmethod
|
|
|
|
|
def from_options(cls, options: argparse.Namespace) -> Config:
|
|
|
|
|
config = {}
|
|
|
|
|
if options.config:
|
|
|
|
|
config = cls.read_from_file(options.config)
|
|
|
|
|
for key, value in vars(options).items():
|
|
|
|
|
if value is not None and key in cls.__dataclass_fields__:
|
|
|
|
|
config[key] = value
|
|
|
|
|
return cls(**config)
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def read_from_file(cls, config_path: str) -> dict:
|
|
|
|
|
result = {}
|
|
|
|
|
with open(config_path, "rb") as f:
|
|
|
|
|
config = json.load(f)
|
|
|
|
|
for key, value in config.items():
|
|
|
|
|
if value is not None and key in cls.__dataclass_fields__:
|
|
|
|
|
result[key] = value
|
|
|
|
|
return result
|