parent
c552a34ec1
commit
977ff684eb
@ -6,9 +6,9 @@
|
|||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<title>Debug For XiaoMusic</title>
|
<title>Debug For XiaoMusic</title>
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
<link rel="stylesheet" type="text/css" href="./main.css?version=1733199308">
|
||||||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||||
<script src="./jquery-3.7.1.min.js?version=1733563859"></script>
|
<script src="./jquery-3.7.1.min.js?version=1733199308"></script>
|
||||||
|
|
||||||
<!-- Google tag (gtag.js) -->
|
<!-- Google tag (gtag.js) -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
@ -57,12 +57,16 @@ function sendDebugCmd() {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Debug For XiaoMusic</h1>
|
<h1>Debug For XiaoMusic</h1>
|
||||||
<textarea id="post-input" rows="10" cols="50" placeholder="粘贴json数据..."></textarea><br>
|
<div class="debug">
|
||||||
<button onclick="postJSON()">提交</button><br>
|
<textarea id="post-input" rows="10" cols="50" placeholder="粘贴json数据..."></textarea><br>
|
||||||
|
<button onclick="postJSON()">提交</button><br>
|
||||||
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<input id="cmd" type="text"></input>
|
<div class="debug">
|
||||||
<button onclick="sendDebugCmd()">测试自定义口令</button><br>
|
<input id="cmd" type="text"></input>
|
||||||
|
<button onclick="sendDebugCmd()">测试自定义口令</button><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<title>歌曲下载工具</title>
|
<title>歌曲下载工具</title>
|
||||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
<link rel="stylesheet" type="text/css" href="./main.css?version=1733199308">
|
||||||
<script src="./jquery-3.7.1.min.js?version=1733563859"></script>
|
<script src="./jquery-3.7.1.min.js?version=1733199308"></script>
|
||||||
|
|
||||||
<!-- Google tag (gtag.js) -->
|
<!-- Google tag (gtag.js) -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
|
BIN
xiaomusic/static/default/favicon.ico
Normal file
BIN
xiaomusic/static/default/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 894 B |
@ -1,110 +1,189 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="zh">
|
||||||
<head>
|
|
||||||
<link rel="icon" href="/favicon.ico">
|
<head>
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>小爱音箱操控面板</title>
|
<title>小爱音箱操控面板</title>
|
||||||
<script src="./jquery-3.7.1.min.js?version=1733563859"></script>
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
<script src="./app.js?version=1733563859"></script>
|
<script src="./jquery-3.7.1.min.js?version=1733199308"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
<link rel="stylesheet" href="./main.css">
|
||||||
|
<link rel="icon" href="./favicon.ico">
|
||||||
|
</head>
|
||||||
|
|
||||||
<!-- Google tag (gtag.js) -->
|
<body class="index_page">
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
<div class="player">
|
||||||
<script>
|
<h1>音乐播放器
|
||||||
window.dataLayer = window.dataLayer || [];
|
<a id="version" href="https://github.com/hanxi/xiaomusic/blob/main/CHANGELOG.md" target="_blank">版本
|
||||||
function gtag(){dataLayer.push(arguments)};
|
1.0.0</a><span id="versionnew" class="new-badge"></span>
|
||||||
gtag('js', new Date());
|
</h1>
|
||||||
gtag('config', 'G-Z09NC1K7ZW');
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!--
|
<label for="did">选择播放设备:</label>
|
||||||
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
<select id="did" class="device-selector">
|
||||||
<script>
|
<option value="default">默认设备</option>
|
||||||
var vConsole = new window.VConsole();
|
</select>
|
||||||
</script>
|
|
||||||
-->
|
|
||||||
|
|
||||||
</head>
|
<label for="music_list" style="display: flex;align-items: center;">选择播放列表:
|
||||||
<body>
|
<div class="option-inline" onclick="sendcmd('刷新列表')">
|
||||||
<h2>小爱音箱操控面板
|
<span class="material-icons">refresh</span>
|
||||||
(<a id="version" href="https://github.com/hanxi/xiaomusic/blob/main/CHANGELOG.md">版本未知</a>)
|
<span class="tooltip">刷新列表</span>
|
||||||
<span id="versionnew" class="blink"></span>
|
</div>
|
||||||
</h2>
|
</label>
|
||||||
<hr>
|
<select id="music_list" class="playlist-selector">
|
||||||
|
</select>
|
||||||
|
|
||||||
<div class="rows">
|
<label for="music_name" style="display: flex;align-items: center;">选择歌曲:
|
||||||
<select id="did">
|
<div class="option-inline" onclick="toggleDelete()">
|
||||||
</select>
|
<span class="material-icons">delete</span>
|
||||||
|
<span class="tooltip">删除歌曲</span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<select id="music_name" class="song-selector">
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<progress class="progress" id="progress" value="0" max="100"></progress>
|
||||||
|
<div style="display: flex; justify-content: space-between; width: 100%;">
|
||||||
|
<span class="current-time" id="current-time">0:00</span>
|
||||||
|
<div class="current-song" id="playering-music">当前播放歌曲:无</div>
|
||||||
|
<span class="duration" id="duration">0:00</span>
|
||||||
|
</div>
|
||||||
|
<audio id="audio" controls src="" autoplay>
|
||||||
|
</audio>
|
||||||
|
<div class="buttons">
|
||||||
|
<div class="player-controls button-group">
|
||||||
|
<button onclick="prevTrack()">
|
||||||
|
<span class="material-icons">skip_previous</span>
|
||||||
|
<span class="tooltip">上一首</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="playOnDevice()">
|
||||||
|
<span class="material-icons" id="playPauseIcon">play_arrow</span>
|
||||||
|
<span class="tooltip">播放</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="nextTrack()">
|
||||||
|
<span class="material-icons">skip_next</span>
|
||||||
|
<span class="tooltip">下一首</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="stopPlay()">
|
||||||
|
<span class="material-icons" id="playPauseIcon">stop</span>
|
||||||
|
<span class="tooltip">关机</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="mode-controls button-group">
|
||||||
|
<button id="modeBtn" onclick="togglePlayMode()">
|
||||||
|
<span class="material-icons">shuffle</span>
|
||||||
|
<span class="tooltip">切换播放模式</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="addToFavorites()" class="favorite">
|
||||||
|
<span class="material-icons">favorite</span>
|
||||||
|
<span class="tooltip">收藏歌曲</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="toggleVolume()">
|
||||||
|
<span class="material-icons">volume_up</span>
|
||||||
|
<span class="tooltip">调节音量</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="toggleLocalPlay()" id="web_play">
|
||||||
|
<span class="material-icons">headphones</span>
|
||||||
|
<span class="tooltip">网页播放</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="mode-controls button-group">
|
||||||
|
<button onclick="toggleSearch()">
|
||||||
|
<span class="material-icons">search</span>
|
||||||
|
<span class="tooltip">搜索歌曲</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="togglePlayLink()">
|
||||||
|
<span class="material-icons">link</span>
|
||||||
|
<span class="tooltip">播放链接</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="toggleTimer()">
|
||||||
|
<span class="material-icons">timer</span>
|
||||||
|
<span class="tooltip">定时关机</span>
|
||||||
|
</button>
|
||||||
|
<button onclick="openSettings()">
|
||||||
|
<span class="material-icons">settings</span>
|
||||||
|
<span class="tooltip">设置</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="cmds">
|
<!-- 搜索组件 -->
|
||||||
<a class="button" href="./setting.html">设置</a>
|
<div class="component" id="search-component">
|
||||||
</div>
|
<h2>搜索歌曲</h2>
|
||||||
<hr>
|
<input type="text" id="search" class="search-input" placeholder="请输入搜索关键词(如:MV高清版 周杰伦 七里香)">
|
||||||
|
<label for="music-name" id="music-name-label" style="display: none;">确认选择:</label>
|
||||||
<div style="margin: 20px;">
|
<select id="music-name" style="display: none;">
|
||||||
<div style="display: flex; align-items: center;">
|
<!-- 动态生成选项 -->
|
||||||
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" fill="#8e43e7" style="height: 48px; width: 48px;"><path d="M550.826667 154.666667a47.786667 47.786667 0 0 0-19.84 4.48L298.666667 298.666667H186.453333A80 80 0 0 0 106.666667 378.453333v267.093334A80 80 0 0 0 186.453333 725.333333H298.666667l232.32 139.52a47.786667 47.786667 0 0 0 19.84 4.48A46.506667 46.506667 0 0 0 597.333333 822.826667V201.173333a46.506667 46.506667 0 0 0-46.506666-46.506666zM554.666667 822.826667c0 3.413333-3.84 3.84-3.84 3.84L320 688.853333l-9.6-6.186666H186.453333A37.12 37.12 0 0 1 149.333333 645.546667V378.453333A37.12 37.12 0 0 1 186.453333 341.333333h123.946667l10.24-6.186666 229.546667-137.6s3.84 0 3.84 3.84zM667.52 346.026667a21.333333 21.333333 0 0 0 0 30.293333 192 192 0 0 1 0 271.36 21.333333 21.333333 0 0 0 0 30.293333 21.333333 21.333333 0 0 0 30.293333 0 234.666667 234.666667 0 0 0 0-331.946666 21.333333 21.333333 0 0 0-30.293333 0z"></path><path d="M804.48 219.52a21.333333 21.333333 0 0 0-30.293333 30.293333 370.986667 370.986667 0 0 1 0 524.373334 21.333333 21.333333 0 0 0 0 30.293333 21.333333 21.333333 0 0 0 30.293333 0 414.08 414.08 0 0 0 0-584.96z"></path></svg>
|
</select>
|
||||||
<input id="volume" type="range"></input>
|
<input id="music-filename" type="text" placeholder="请输入保存为的文件名称(如:周杰伦七里香)" style="display: none;"></input>
|
||||||
</div>
|
<div class="component-button-group">
|
||||||
</div>
|
<button onclick="confirmSearch()">确定</button>
|
||||||
<hr>
|
<button onclick="toggleSearch()">关闭</button>
|
||||||
<div class="rows">
|
</div>
|
||||||
<label for="search">搜索歌曲:</label>
|
|
||||||
<input type="text" id="search" placeholder="请输入搜索关键词(如:MV高清版 周杰伦 七里香)">
|
|
||||||
|
|
||||||
<label for="music-name" id="music-name-label" style="display: none;">确认选择:</label>
|
|
||||||
<select id="music-name" style="display: none;">
|
|
||||||
<!-- 动态生成选项 -->
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<input id="music-filename" type="text" placeholder="请输入保存为的文件名称(如:周杰伦七里香)" style="display: none;"></input>
|
|
||||||
<div style="display: flex; align-items: center">
|
|
||||||
<progress id="progress" value="0" max="100" style="width: 270px"></progress>
|
|
||||||
<div id="play-time" style="margin-left: 10px">00:00/00:00</div>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button id="play">播放</button>
|
|
||||||
<div id="playering-music" class="text"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<!-- 定时关机组件 -->
|
||||||
<div class="rows">
|
<div class="component" id="timer-component">
|
||||||
<label for="music_list">播放列表:</label>
|
<h2>定时关机</h2>
|
||||||
<select id="music_list"></select>
|
|
||||||
<label for="music_name">歌曲:</label>
|
<button onclick="timedShutDown('10分钟后关机')">10分钟后关机</button>
|
||||||
<select id="music_name"></select>
|
<button onclick="timedShutDown('30分钟后关机')">30分钟后关机</button>
|
||||||
<div>
|
<button onclick="timedShutDown('60分钟后关机')">60分钟后关机</button>
|
||||||
<button id="play_music_list">播放选中歌曲</button>
|
<span class="tooltip timer-tooltip" style="display: none;">已发送指令</span>
|
||||||
<button id="del_music">删除选中歌曲</button>
|
<div class="component-button-one">
|
||||||
<button id="web_play">网页播放</button>
|
<button onclick="toggleTimer()">关闭</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="play_pannel">
|
|
||||||
<audio autoplay controls src=""></audio>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<!-- 播放链接组件 -->
|
||||||
<div class="rows">
|
<div class="component" id="playlink-component">
|
||||||
<input id="music-url" type="text" value="https://lhttp.qtfm.cn/live/4915/64k.mp3"></input>
|
<h2>播放链接</h2>
|
||||||
<button id="playurl">播放链接</button>
|
<input type="text" id="music-url" class="search-input" placeholder="请输入播放链接"
|
||||||
|
value="https://lhttp.qtfm.cn/live/4915/64k.mp3">
|
||||||
|
<div class="component-button-group">
|
||||||
|
<button id="playurl">播放链接</button>
|
||||||
|
<button onclick="togglePlayLink()">关闭</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
|
||||||
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
|
<!-- 音量组件 -->
|
||||||
</footer>
|
<div class="component" id="volume-component">
|
||||||
<dialog id="valid-host">
|
<h2>调节音量</h2>
|
||||||
<form method="dialog">
|
<input type="range" id="volume" class="volume-slider" />
|
||||||
|
<div class="component-button-one">
|
||||||
|
<button onclick="toggleVolume()">关闭</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 删除确认组件 -->
|
||||||
|
<div class="component" id="delete-component">
|
||||||
|
<h2>警告</h2>
|
||||||
|
<p>你确定要删除歌曲 <span id="delete-music-name"></span> 吗?</p>
|
||||||
|
<p style="font-weight: bold;">注意:该操作会永久删除该歌曲且不可撤销</p>
|
||||||
|
<div class="component-button-group">
|
||||||
|
<button onclick="confirmDelete()">确定</button>
|
||||||
|
<button onclick="toggleDelete()">关闭</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 警告组件 -->
|
||||||
|
<div class="component" id="warning-component">
|
||||||
|
<h2>警告</h2>
|
||||||
<p>当前页面的HOST与设置中的HOST不一致,请检查是否设置错误</p>
|
<p>当前页面的HOST与设置中的HOST不一致,请检查是否设置错误</p>
|
||||||
<p>当前HOST: <span id="local-host"></span></p>
|
<p>当前HOST: <span id="local-host"></span></p>
|
||||||
<p>设置中的HOST: <span id="setting-host"></span></p>
|
<p>设置中的HOST: <span id="setting-host"></span></p>
|
||||||
<div class="btn-list">
|
<div class="component-button-group">
|
||||||
<a href="./setting.html" target="_blank">立即修改</a>
|
<a href="./setting.html" target="_blank"><button>立即修改</button></a>
|
||||||
<button value="no-warning" type="submit">继续并不再显示</button>
|
<button onclick="nowarning()">继续并不再显示</button>
|
||||||
<button value="cancle" type="submit">取消</button>
|
<button onclick="toggleWarning()">取消</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</dialog>
|
<div class="footer">
|
||||||
</body>
|
Powered by XiaoMusic
|
||||||
</html>
|
</div>
|
||||||
|
|
||||||
|
<script src="./md.js">
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -5,7 +5,7 @@
|
|||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<title>M3U to JSON Converter</title>
|
<title>M3U to JSON Converter</title>
|
||||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
<link rel="stylesheet" type="text/css" href="./main.css?version=1733199308">
|
||||||
|
|
||||||
<!-- Google tag (gtag.js) -->
|
<!-- Google tag (gtag.js) -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
|
296
xiaomusic/static/default/main.css
Normal file
296
xiaomusic/static/default/main.css
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.index_page {
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player {
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
|
||||||
|
text-align: center;
|
||||||
|
max-width: 360px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #333;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 a {
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #007bff;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-badge {
|
||||||
|
background-color: #ff4757;
|
||||||
|
color: white;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 5px;
|
||||||
|
display: none;
|
||||||
|
width: fit-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #555;
|
||||||
|
margin: 5px 0;
|
||||||
|
display: block;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
select,
|
||||||
|
input[type="range"],
|
||||||
|
input[type="text"],
|
||||||
|
input[type="password"],
|
||||||
|
input[type="number"] {
|
||||||
|
width: 300px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid #cccccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
transition: border 0.2s ease;
|
||||||
|
box-sizing: border-box
|
||||||
|
}
|
||||||
|
|
||||||
|
select:focus,
|
||||||
|
input[type="text"]:focus {
|
||||||
|
border-color: #007bff;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
margin: 5px;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
position: relative; /* 为tooltip绝对定位做准备 */
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
.tooltip {
|
||||||
|
visibility: hidden;
|
||||||
|
background-color: #555;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 5px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
bottom: 150%; /* 控制tooltip相对按钮的位置 */
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -50px; /* 调整位置以居中显示 Tooltip */
|
||||||
|
width: 100px; /* 设置固定宽度以保证足够的显示空间 */
|
||||||
|
white-space: nowrap; /* 防止换行 */
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
button:hover .tooltip,.option-inline:hover .tooltip {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.option-inline{
|
||||||
|
display: flex;
|
||||||
|
margin-left: auto;
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.option-inline:hover .tooltip {
|
||||||
|
/* 位置调整到左边 */
|
||||||
|
left: -80px; /* 调整位置以居中显示 Tooltip */
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.progress {
|
||||||
|
width: 90%;
|
||||||
|
height: 6px;
|
||||||
|
background: #e0e0e0;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 15px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
progress::-webkit-progress-bar {
|
||||||
|
background: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress::-moz-progress-bar,
|
||||||
|
progress::-webkit-progress-value {
|
||||||
|
background: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-song {
|
||||||
|
color: #333;
|
||||||
|
margin: 10px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.component {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 5px 15px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 100;
|
||||||
|
width: 300px;
|
||||||
|
}
|
||||||
|
.component input {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
.component-button-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.component-button-one {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
#warning-component p span {
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player-controls {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timer-tooltip {
|
||||||
|
bottom: 50%;
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.favorite.favorite-active .material-icons {
|
||||||
|
color: #ff6347;
|
||||||
|
}
|
||||||
|
#audio {
|
||||||
|
width: 100%;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-tips {
|
||||||
|
color: red;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.login-tips a {
|
||||||
|
color: rgb(9, 105, 218);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setting.html */
|
||||||
|
.rows {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rows a {
|
||||||
|
color: rgb(9, 105, 218);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.rows a:hover {
|
||||||
|
color: rgb(9, 95, 198);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
margin-left: 5%;
|
||||||
|
margin-right: 5%;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 400px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
.custom-checkbox {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 10px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
vertical-align: middle; /* 确保与标签垂直居中对齐 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 180px;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 0px solid #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: middle; /* 确保与复选框垂直居中对齐 */
|
||||||
|
margin-left: 1px; /* 给复选框和标签之间一些距离,如果需要的话 */
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
.debug {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
/* 媒体查询 屏幕宽度小于440px时 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@media screen and (max-width: 440px) {
|
||||||
|
.player{
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
}
|
621
xiaomusic/static/default/md.js
Normal file
621
xiaomusic/static/default/md.js
Normal file
@ -0,0 +1,621 @@
|
|||||||
|
// $(function () {
|
||||||
|
|
||||||
|
// })
|
||||||
|
let isPlaying = false;
|
||||||
|
let playModeIndex = 2;
|
||||||
|
//重新设计playModes
|
||||||
|
const playModes = {
|
||||||
|
0: {
|
||||||
|
icon: "repeat_one",
|
||||||
|
cmd: "单曲循环",
|
||||||
|
},
|
||||||
|
1: {
|
||||||
|
icon: "repeat",
|
||||||
|
cmd: "全部循环",
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
icon: "shuffle",
|
||||||
|
cmd: "随机播放",
|
||||||
|
},
|
||||||
|
3: {
|
||||||
|
icon: "filter_1",
|
||||||
|
cmd: "单曲播放",
|
||||||
|
},
|
||||||
|
4: {
|
||||||
|
icon: "playlist_play",
|
||||||
|
cmd: "顺序播放",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let favoritelist = []; //收藏列表
|
||||||
|
|
||||||
|
function playOnDevice() {
|
||||||
|
var music_list = $("#music_list").val();
|
||||||
|
var music_name = $("#music_name").val();
|
||||||
|
if (no_warning) {
|
||||||
|
do_play_music_list(music_list, music_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.get(`/musicinfo?name=${music_name}`, function (data, status) {
|
||||||
|
console.log(data);
|
||||||
|
if (data.ret == "OK") {
|
||||||
|
console.log(
|
||||||
|
"%cmd.js:42 validHost(data.url) ",
|
||||||
|
"color: #007acc;",
|
||||||
|
validHost(data.url)
|
||||||
|
);
|
||||||
|
validHost(data.url) && do_play_music_list(music_list, music_name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function stopPlay() {
|
||||||
|
sendcmd("关机");
|
||||||
|
}
|
||||||
|
|
||||||
|
function prevTrack() {
|
||||||
|
sendcmd("上一首");
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextTrack() {
|
||||||
|
sendcmd("下一首");
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePlayMode(isSend = true) {
|
||||||
|
const modeBtnIcon = $("#modeBtn .material-icons");
|
||||||
|
modeBtnIcon.text(playModes[playModeIndex].icon);
|
||||||
|
$("#modeBtn .tooltip").text(playModes[playModeIndex].cmd);
|
||||||
|
// return;
|
||||||
|
isSend && sendcmd(playModes[playModeIndex].cmd);
|
||||||
|
console.log(`当前播放模式: ${playModeIndex} ${playModes[playModeIndex].cmd}`);
|
||||||
|
playModeIndex = (playModeIndex + 1) % Object.keys(playModes).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addToFavorites() {
|
||||||
|
|
||||||
|
const cmd = $(".favorite").hasClass("favorite-active")
|
||||||
|
? "取消收藏"
|
||||||
|
: "加入收藏";
|
||||||
|
if ($(".favorite").hasClass("favorite-active")) {
|
||||||
|
$(".favorite").removeClass("favorite-active");
|
||||||
|
} else {
|
||||||
|
$(".favorite").addClass("favorite-active");
|
||||||
|
}
|
||||||
|
sendcmd(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openSettings() {
|
||||||
|
console.log("打开设置");
|
||||||
|
//新建标签页打开setting.html页面
|
||||||
|
window.open("setting.html", "_blank");
|
||||||
|
}
|
||||||
|
function toggleVolume() {
|
||||||
|
$("#volume-component").toggle();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSearch() {
|
||||||
|
$("#search-component").toggle();
|
||||||
|
}
|
||||||
|
function toggleTimer() {
|
||||||
|
$("#timer-component").toggle();
|
||||||
|
}
|
||||||
|
function togglePlayLink() {
|
||||||
|
$("#playlink-component").toggle(); // 切换播放链接的显示状态
|
||||||
|
}
|
||||||
|
function toggleLocalPlay() {
|
||||||
|
$("#audio").fadeIn();
|
||||||
|
}
|
||||||
|
function toggleWarning() {
|
||||||
|
$("#warning-component").toggle(); // 切换警告框的显示状态
|
||||||
|
}
|
||||||
|
function toggleDelete() {
|
||||||
|
var del_music_name = $("#music_name").val();
|
||||||
|
$("#delete-music-name").text(del_music_name);
|
||||||
|
$("#delete-component").toggle(); // 切换删除框的显示状态
|
||||||
|
}
|
||||||
|
function confirmDelete() {
|
||||||
|
var del_music_name = $("#music_name").val();
|
||||||
|
console.log(`删除歌曲 ${del_music_name}`);
|
||||||
|
$("#delete-component").hide(); // 隐藏删除框
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/delmusic",
|
||||||
|
data: JSON.stringify({ name: del_music_name }),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
success: () => {
|
||||||
|
alert(`删除 ${del_music_name} 成功`);
|
||||||
|
refresh_music_list();
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
alert(`删除 ${del_music_name} 失败`);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function formatTime(seconds) {
|
||||||
|
const minutes = Math.floor(seconds / 60);
|
||||||
|
const secs = Math.floor(seconds % 60);
|
||||||
|
return `${minutes}:${secs < 10 ? "0" : ""}${secs}`; // Format time as mm:ss
|
||||||
|
}
|
||||||
|
|
||||||
|
var offset = 0;
|
||||||
|
var duration = 0;
|
||||||
|
let no_warning = localStorage.getItem("no-warning");
|
||||||
|
// 拉取现有配置
|
||||||
|
$.get("/getsetting", function (data, status) {
|
||||||
|
console.log(data, status);
|
||||||
|
localStorage.setItem("mi_did", data.mi_did);
|
||||||
|
|
||||||
|
var did = localStorage.getItem("cur_did");
|
||||||
|
var dids = [];
|
||||||
|
if (data.mi_did != null) {
|
||||||
|
dids = data.mi_did.split(",");
|
||||||
|
}
|
||||||
|
console.log("cur_did", did);
|
||||||
|
console.log("dids", dids);
|
||||||
|
if (dids.length > 0 && (did == null || did == "" || !dids.includes(did))) {
|
||||||
|
did = dids[0];
|
||||||
|
localStorage.setItem("cur_did", did);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.did = did;
|
||||||
|
$.get(`/getvolume?did=${did}`, function (data, status) {
|
||||||
|
console.log(data, status, data["volume"]);
|
||||||
|
$("#volume").val(data.volume);
|
||||||
|
});
|
||||||
|
refresh_music_list();
|
||||||
|
|
||||||
|
$("#did").empty();
|
||||||
|
var dids = data.mi_did.split(",");
|
||||||
|
$.each(dids, function (index, value) {
|
||||||
|
var cur_device = Object.values(data.devices).find(
|
||||||
|
(device) => device.did === value
|
||||||
|
);
|
||||||
|
if (cur_device) {
|
||||||
|
var option = $("<option></option>")
|
||||||
|
.val(value)
|
||||||
|
.text(cur_device.name)
|
||||||
|
.prop("selected", value === did);
|
||||||
|
$("#did").append(option);
|
||||||
|
|
||||||
|
if (value === did) {
|
||||||
|
playModeIndex = cur_device.play_type;
|
||||||
|
console.log(
|
||||||
|
"%c当前设备播放模式: ",
|
||||||
|
"color: #007acc;",
|
||||||
|
cur_device.play_type
|
||||||
|
);
|
||||||
|
togglePlayMode(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("cur_did", did);
|
||||||
|
$("#did").change(function () {
|
||||||
|
did = $(this).val();
|
||||||
|
localStorage.setItem("cur_did", did);
|
||||||
|
window.did = did;
|
||||||
|
console.log("cur_did", did);
|
||||||
|
location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function compareVersion(version1, version2) {
|
||||||
|
const v1 = version1.split(".").map(Number);
|
||||||
|
const v2 = version2.split(".").map(Number);
|
||||||
|
const len = Math.max(v1.length, v2.length);
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const num1 = v1[i] || 0;
|
||||||
|
const num2 = v2[i] || 0;
|
||||||
|
if (num1 > num2) return 1;
|
||||||
|
if (num1 < num2) return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拉取版本
|
||||||
|
$.get("/getversion", function (data, status) {
|
||||||
|
console.log(data, status, data["version"]);
|
||||||
|
$("#version").text(`${data.version}`);
|
||||||
|
|
||||||
|
$.get("/latestversion", function (ret, status) {
|
||||||
|
console.log(ret, status);
|
||||||
|
if (ret.ret == "OK") {
|
||||||
|
const result = compareVersion(ret.version, data.version);
|
||||||
|
if (result > 0) {
|
||||||
|
console.log(`${ret.version} is greater than ${data.version}`);
|
||||||
|
$("#versionnew").text("new").css("display", "inline-block");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function _refresh_music_list(callback) {
|
||||||
|
$("#music_list").empty();
|
||||||
|
$.get("/musiclist", function (data, status) {
|
||||||
|
console.log(data, status);
|
||||||
|
favoritelist = data["收藏"];
|
||||||
|
$.each(data, function (key, value) {
|
||||||
|
let cnt = value.length;
|
||||||
|
$("#music_list").append(
|
||||||
|
$("<option></option>").val(key).text(`${key} (${cnt})`)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#music_list").change(function () {
|
||||||
|
const selectedValue = $(this).val();
|
||||||
|
localStorage.setItem("cur_playlist", selectedValue);
|
||||||
|
$("#music_name").empty();
|
||||||
|
$.each(data[selectedValue], function (index, item) {
|
||||||
|
$("#music_name").append($("<option></option>").val(item).text(item));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#music_list").trigger("change");
|
||||||
|
|
||||||
|
// 获取当前播放列表
|
||||||
|
$.get(`/curplaylist?did=${did}`, function (playlist, status) {
|
||||||
|
if (playlist != "") {
|
||||||
|
$("#music_list").val(playlist);
|
||||||
|
$("#music_list").trigger("change");
|
||||||
|
} else {
|
||||||
|
// 使用本地记录的
|
||||||
|
playlist = localStorage.getItem("cur_playlist");
|
||||||
|
if (data.hasOwnProperty(playlist)) {
|
||||||
|
$("#music_list").val(playlist);
|
||||||
|
$("#music_list").trigger("change");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拉取播放列表
|
||||||
|
function refresh_music_list() {
|
||||||
|
// 刷新列表时清空并临时禁用搜索框
|
||||||
|
const searchInput = document.getElementById("search");
|
||||||
|
const oriPlaceHolder = searchInput.placeholder;
|
||||||
|
const oriValue = searchInput.value;
|
||||||
|
const inputEvent = new Event("input", { bubbles: true });
|
||||||
|
searchInput.value = "";
|
||||||
|
// 分发事件,让其他控件改变状态
|
||||||
|
searchInput.dispatchEvent(inputEvent);
|
||||||
|
searchInput.disabled = true;
|
||||||
|
searchInput.placeholder = "请等待...";
|
||||||
|
|
||||||
|
_refresh_music_list(() => {
|
||||||
|
// 刷新完成再启用
|
||||||
|
searchInput.disabled = false;
|
||||||
|
searchInput.value = oriValue;
|
||||||
|
searchInput.dispatchEvent(inputEvent);
|
||||||
|
searchInput.placeholder = oriPlaceHolder;
|
||||||
|
// 每3秒获取下正在播放的音乐
|
||||||
|
get_playing_music();
|
||||||
|
setInterval(() => {
|
||||||
|
get_playing_music();
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_play_music_list(listname, musicname) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/playmusiclist",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({
|
||||||
|
did: did,
|
||||||
|
listname: listname,
|
||||||
|
musicname: musicname,
|
||||||
|
}),
|
||||||
|
success: () => {
|
||||||
|
console.log("do_play_music_list succ", listname, musicname);
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
console.log("do_play_music_list failed", listname, musicname);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#play_music_list").on("click", () => {
|
||||||
|
var music_list = $("#music_list").val();
|
||||||
|
var music_name = $("#music_name").val();
|
||||||
|
if (no_warning) {
|
||||||
|
do_play_music_list(music_list, music_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.get(`/musicinfo?name=${music_name}`, function (data, status) {
|
||||||
|
console.log(data);
|
||||||
|
if (data.ret == "OK") {
|
||||||
|
validHost(data.url) && do_play_music_list(music_list, music_name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#web_play").on("click", () => {
|
||||||
|
const music_name = $("#music_name").val();
|
||||||
|
$.get(`/musicinfo?name=${music_name}`, function (data, status) {
|
||||||
|
console.log(data);
|
||||||
|
if (data.ret == "OK") {
|
||||||
|
validHost(data.url) && $("audio").attr("src", data.url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#playurl").on("click", () => {
|
||||||
|
var url = $("#music-url").val();
|
||||||
|
const encoded_url = encodeURIComponent(url);
|
||||||
|
$.get(`/playurl?url=${encoded_url}&did=${did}`, function (data, status) {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function do_play_music(musicname, searchkey) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/playmusic",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({
|
||||||
|
did: did,
|
||||||
|
musicname: musicname,
|
||||||
|
searchkey: searchkey,
|
||||||
|
}),
|
||||||
|
success: () => {
|
||||||
|
console.log("do_play_music succ", musicname, searchkey);
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
console.log("do_play_music failed", musicname, searchkey);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#play").on("click", () => {
|
||||||
|
var search_key = $("#music-name").val();
|
||||||
|
if (search_key == null) {
|
||||||
|
search_key = "";
|
||||||
|
}
|
||||||
|
var filename = $("#music-filename").val();
|
||||||
|
if (filename == null || filename == "") {
|
||||||
|
filename = search_key;
|
||||||
|
}
|
||||||
|
do_play_music(filename, search_key);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#volume").on("change", function () {
|
||||||
|
var value = $(this).val();
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/setvolume",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({ did: did, volume: value }),
|
||||||
|
success: () => { },
|
||||||
|
error: () => { },
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function check_status_refresh_music_list(retries) {
|
||||||
|
$.get("/cmdstatus", function (data) {
|
||||||
|
if (data.status === "finish") {
|
||||||
|
refresh_music_list();
|
||||||
|
} else if (retries > 0) {
|
||||||
|
setTimeout(function () {
|
||||||
|
check_status_refresh_music_list(retries - 1);
|
||||||
|
}, 1000); // 等待1秒后重试
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendcmd(cmd) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/cmd",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({ did: did, cmd: cmd }),
|
||||||
|
success: () => {
|
||||||
|
if (cmd == "刷新列表") {
|
||||||
|
check_status_refresh_music_list(3); // 最多重试3次
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
["全部循环", "单曲循环", "随机播放", "单曲播放", "顺序播放"].includes(
|
||||||
|
cmd
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
// 请求失败时执行的操作
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听输入框的输入事件
|
||||||
|
function debounce(func, delay) {
|
||||||
|
let timeout;
|
||||||
|
return function (...args) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(() => func.apply(this, args), delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function handleSearch() {
|
||||||
|
const searchInput = document.getElementById("search");
|
||||||
|
const musicSelect = document.getElementById("music-name");
|
||||||
|
const musicSelectLabel = document.getElementById("music-name-label");
|
||||||
|
|
||||||
|
searchInput.addEventListener(
|
||||||
|
"input",
|
||||||
|
debounce(function () {
|
||||||
|
const query = searchInput.value.trim();
|
||||||
|
|
||||||
|
if (query.length === 0) {
|
||||||
|
musicSelect.innerHTML = "";
|
||||||
|
musicSelect.style.display = "none";
|
||||||
|
musicSelectLabel.style.display = "none";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
musicSelect.style.display = "block";
|
||||||
|
musicSelectLabel.style.display = "block";
|
||||||
|
fetch(`/searchmusic?name=${encodeURIComponent(query)}`)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
musicSelect.innerHTML = ""; // 清空现有选项
|
||||||
|
|
||||||
|
// 找到的优先显示
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach((song) => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = song;
|
||||||
|
option.textContent = song;
|
||||||
|
musicSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加用户输入作为一个选项
|
||||||
|
const userOption = document.createElement("option");
|
||||||
|
userOption.value = query;
|
||||||
|
userOption.textContent = `使用关键词播放: ${query}`;
|
||||||
|
musicSelect.appendChild(userOption);
|
||||||
|
|
||||||
|
// 提示没找到
|
||||||
|
if (data.length === 0) {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.textContent = "没有匹配的结果";
|
||||||
|
option.disabled = true;
|
||||||
|
musicSelect.appendChild(option);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Error fetching data:", error);
|
||||||
|
});
|
||||||
|
}, 600)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 动态显示保存文件名输入框
|
||||||
|
const musicNameSelect = document.getElementById("music-name");
|
||||||
|
const musicFilenameInput = document.getElementById("music-filename");
|
||||||
|
function updateInputVisibility() {
|
||||||
|
const selectedOption =
|
||||||
|
musicNameSelect.options[musicNameSelect.selectedIndex];
|
||||||
|
var startsWithKeyword;
|
||||||
|
if (musicNameSelect.options.length === 0) {
|
||||||
|
startsWithKeyword = false;
|
||||||
|
} else {
|
||||||
|
startsWithKeyword = selectedOption.text.startsWith("使用关键词联网搜索:");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startsWithKeyword) {
|
||||||
|
musicFilenameInput.style.display = "block";
|
||||||
|
musicFilenameInput.placeholder =
|
||||||
|
"请输入保存为的文件名称(默认:" + selectedOption.value + ")";
|
||||||
|
} else {
|
||||||
|
musicFilenameInput.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 观察元素修改
|
||||||
|
const observer = new MutationObserver((mutationsList) => {
|
||||||
|
for (const mutation of mutationsList) {
|
||||||
|
if (mutation.type === "childList") {
|
||||||
|
updateInputVisibility();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe(musicNameSelect, { childList: true });
|
||||||
|
// 监听用户输入
|
||||||
|
musicNameSelect.addEventListener("change", updateInputVisibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearch();
|
||||||
|
|
||||||
|
function get_playing_music() {
|
||||||
|
$.get(`/playingmusic?did=${did}`, function (data, status) {
|
||||||
|
console.log(data);
|
||||||
|
if (data.ret == "OK") {
|
||||||
|
if (data.is_playing) {
|
||||||
|
$("#playering-music").text(`【播放中】 ${data.cur_music}`);
|
||||||
|
} else {
|
||||||
|
$("#playering-music").text(`【空闲中】 ${data.cur_music}`);
|
||||||
|
}
|
||||||
|
offset = data.offset;
|
||||||
|
duration = data.duration;
|
||||||
|
//检查歌曲是否在收藏中,如果是,设置收藏按钮为选中状态
|
||||||
|
console.log(
|
||||||
|
"%cmd.js:614 object",
|
||||||
|
"color: #007acc;",
|
||||||
|
favoritelist.includes(data.cur_music)
|
||||||
|
);
|
||||||
|
if (favoritelist.includes(data.cur_music)) {
|
||||||
|
$(".favorite").addClass("favorite-active");
|
||||||
|
} else {
|
||||||
|
$(".favorite").removeClass("favorite-active");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setInterval(() => {
|
||||||
|
if (duration > 0) {
|
||||||
|
offset++;
|
||||||
|
$("#progress").val((offset / duration) * 100);
|
||||||
|
$("#current-time").text(formatTime(offset));
|
||||||
|
$("#duration").text(formatTime(duration));
|
||||||
|
} else {
|
||||||
|
$("#current-time").text(formatTime(0));
|
||||||
|
$("#duration").text(formatTime(0));
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
function formatTime(seconds) {
|
||||||
|
var minutes = Math.floor(seconds / 60);
|
||||||
|
var remainingSeconds = Math.floor(seconds % 60);
|
||||||
|
return `${minutes.toString().padStart(2, "0")}:${remainingSeconds
|
||||||
|
.toString()
|
||||||
|
.padStart(2, "0")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("audio").on("error", (e) => {
|
||||||
|
//如果audio标签的src为空,则不做任何操作,兼容安卓端的低版本webview
|
||||||
|
if ($("audio").attr("src") === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
"%c网页播放出现错误: ",
|
||||||
|
"color: #007acc;",
|
||||||
|
e.currentTarget.error.code,
|
||||||
|
e.currentTarget.error.message
|
||||||
|
);
|
||||||
|
alert(
|
||||||
|
e.currentTarget.error.code == 4
|
||||||
|
? "无法打开媒体文件,XIAOMUSIC_HOSTNAME或端口地址错误,请重新设置"
|
||||||
|
: "在线播放失败,请截图反馈: " + e.currentTarget.error.message
|
||||||
|
);
|
||||||
|
});
|
||||||
|
function validHost(url) {
|
||||||
|
//如果 localStorage 中有 no-warning 则直接返回true
|
||||||
|
if (no_warning) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const local = location.host;
|
||||||
|
const host = new URL(url).host;
|
||||||
|
// 如果当前页面的Host与设置中的XIAOMUSIC_HOSTNAME、PORT一致, 不再提醒
|
||||||
|
if (local === host) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#local-host").text(local);
|
||||||
|
$("#setting-host").text(host);
|
||||||
|
$("#warning-component").show();
|
||||||
|
console.log("%c 验证返回false", "color: #007acc;");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function nowarning() {
|
||||||
|
localStorage.setItem("no-warning", "true");
|
||||||
|
no_warning = true;
|
||||||
|
$("#warning-component").hide();
|
||||||
|
}
|
||||||
|
function timedShutDown(cmd) {
|
||||||
|
$(".timer-tooltip").toggle();
|
||||||
|
sendcmd(cmd);
|
||||||
|
setTimeout(() => {
|
||||||
|
$(".timer-tooltip").fadeOut();
|
||||||
|
}, 3000);
|
||||||
|
}
|
@ -4,9 +4,9 @@
|
|||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<title>小爱音箱操控面板</title>
|
<title>小爱音箱操控面板</title>
|
||||||
<script src="./jquery-3.7.1.min.js?version=1733563859"></script>
|
<script src="./jquery-3.7.1.min.js?version=1733199308"></script>
|
||||||
<script src="./setting.js?version=1733563859"></script>
|
<script src="./setting.js?version=1733199308"></script>
|
||||||
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
<link rel="stylesheet" type="text/css" href="./main.css?version=1733199308">
|
||||||
|
|
||||||
<!-- Google tag (gtag.js) -->
|
<!-- Google tag (gtag.js) -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
@ -198,12 +198,6 @@ var vConsole = new window.VConsole();
|
|||||||
<option value="false" selected>false</option>
|
<option value="false" selected>false</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="enable_save_tag">启用ID3标签写入文件:</label>
|
|
||||||
<select id="enable_save_tag">
|
|
||||||
<option value="true">true</option>
|
|
||||||
<option value="false" selected>false</option>
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<label for="get_ask_by_mina">特殊型号获取对话记录:</label>
|
<label for="get_ask_by_mina">特殊型号获取对话记录:</label>
|
||||||
<select id="get_ask_by_mina">
|
<select id="get_ask_by_mina">
|
||||||
<option value="true">true</option>
|
<option value="true">true</option>
|
||||||
@ -231,27 +225,27 @@ var vConsole = new window.VConsole();
|
|||||||
<button id="upload_yt_dlp_cookie">上传</button>
|
<button id="upload_yt_dlp_cookie">上传</button>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
<div class="button-group-other">
|
||||||
<button onclick="location.href='/static/default/index.html';">返回首页</button>
|
<button onclick="location.href='/static/default/index.html';">返回首页</button>
|
||||||
<button id="get_music_list">获取歌单</button>
|
<button id="get_music_list">获取歌单</button>
|
||||||
<button class="save-button">保存</button>
|
<button class="save-button">保存</button>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<button id="refresh_music_tag">刷新tag</button>
|
<button id="refresh_music_tag">刷新tag</button>
|
||||||
<button id="clear_cache">清空缓存</button>
|
<button id="clear_cache">清空缓存</button>
|
||||||
<a class="button" href="/downloadlog" download="xiaomusic.txt">下载日志文件</a>
|
<a href="/downloadlog" download="xiaomusic.txt"><button>下载日志文件</button></a>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
<a href="/docs" target="_blank"><button>查看接口文档</button></a>
|
||||||
<button onclick="location.href='/docs';">查看接口文档</button>
|
<a href="./m3u.html" target="_blank"><button>m3u文件转换</button></a>
|
||||||
<a class="button" href="./m3u.html" target="_blank">m3u文件转换</a>
|
<a href="./downloadtool.html" target="_blank"><button>歌曲下载工具</button></a>
|
||||||
<a class="button" href="./downloadtool.html" target="_blank">歌曲下载工具</a>
|
<hr>
|
||||||
<hr>
|
|
||||||
|
<a href="./debug.html" target="_blank"><button>调试工具</button></a>
|
||||||
<a class="button" href="./debug.html" target="_blank">调试工具</a>
|
<a href="https://afdian.com/a/imhanxi" target="_blank"><button>💰 爱发电</button></a>
|
||||||
<a class="button" href="https://afdian.com/a/imhanxi" target="_blank">💰 爱发电</a>
|
<a href="https://github.com/hanxi/xiaomusic" target="_blank"><button>点个 Star ⭐</button></a>
|
||||||
<a class="button" href="https://github.com/hanxi/xiaomusic" target="_blank">点个 Star ⭐</a>
|
|
||||||
|
</div>
|
||||||
<div class="rows">
|
<div class="rows">
|
||||||
<img class="qrcode" src="./qrcode.png" alt="请涵曦喝奶茶🧋">
|
<img class="qrcode" src="./qrcode.png" alt="请涵曦喝奶茶🧋">
|
||||||
</div>
|
</div>
|
||||||
|
520
xiaomusic/static/default_past/app.js
Normal file
520
xiaomusic/static/default_past/app.js
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
$(function(){
|
||||||
|
$container=$("#cmds");
|
||||||
|
|
||||||
|
append_op_button_name("加入收藏");
|
||||||
|
append_op_button_name("取消收藏");
|
||||||
|
|
||||||
|
append_op_button_name("上一首");
|
||||||
|
append_op_button_name("关机");
|
||||||
|
append_op_button_name("下一首");
|
||||||
|
|
||||||
|
const PLAY_TYPE_ONE = 0; // 单曲循环
|
||||||
|
const PLAY_TYPE_ALL = 1; // 全部循环
|
||||||
|
const PLAY_TYPE_RND = 2; // 随机播放
|
||||||
|
const PLAY_TYPE_SIN = 3; // 单曲播放
|
||||||
|
const PLAY_TYPE_SEQ = 4; // 顺序播放
|
||||||
|
append_op_button("play_type_all", "全部循环", "全部循环");
|
||||||
|
append_op_button("play_type_one", "单曲循环", "单曲循环");
|
||||||
|
append_op_button("play_type_rnd", "随机播放", "随机播放");
|
||||||
|
append_op_button("play_type_sin", "单曲播放", "单曲播放");
|
||||||
|
append_op_button("play_type_seq", "顺序播放", "顺序播放");
|
||||||
|
|
||||||
|
append_op_button_name("刷新列表");
|
||||||
|
|
||||||
|
$container.append($("<hr>"));
|
||||||
|
|
||||||
|
append_op_button_name("10分钟后关机");
|
||||||
|
append_op_button_name("30分钟后关机");
|
||||||
|
append_op_button_name("60分钟后关机");
|
||||||
|
|
||||||
|
var offset = 0;
|
||||||
|
var duration = 0;
|
||||||
|
let no_warning = localStorage.getItem('no-warning');
|
||||||
|
// 拉取现有配置
|
||||||
|
$.get("/getsetting", function(data, status) {
|
||||||
|
console.log(data, status);
|
||||||
|
localStorage.setItem('mi_did', data.mi_did);
|
||||||
|
|
||||||
|
var did = localStorage.getItem('cur_did');
|
||||||
|
var dids = [];
|
||||||
|
if (data.mi_did != null) {
|
||||||
|
dids = data.mi_did.split(',');
|
||||||
|
}
|
||||||
|
console.log('cur_did', did);
|
||||||
|
console.log('dids', dids);
|
||||||
|
if ((dids.length > 0) && (did == null || did == "" || !dids.includes(did))) {
|
||||||
|
did = dids[0];
|
||||||
|
localStorage.setItem('cur_did', did);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.did = did;
|
||||||
|
$.get(`/getvolume?did=${did}`, function(data, status) {
|
||||||
|
console.log(data, status, data["volume"]);
|
||||||
|
$("#volume").val(data.volume);
|
||||||
|
});
|
||||||
|
refresh_music_list();
|
||||||
|
|
||||||
|
$("#did").empty();
|
||||||
|
var dids = data.mi_did.split(',');
|
||||||
|
$.each(dids, function(index, value) {
|
||||||
|
var cur_device = Object.values(data.devices).find(device => device.did === value);
|
||||||
|
if (cur_device) {
|
||||||
|
var option = $('<option></option>')
|
||||||
|
.val(value)
|
||||||
|
.text(cur_device.name)
|
||||||
|
.prop('selected', value === did);
|
||||||
|
$("#did").append(option);
|
||||||
|
|
||||||
|
if (value === did) {
|
||||||
|
if (cur_device.play_type == PLAY_TYPE_ALL) {
|
||||||
|
$("#play_type_all").css('background-color', '#b1a8f3');
|
||||||
|
$("#play_type_all").text('✔️ 全部循环');
|
||||||
|
} else if (cur_device.play_type == PLAY_TYPE_ONE) {
|
||||||
|
$("#play_type_one").css('background-color', '#b1a8f3');
|
||||||
|
$("#play_type_one").text('✔️ 单曲循环');
|
||||||
|
} else if (cur_device.play_type == PLAY_TYPE_RND) {
|
||||||
|
$("#play_type_rnd").css('background-color', '#b1a8f3');
|
||||||
|
$("#play_type_rnd").text('✔️ 随机播放');
|
||||||
|
} else if (cur_device.play_type == PLAY_TYPE_SIN) {
|
||||||
|
$("#play_type_sin").css('background-color', '#b1a8f3');
|
||||||
|
$("#play_type_sin").text('✔️ 单曲播放');
|
||||||
|
} else if (cur_device.play_type == PLAY_TYPE_SEQ) {
|
||||||
|
$("#play_type_seq").css('background-color', '#b1a8f3');
|
||||||
|
$("#play_type_seq").text('✔️ 顺序播放');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('cur_did', did);
|
||||||
|
$('#did').change(function() {
|
||||||
|
did = $(this).val();
|
||||||
|
localStorage.setItem('cur_did', did);
|
||||||
|
window.did = did;
|
||||||
|
console.log('cur_did', did);
|
||||||
|
location.reload();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
function compareVersion(version1, version2) {
|
||||||
|
const v1 = version1.split('.').map(Number);
|
||||||
|
const v2 = version2.split('.').map(Number);
|
||||||
|
const len = Math.max(v1.length, v2.length);
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const num1 = v1[i] || 0;
|
||||||
|
const num2 = v2[i] || 0;
|
||||||
|
if (num1 > num2) return 1;
|
||||||
|
if (num1 < num2) return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拉取版本
|
||||||
|
$.get("/getversion", function(data, status) {
|
||||||
|
console.log(data, status, data["version"]);
|
||||||
|
$("#version").text(`${data.version}`);
|
||||||
|
|
||||||
|
$.get("/latestversion", function(ret, status) {
|
||||||
|
console.log(ret, status);
|
||||||
|
if (ret.ret == "OK") {
|
||||||
|
const result = compareVersion(ret.version, data.version);
|
||||||
|
if (result > 0) {
|
||||||
|
console.log(`${ret.version} is greater than ${data.version}`);
|
||||||
|
$("#versionnew").text("🆕");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function _refresh_music_list(callback) {
|
||||||
|
$('#music_list').empty();
|
||||||
|
$.get("/musiclist", function(data, status) {
|
||||||
|
console.log(data, status);
|
||||||
|
$.each(data, function(key, value) {
|
||||||
|
let cnt = value.length;
|
||||||
|
$('#music_list').append($('<option></option>').val(key).text(`${key} (${cnt})`));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#music_list').change(function() {
|
||||||
|
const selectedValue = $(this).val();
|
||||||
|
localStorage.setItem('cur_playlist', selectedValue);
|
||||||
|
$('#music_name').empty();
|
||||||
|
$.each(data[selectedValue], function(index, item) {
|
||||||
|
$('#music_name').append($('<option></option>').val(item).text(item));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#music_list').trigger('change');
|
||||||
|
|
||||||
|
// 获取当前播放列表
|
||||||
|
$.get(`/curplaylist?did=${did}`, function(playlist, status) {
|
||||||
|
if (playlist != "") {
|
||||||
|
$('#music_list').val(playlist);
|
||||||
|
$('#music_list').trigger('change');
|
||||||
|
} else {
|
||||||
|
// 使用本地记录的
|
||||||
|
playlist = localStorage.getItem('cur_playlist');
|
||||||
|
if (data.includes(playlist)) {
|
||||||
|
$('#music_list').val(playlist);
|
||||||
|
$('#music_list').trigger('change');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
callback();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拉取播放列表
|
||||||
|
function refresh_music_list() {
|
||||||
|
// 刷新列表时清空并临时禁用搜索框
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
const oriPlaceHolder = searchInput.placeholder
|
||||||
|
const oriValue = searchInput.value
|
||||||
|
const inputEvent = new Event('input', { bubbles: true });
|
||||||
|
searchInput.value = '';
|
||||||
|
// 分发事件,让其他控件改变状态
|
||||||
|
searchInput.dispatchEvent(inputEvent);
|
||||||
|
searchInput.disabled = true;
|
||||||
|
searchInput.placeholder = '请等待...';
|
||||||
|
|
||||||
|
_refresh_music_list(() => {
|
||||||
|
// 刷新完成再启用
|
||||||
|
searchInput.disabled = false;
|
||||||
|
searchInput.value = oriValue
|
||||||
|
searchInput.dispatchEvent(inputEvent);
|
||||||
|
searchInput.placeholder = oriPlaceHolder;
|
||||||
|
// 每3秒获取下正在播放的音乐
|
||||||
|
get_playing_music();
|
||||||
|
setInterval(() => {
|
||||||
|
get_playing_music();
|
||||||
|
}, 3000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_play_music_list(listname, musicname) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/playmusiclist",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({did: did, listname: listname, musicname: musicname}),
|
||||||
|
success: () => {
|
||||||
|
console.log("do_play_music_list succ", listname, musicname);
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
console.log("do_play_music_list failed", listname, musicname);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#play_music_list").on("click", () => {
|
||||||
|
var music_list = $("#music_list").val();
|
||||||
|
var music_name = $("#music_name").val();
|
||||||
|
if (no_warning) {
|
||||||
|
do_play_music_list(music_list, music_name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.get(`/musicinfo?name=${music_name}`, function(data, status) {
|
||||||
|
console.log(data);
|
||||||
|
if (data.ret == "OK") {
|
||||||
|
validHost(data.url) && do_play_music_list(music_list, music_name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#web_play").on("click", () => {
|
||||||
|
const music_name = $("#music_name").val();
|
||||||
|
$.get(`/musicinfo?name=${music_name}`, function(data, status) {
|
||||||
|
console.log(data);
|
||||||
|
if (data.ret == "OK") {
|
||||||
|
validHost(data.url) && $('audio').attr('src',data.url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#del_music").on("click", () => {
|
||||||
|
var del_music_name = $("#music_name").val();
|
||||||
|
if (confirm(`确定删除歌曲 ${del_music_name} 吗?`)) {
|
||||||
|
console.log(`删除歌曲 ${del_music_name}`);
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/delmusic',
|
||||||
|
data: JSON.stringify({"name": del_music_name}),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
success: () => {
|
||||||
|
alert(`删除 ${del_music_name} 成功`);
|
||||||
|
refresh_music_list();
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
alert(`删除 ${del_music_name} 失败`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#playurl").on("click", () => {
|
||||||
|
var url = $("#music-url").val();
|
||||||
|
const encoded_url = encodeURIComponent(url);
|
||||||
|
$.get(`/playurl?url=${encoded_url}&did=${did}`, function(data, status) {
|
||||||
|
console.log(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function append_op_button_name(name) {
|
||||||
|
append_op_button(null, name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function append_op_button(id, name, cmd) {
|
||||||
|
// 创建按钮
|
||||||
|
const $button = $("<button>");
|
||||||
|
$button.text(name);
|
||||||
|
$button.attr("type", "button");
|
||||||
|
if (id !== null) {
|
||||||
|
$button.attr("id", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置按钮点击事件
|
||||||
|
$button.on("click", () => {
|
||||||
|
sendcmd(cmd);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 添加按钮到容器
|
||||||
|
$container.append($button);
|
||||||
|
}
|
||||||
|
|
||||||
|
function do_play_music(musicname, searchkey) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/playmusic",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({did: did, musicname: musicname, searchkey: searchkey}),
|
||||||
|
success: () => {
|
||||||
|
console.log("do_play_music succ", musicname, searchkey);
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
console.log("do_play_music failed", musicname, searchkey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$("#play").on("click", () => {
|
||||||
|
var search_key = $("#music-name").val();
|
||||||
|
if (search_key == null) {
|
||||||
|
search_key = "";
|
||||||
|
}
|
||||||
|
var filename = $("#music-filename").val();
|
||||||
|
if (filename == null || filename == "") {
|
||||||
|
filename = search_key;
|
||||||
|
}
|
||||||
|
do_play_music(filename, search_key);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#volume").on('change', function () {
|
||||||
|
var value = $(this).val();
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/setvolume",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({did: did, volume: value}),
|
||||||
|
success: () => {
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function check_status_refresh_music_list(retries) {
|
||||||
|
$.get("/cmdstatus", function(data) {
|
||||||
|
if (data.status === "finish") {
|
||||||
|
refresh_music_list();
|
||||||
|
} else if (retries > 0) {
|
||||||
|
setTimeout(function() {
|
||||||
|
check_status_refresh_music_list(retries - 1);
|
||||||
|
}, 1000); // 等待1秒后重试
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendcmd(cmd) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/cmd",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({did: did, cmd: cmd}),
|
||||||
|
success: () => {
|
||||||
|
if (cmd == "刷新列表") {
|
||||||
|
check_status_refresh_music_list(3); // 最多重试3次
|
||||||
|
}
|
||||||
|
if (["全部循环", "单曲循环", "随机播放", "单曲播放", "顺序播放"].includes(cmd)) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
// 请求失败时执行的操作
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听输入框的输入事件
|
||||||
|
function debounce(func, delay) {
|
||||||
|
let timeout;
|
||||||
|
return function(...args) {
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(() => func.apply(this, args), delay);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const searchInput = document.getElementById('search');
|
||||||
|
const musicSelect = document.getElementById('music-name');
|
||||||
|
const musicSelectLabel = document.getElementById('music-name-label');
|
||||||
|
|
||||||
|
searchInput.addEventListener('input', debounce(function() {
|
||||||
|
const query = searchInput.value.trim();
|
||||||
|
|
||||||
|
if (query.length === 0) {
|
||||||
|
musicSelect.innerHTML = '';
|
||||||
|
musicSelect.style.display = 'none'
|
||||||
|
musicSelectLabel.style.display = 'none'
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
musicSelect.style.display = 'block'
|
||||||
|
musicSelectLabel.style.display = 'block'
|
||||||
|
fetch(`/searchmusic?name=${encodeURIComponent(query)}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
musicSelect.innerHTML = ''; // 清空现有选项
|
||||||
|
|
||||||
|
// 找到的优先显示
|
||||||
|
if (data.length > 0) {
|
||||||
|
data.forEach(song => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = song
|
||||||
|
option.textContent = song
|
||||||
|
musicSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加用户输入作为一个选项
|
||||||
|
const userOption = document.createElement('option');
|
||||||
|
userOption.value = query;
|
||||||
|
userOption.textContent = `使用关键词播放: ${query}`;
|
||||||
|
musicSelect.appendChild(userOption);
|
||||||
|
|
||||||
|
// 提示没找到
|
||||||
|
if (data.length === 0) {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.textContent = '没有匹配的结果';
|
||||||
|
option.disabled = true;
|
||||||
|
musicSelect.appendChild(option);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
});
|
||||||
|
}, 500));
|
||||||
|
|
||||||
|
// 动态显示保存文件名输入框
|
||||||
|
const musicNameSelect = document.getElementById('music-name');
|
||||||
|
const musicFilenameInput = document.getElementById('music-filename');
|
||||||
|
function updateInputVisibility() {
|
||||||
|
const selectedOption = musicNameSelect.options[musicNameSelect.selectedIndex];
|
||||||
|
var startsWithKeyword;
|
||||||
|
if (musicNameSelect.options.length === 0) {
|
||||||
|
startsWithKeyword = false;
|
||||||
|
} else {
|
||||||
|
startsWithKeyword = selectedOption.text.startsWith('使用关键词联网搜索:');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startsWithKeyword) {
|
||||||
|
musicFilenameInput.style.display = 'block';
|
||||||
|
musicFilenameInput.placeholder = '请输入保存为的文件名称(默认:' + selectedOption.value + ')';
|
||||||
|
} else {
|
||||||
|
musicFilenameInput.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 观察元素修改
|
||||||
|
const observer = new MutationObserver((mutationsList) => {
|
||||||
|
for (const mutation of mutationsList) {
|
||||||
|
if (mutation.type === 'childList') {
|
||||||
|
updateInputVisibility()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
observer.observe(musicNameSelect, { childList: true });
|
||||||
|
// 监听用户输入
|
||||||
|
musicNameSelect.addEventListener('change', updateInputVisibility);
|
||||||
|
|
||||||
|
function get_playing_music() {
|
||||||
|
$.get(`/playingmusic?did=${did}`, function(data, status) {
|
||||||
|
console.log(data);
|
||||||
|
if (data.ret == "OK") {
|
||||||
|
if (data.is_playing) {
|
||||||
|
$("#playering-music").text(`【播放中】 ${data.cur_music}`);
|
||||||
|
} else {
|
||||||
|
$("#playering-music").text(`【空闲中】 ${data.cur_music}`);
|
||||||
|
}
|
||||||
|
offset = data.offset;
|
||||||
|
duration = data.duration;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setInterval(()=>{
|
||||||
|
if (duration > 0) {
|
||||||
|
offset++;
|
||||||
|
$("#progress").val(offset / duration * 100);
|
||||||
|
$("#play-time").text(`${formatTime(offset)}/${formatTime(duration)}`)
|
||||||
|
}else{
|
||||||
|
$("#play-time").text(`${formatTime(0)}/${formatTime(0)}`)
|
||||||
|
}
|
||||||
|
},1000)
|
||||||
|
function formatTime(seconds) {
|
||||||
|
var minutes = Math.floor(seconds / 60);
|
||||||
|
var remainingSeconds =Math.floor(seconds % 60);
|
||||||
|
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("audio").on("error", (e) => {
|
||||||
|
//如果audio标签的src为空,则不做任何操作,兼容安卓端的低版本webview
|
||||||
|
if ($("audio").attr("src") === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('%c网页播放出现错误: ', 'color: #007acc;', e.currentTarget.error.code,e.currentTarget.error.message);
|
||||||
|
alert(e.currentTarget.error.code==4 ? "无法打开媒体文件,XIAOMUSIC_HOSTNAME或端口地址错误,请重新设置" : "在线播放失败,请截图反馈: "+e.currentTarget.error.message);
|
||||||
|
});
|
||||||
|
function validHost(url) {
|
||||||
|
//如果 localStorage 中有 no-warning 则直接返回true
|
||||||
|
if (no_warning) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const local = location.host;
|
||||||
|
const host = new URL(url).host;
|
||||||
|
// 如果当前页面的Host与设置中的XIAOMUSIC_HOSTNAME、PORT一致, 不再提醒
|
||||||
|
if (local === host) {
|
||||||
|
|
||||||
|
localStorage.setItem('no-warning', 'true');
|
||||||
|
// 设置全局变量
|
||||||
|
no_warning = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 如果当前页面的Host与设置中的XIAOMUSIC_HOSTNAME、PORT不一致
|
||||||
|
const validHost = document.getElementById('valid-host');
|
||||||
|
let validFlag = false;
|
||||||
|
$('#local-host').text(local);
|
||||||
|
$('#setting-host').text(host);
|
||||||
|
validHost.showModal();
|
||||||
|
//监听validHost的close事件
|
||||||
|
function _handleClose() {
|
||||||
|
console.log('%c提醒HOST不一致弹窗,用户已选择: ', 'color: #007acc;', validHost.returnValue);
|
||||||
|
if (validHost.returnValue == "no-warning") {
|
||||||
|
localStorage.setItem('no-warning', 'true');
|
||||||
|
no_warning = true;
|
||||||
|
validFlag = true;
|
||||||
|
}
|
||||||
|
validHost.removeEventListener('close', _handleClose)
|
||||||
|
}
|
||||||
|
validHost.addEventListener('close', _handleClose)
|
||||||
|
return validFlag;
|
||||||
|
}
|
||||||
|
});
|
71
xiaomusic/static/default_past/debug.html
Normal file
71
xiaomusic/static/default_past/debug.html
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<title>Debug For XiaoMusic</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
||||||
|
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||||
|
<script src="./jquery-3.7.1.min.js?version=1733563859"></script>
|
||||||
|
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments)};
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', 'G-Z09NC1K7ZW');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var vConsole = new window.VConsole();
|
||||||
|
|
||||||
|
function postJSON() {
|
||||||
|
var data = $('#post-input').val();
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/debug_play_by_music_url',
|
||||||
|
data: data,
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
success: (err) => {
|
||||||
|
console.log("succ", res);
|
||||||
|
},
|
||||||
|
error: (res) => {
|
||||||
|
console.log("error", res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendDebugCmd() {
|
||||||
|
var cmd = $("#cmd").val();
|
||||||
|
var did = localStorage.getItem('cur_did');
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/cmd",
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
data: JSON.stringify({did: did, cmd: cmd}),
|
||||||
|
success: () => {
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
// 请求失败时执行的操作
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Debug For XiaoMusic</h1>
|
||||||
|
<textarea id="post-input" rows="10" cols="50" placeholder="粘贴json数据..."></textarea><br>
|
||||||
|
<button onclick="postJSON()">提交</button><br>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<input id="cmd" type="text"></input>
|
||||||
|
<button onclick="sendDebugCmd()">测试自定义口令</button><br>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
|
||||||
|
</footer>
|
||||||
|
</html>
|
113
xiaomusic/static/default_past/downloadtool.html
Normal file
113
xiaomusic/static/default_past/downloadtool.html
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<title>歌曲下载工具</title>
|
||||||
|
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
||||||
|
<script src="./jquery-3.7.1.min.js?version=1733563859"></script>
|
||||||
|
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments)};
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', 'G-Z09NC1K7ZW');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>歌曲下载工具</h1>
|
||||||
|
|
||||||
|
<div class="rows">
|
||||||
|
<!-- 歌单的输入 -->
|
||||||
|
<label for="playlistUrl">输入歌单 URL:</label>
|
||||||
|
<input type="text" id="playlistUrl" value="https://m.bilibili.com/video/BV1WUsDezE88">
|
||||||
|
|
||||||
|
<label for="dirname">输入歌单名字:</label>
|
||||||
|
<input type="text" id="dirname" placeholder="流行歌曲">
|
||||||
|
|
||||||
|
<button id="downloadPlaylistBtn">下载歌单</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="rows">
|
||||||
|
|
||||||
|
<!-- 单曲的输入 -->
|
||||||
|
<label for="songUrl">输入歌曲 URL:</label>
|
||||||
|
<input type="text" id="songUrl" value="https://m.bilibili.com/video/BV1qD4y1U7fs">
|
||||||
|
|
||||||
|
<label for="songName">输入歌曲名字:</label>
|
||||||
|
<input type="text" id="songName" placeholder="歌曲名">
|
||||||
|
|
||||||
|
<button id="downloadSongBtn">下载单曲</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 下载歌单
|
||||||
|
$('#downloadPlaylistBtn').click(function() {
|
||||||
|
var playlistUrl = $('#playlistUrl').val();
|
||||||
|
var dirname = $('#dirname').val();
|
||||||
|
|
||||||
|
if (!playlistUrl || !dirname) {
|
||||||
|
alert('请填写完整的歌单 URL 和歌单名字');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
dirname: dirname,
|
||||||
|
url: playlistUrl
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/downloadplaylist",
|
||||||
|
contentType: "application/json",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
success: (msg) => {
|
||||||
|
alert('歌单下载请求已发送!');
|
||||||
|
console.log(response);
|
||||||
|
},
|
||||||
|
error: (msg) => {
|
||||||
|
alert('歌单下载请求失败,请重试。');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 下载单曲
|
||||||
|
$('#downloadSongBtn').click(function() {
|
||||||
|
var songName = $('#songName').val();
|
||||||
|
var songUrl = $('#songUrl').val();
|
||||||
|
|
||||||
|
if (!songUrl || !songName) {
|
||||||
|
alert('请填写完整的歌曲 URL 和歌曲名字');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
name: songName,
|
||||||
|
url: songUrl
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/downloadonemusic",
|
||||||
|
contentType: "application/json",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
success: (msg) => {
|
||||||
|
alert('单曲下载请求已发送!');
|
||||||
|
console.log(response);
|
||||||
|
},
|
||||||
|
error: (msg) => {
|
||||||
|
alert('单曲下载请求失败,请重试。');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
110
xiaomusic/static/default_past/index.html
Normal file
110
xiaomusic/static/default_past/index.html
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="icon" href="/favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<title>小爱音箱操控面板</title>
|
||||||
|
<script src="./jquery-3.7.1.min.js?version=1733563859"></script>
|
||||||
|
<script src="./app.js?version=1733563859"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
||||||
|
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments)};
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', 'G-Z09NC1K7ZW');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||||
|
<script>
|
||||||
|
var vConsole = new window.VConsole();
|
||||||
|
</script>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>小爱音箱操控面板
|
||||||
|
(<a id="version" href="https://github.com/hanxi/xiaomusic/blob/main/CHANGELOG.md">版本未知</a>)
|
||||||
|
<span id="versionnew" class="blink"></span>
|
||||||
|
</h2>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="rows">
|
||||||
|
<select id="did">
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="cmds">
|
||||||
|
<a class="button" href="./setting.html">设置</a>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div style="margin: 20px;">
|
||||||
|
<div style="display: flex; align-items: center;">
|
||||||
|
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" fill="#8e43e7" style="height: 48px; width: 48px;"><path d="M550.826667 154.666667a47.786667 47.786667 0 0 0-19.84 4.48L298.666667 298.666667H186.453333A80 80 0 0 0 106.666667 378.453333v267.093334A80 80 0 0 0 186.453333 725.333333H298.666667l232.32 139.52a47.786667 47.786667 0 0 0 19.84 4.48A46.506667 46.506667 0 0 0 597.333333 822.826667V201.173333a46.506667 46.506667 0 0 0-46.506666-46.506666zM554.666667 822.826667c0 3.413333-3.84 3.84-3.84 3.84L320 688.853333l-9.6-6.186666H186.453333A37.12 37.12 0 0 1 149.333333 645.546667V378.453333A37.12 37.12 0 0 1 186.453333 341.333333h123.946667l10.24-6.186666 229.546667-137.6s3.84 0 3.84 3.84zM667.52 346.026667a21.333333 21.333333 0 0 0 0 30.293333 192 192 0 0 1 0 271.36 21.333333 21.333333 0 0 0 0 30.293333 21.333333 21.333333 0 0 0 30.293333 0 234.666667 234.666667 0 0 0 0-331.946666 21.333333 21.333333 0 0 0-30.293333 0z"></path><path d="M804.48 219.52a21.333333 21.333333 0 0 0-30.293333 30.293333 370.986667 370.986667 0 0 1 0 524.373334 21.333333 21.333333 0 0 0 0 30.293333 21.333333 21.333333 0 0 0 30.293333 0 414.08 414.08 0 0 0 0-584.96z"></path></svg>
|
||||||
|
<input id="volume" type="range"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="rows">
|
||||||
|
<label for="search">搜索歌曲:</label>
|
||||||
|
<input type="text" id="search" placeholder="请输入搜索关键词(如:MV高清版 周杰伦 七里香)">
|
||||||
|
|
||||||
|
<label for="music-name" id="music-name-label" style="display: none;">确认选择:</label>
|
||||||
|
<select id="music-name" style="display: none;">
|
||||||
|
<!-- 动态生成选项 -->
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<input id="music-filename" type="text" placeholder="请输入保存为的文件名称(如:周杰伦七里香)" style="display: none;"></input>
|
||||||
|
<div style="display: flex; align-items: center">
|
||||||
|
<progress id="progress" value="0" max="100" style="width: 270px"></progress>
|
||||||
|
<div id="play-time" style="margin-left: 10px">00:00/00:00</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button id="play">播放</button>
|
||||||
|
<div id="playering-music" class="text"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<div class="rows">
|
||||||
|
<label for="music_list">播放列表:</label>
|
||||||
|
<select id="music_list"></select>
|
||||||
|
<label for="music_name">歌曲:</label>
|
||||||
|
<select id="music_name"></select>
|
||||||
|
<div>
|
||||||
|
<button id="play_music_list">播放选中歌曲</button>
|
||||||
|
<button id="del_music">删除选中歌曲</button>
|
||||||
|
<button id="web_play">网页播放</button>
|
||||||
|
</div>
|
||||||
|
<div class="play_pannel">
|
||||||
|
<audio autoplay controls src=""></audio>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<div class="rows">
|
||||||
|
<input id="music-url" type="text" value="https://lhttp.qtfm.cn/live/4915/64k.mp3"></input>
|
||||||
|
<button id="playurl">播放链接</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
|
||||||
|
</footer>
|
||||||
|
<dialog id="valid-host">
|
||||||
|
<form method="dialog">
|
||||||
|
<p>当前页面的HOST与设置中的HOST不一致,请检查是否设置错误</p>
|
||||||
|
<p>当前HOST: <span id="local-host"></span></p>
|
||||||
|
<p>设置中的HOST: <span id="setting-host"></span></p>
|
||||||
|
<div class="btn-list">
|
||||||
|
<a href="./setting.html" target="_blank">立即修改</a>
|
||||||
|
<button value="no-warning" type="submit">继续并不再显示</button>
|
||||||
|
<button value="cancle" type="submit">取消</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</dialog>
|
||||||
|
</body>
|
||||||
|
</html>
|
2
xiaomusic/static/default_past/jquery-3.7.1.min.js
vendored
Normal file
2
xiaomusic/static/default_past/jquery-3.7.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
75
xiaomusic/static/default_past/m3u.html
Normal file
75
xiaomusic/static/default_past/m3u.html
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<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=1733563859">
|
||||||
|
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments)};
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', 'G-Z09NC1K7ZW');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||||
|
<script>
|
||||||
|
// VConsole 默认会挂载到 `window.VConsole` 上
|
||||||
|
var vConsole = new window.VConsole();
|
||||||
|
</script>
|
||||||
|
-->
|
||||||
|
<script>
|
||||||
|
function handleFileSelect(evt) {
|
||||||
|
var file = evt.target.files[0];
|
||||||
|
if (file) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(e) {
|
||||||
|
document.getElementById('m3u-input').value = e.target.result;
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
} else {
|
||||||
|
alert('无法加载文件');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertToJSON() {
|
||||||
|
var m3uContent = document.getElementById('m3u-input').value;
|
||||||
|
var lines = m3uContent.split('\n');
|
||||||
|
console.log(lines);
|
||||||
|
var musicsArray = [];
|
||||||
|
var currentName = '';
|
||||||
|
lines.forEach(function(line) {
|
||||||
|
line = line.trim();
|
||||||
|
if (line.startsWith('#EXTINF:')) {
|
||||||
|
currentName = line.replace(/.*,/g, '');
|
||||||
|
} else if (line.startsWith('http') && currentName !== '') {
|
||||||
|
musicsArray.push({"name": currentName, "type": "radio", "url": line});
|
||||||
|
currentName = ''; // Reset the name for the next entry
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var output = [{
|
||||||
|
"name": "m3u电台",
|
||||||
|
"musics": musicsArray
|
||||||
|
}];
|
||||||
|
|
||||||
|
document.getElementById('json-output').value = JSON.stringify(output, null, 2);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>M3U to JSON Converter</h1>
|
||||||
|
<input type="file" id="file-input" accept=".m3u" onchange="handleFileSelect(event)"/><br>
|
||||||
|
<textarea id="m3u-input" rows="10" cols="50" placeholder="粘贴m3u内容或上传文件..."></textarea><br>
|
||||||
|
<button onclick="convertToJSON()">转换</button><br>
|
||||||
|
<textarea id="json-output" rows="10" cols="50" placeholder="转换后的JSON..."></textarea>
|
||||||
|
</body>
|
||||||
|
<footer>
|
||||||
|
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
|
||||||
|
</footer>
|
||||||
|
</html>
|
||||||
|
|
BIN
xiaomusic/static/default_past/qrcode.png
Normal file
BIN
xiaomusic/static/default_past/qrcode.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
262
xiaomusic/static/default_past/setting.html
Normal file
262
xiaomusic/static/default_past/setting.html
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="icon" href="/favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width">
|
||||||
|
<title>小爱音箱操控面板</title>
|
||||||
|
<script src="./jquery-3.7.1.min.js?version=1733563859"></script>
|
||||||
|
<script src="./setting.js?version=1733563859"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="./style.css?version=1733563859">
|
||||||
|
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments)};
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', 'G-Z09NC1K7ZW');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<script src="https://unpkg.com/vconsole@latest/dist/vconsole.min.js"></script>
|
||||||
|
<script>
|
||||||
|
var vConsole = new window.VConsole();
|
||||||
|
</script>
|
||||||
|
-->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>小爱音箱设置面板
|
||||||
|
(<a id="version" href="https://github.com/hanxi/xiaomusic/blob/main/CHANGELOG.md">
|
||||||
|
版本未知
|
||||||
|
</a>)
|
||||||
|
</h2>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="rows">
|
||||||
|
<label for="mi_did">*勾选设备(至少勾选1个):</label>
|
||||||
|
<div id="mi_did">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div id="setting">
|
||||||
|
<div class="rows">
|
||||||
|
<label for="account">*小米账号:</label>
|
||||||
|
<input id="account" type="text" placeholder="填写小米登录账号" />
|
||||||
|
|
||||||
|
<label for="password">*小米密码:</label>
|
||||||
|
<input id="password" type="password" placeholder="填写小米登录密码" />
|
||||||
|
|
||||||
|
<label for="hostname">*XIAOMUSIC_HOSTNAME(IP或域名):</label>
|
||||||
|
<input id="hostname" type="text" />
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="rows">
|
||||||
|
<label for="verbose">是否开启调试日志:</label>
|
||||||
|
<select id="verbose">
|
||||||
|
<option value="true" selected>true</option>
|
||||||
|
<option value="false">false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="port">监听端口(修改后需要重启):</label>
|
||||||
|
<input id="port" type="number" value="8090" />
|
||||||
|
|
||||||
|
<label for="public_port">外网访问端口(0表示跟监听端口一致):</label>
|
||||||
|
<input id="public_port" type="number" value="0" />
|
||||||
|
|
||||||
|
<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" />
|
||||||
|
|
||||||
|
<label for="music_path">音乐目录:</label>
|
||||||
|
<input id="music_path" type="text" value="music" />
|
||||||
|
|
||||||
|
<label for="download_path">音乐下载目录(必须是music的子目录):</label>
|
||||||
|
<input id="download_path" type="text" value='music/download' />
|
||||||
|
|
||||||
|
<label for="conf_path">配置文件目录:</label>
|
||||||
|
<input id="conf_path" type="text" />
|
||||||
|
|
||||||
|
<label for="cache_dir">缓存文件目录:</label>
|
||||||
|
<input id="cache_dir" type="text" />
|
||||||
|
|
||||||
|
<label for="temp_path">临时文件目录:</label>
|
||||||
|
<input id="temp_path" type="text" value="music/tmp" />
|
||||||
|
|
||||||
|
<label for="ffmpeg_location">ffmpeg路径:</label>
|
||||||
|
<input id="ffmpeg_location" type="text" value="./ffmpeg/bin" />
|
||||||
|
|
||||||
|
<label for="log_file">日志路径:</label>
|
||||||
|
<input id="log_file" type="text" value="xiaomusic.log.txt" />
|
||||||
|
|
||||||
|
<label for="active_cmd">允许唤醒的命令:</label>
|
||||||
|
<input id="active_cmd" type="text" value="play,random_play,playlocal,play_music_list,stop" />
|
||||||
|
|
||||||
|
<label for="exclude_dirs">忽略目录(逗号分割):</label>
|
||||||
|
<input id="exclude_dirs" type="text" value="@eaDir,tmp" />
|
||||||
|
|
||||||
|
<label for="music_path_depth">目录深度:</label>
|
||||||
|
<input id="music_path_depth" type="number" value="10" />
|
||||||
|
|
||||||
|
<label for="search_prefix">XIAOMUSIC_SEARCH(歌曲下载方式):</label>
|
||||||
|
<select id="search_prefix">
|
||||||
|
<option value="bilisearch:">bilisearch:</option>
|
||||||
|
<option value="ytsearch:">ytsearch:</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="proxy">XIAOMUSIC_PROXY(ytsearch需要):</label>
|
||||||
|
<input id="proxy" type="text" placeholder="http://192.168.2.5:8080" />
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<select id="convert_to_mp3">
|
||||||
|
<option value="true">true</option>
|
||||||
|
<option value="false" selected>false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="miio_tts_command">MiIO tts 指令(解决部分型号没有提示音的问题):</label>
|
||||||
|
<input id="miio_tts_command" type="text" placeholder="如:5 或者 5-3" />
|
||||||
|
|
||||||
|
<label for="disable_httpauth">关闭控制台密码验证:</label>
|
||||||
|
<select id="disable_httpauth">
|
||||||
|
<option value="true" selected>true</option>
|
||||||
|
<option value="false">false</option>
|
||||||
|
</select>
|
||||||
|
<label for="httpauth_username">控制台账户:</label>
|
||||||
|
<input id="httpauth_username" type="text" value="" />
|
||||||
|
<label for="httpauth_password">控制台密码:</label>
|
||||||
|
<input id="httpauth_password" type="password" value="" />
|
||||||
|
|
||||||
|
<label for="disable_download">关闭下载功能:</label>
|
||||||
|
<select id="disable_download">
|
||||||
|
<option value="true">true</option>
|
||||||
|
<option value="false" selected>false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="use_music_audio_id">触屏版显示歌曲ID:</label>
|
||||||
|
<input id="use_music_audio_id" type="text" value="1582971365183456177" />
|
||||||
|
<label for="use_music_id">触屏版显示歌曲分段ID:</label>
|
||||||
|
<input id="use_music_id" type="text" value="355454500" />
|
||||||
|
|
||||||
|
<label for="fuzzy_match_cutoff">模糊匹配阈值(0.1~0.9):</label>
|
||||||
|
<input id="fuzzy_match_cutoff" type="number" value="0.6" />
|
||||||
|
|
||||||
|
<label for="enable_fuzzy_match">开启模糊搜索:</label>
|
||||||
|
<select id="enable_fuzzy_match">
|
||||||
|
<option value="true" selected>true</option>
|
||||||
|
<option value="false">false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="use_music_api">型号兼容模式:</label>
|
||||||
|
<select id="use_music_api">
|
||||||
|
<option value="true">true</option>
|
||||||
|
<option value="false" selected>false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="continue_play">启用继续播放(可能导致兼容性问题):</label>
|
||||||
|
<select id="continue_play">
|
||||||
|
<option value="true">true</option>
|
||||||
|
<option value="false" selected>false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="pull_ask_sec">获取对话记录间隔(秒):</label>
|
||||||
|
<input id="pull_ask_sec" type="number" value="1" />
|
||||||
|
|
||||||
|
<label for="delay_sec">下一首歌延迟播放秒数:</label>
|
||||||
|
<input id="delay_sec" type="number" value="3" />
|
||||||
|
|
||||||
|
<label for="stop_tts_msg">停止提示音:</label>
|
||||||
|
<input id="stop_tts_msg" type="text" value="收到,再见" />
|
||||||
|
<label for="play_type_one_tts_msg">单曲循环提示音:</label>
|
||||||
|
<input id="play_type_one_tts_msg" type="text" value="已经设置为单曲循环" />
|
||||||
|
<label for="play_type_all_tts_msg">全部循环提示音:</label>
|
||||||
|
<input id="play_type_all_tts_msg" type="text" value="已经设置为全部循环" />
|
||||||
|
<label for="play_type_rnd_tts_msg">随机播放提示音:</label>
|
||||||
|
<input id="play_type_rnd_tts_msg" type="text" value="已经设置为随机播放" />
|
||||||
|
<label for="play_type_sin_tts_msg">单曲播放提示音:</label>
|
||||||
|
<input id="play_type_sin_tts_msg" type="text" value="已经设置为单曲播放" />
|
||||||
|
<label for="play_type_seq_tts_msg">顺序播放提示音:</label>
|
||||||
|
<input id="play_type_seq_tts_msg" type="text" value="已经设置为顺序播放" />
|
||||||
|
|
||||||
|
<label for="keywords_playlocal">播放本地歌曲口令:</label>
|
||||||
|
<input id="keywords_playlocal" type="text" value="播放本地歌曲,本地播放歌曲" />
|
||||||
|
<label for="keywords_play">播放歌曲口令:</label>
|
||||||
|
<input id="keywords_play" type="text" value="播放歌曲,放歌曲" />
|
||||||
|
<label for="keywords_playlist">播放列表口令:</label>
|
||||||
|
<input id="keywords_playlist" type="text" value="播放列表,播放歌单" />
|
||||||
|
<label for="keywords_stop">停止口令:</label>
|
||||||
|
<input id="keywords_stop" type="text" value="关机,暂停,停止,停止播放" />
|
||||||
|
|
||||||
|
<label for="enable_yt_dlp_cookies">启用yt-dlp-cookies(需要先上传yt-dlp-cookies.txt文件):</label>
|
||||||
|
<select id="enable_yt_dlp_cookies">
|
||||||
|
<option value="true">true</option>
|
||||||
|
<option value="false" selected>false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="enable_save_tag">启用ID3标签写入文件:</label>
|
||||||
|
<select id="enable_save_tag">
|
||||||
|
<option value="true">true</option>
|
||||||
|
<option value="false" selected>false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="get_ask_by_mina">特殊型号获取对话记录:</label>
|
||||||
|
<select id="get_ask_by_mina">
|
||||||
|
<option value="true">true</option>
|
||||||
|
<option value="false" selected>false</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="recently_added_playlist_len">最近新增的歌曲数量:</label>
|
||||||
|
<input id="recently_added_playlist_len" type="number" value="50" />
|
||||||
|
|
||||||
|
<label for="music_list_url">歌单地址:</label>
|
||||||
|
<input id="music_list_url" type="text" value="https://gist.githubusercontent.com/hanxi/dda82d964a28f8110f8fba81c3ff8314/raw/example.json" />
|
||||||
|
|
||||||
|
<label for="music_list_json">歌单内容:<a href="https://github.com/hanxi/xiaomusic/issues/78" target="_blank">格式文档</a></label>
|
||||||
|
<textarea id="music_list_json" type="text"></textarea>
|
||||||
|
|
||||||
|
<label for="crontab_json">定时任务:<a href="https://github.com/hanxi/xiaomusic/issues/182" target="_blank">格式文档</a></label>
|
||||||
|
<textarea id="crontab_json" type="text"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="rows">
|
||||||
|
<label for="yt_dlp_cookies_file">上传yt_dlp_cookies.txt文件:<a href="https://github.com/hanxi/xiaomusic/issues/210" target="_blank">文档</a></label>
|
||||||
|
<input id="yt_dlp_cookies_file" name="file" type="file">
|
||||||
|
<button id="upload_yt_dlp_cookie">上传</button>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<button onclick="location.href='/static/default/index.html';">返回首页</button>
|
||||||
|
<button id="get_music_list">获取歌单</button>
|
||||||
|
<button class="save-button">保存</button>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<button id="refresh_music_tag">刷新tag</button>
|
||||||
|
<button id="clear_cache">清空缓存</button>
|
||||||
|
<a class="button" href="/downloadlog" download="xiaomusic.txt">下载日志文件</a>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<button onclick="location.href='/docs';">查看接口文档</button>
|
||||||
|
<a class="button" href="./m3u.html" target="_blank">m3u文件转换</a>
|
||||||
|
<a class="button" href="./downloadtool.html" target="_blank">歌曲下载工具</a>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<a class="button" href="./debug.html" target="_blank">调试工具</a>
|
||||||
|
<a class="button" href="https://afdian.com/a/imhanxi" target="_blank">💰 爱发电</a>
|
||||||
|
<a class="button" href="https://github.com/hanxi/xiaomusic" target="_blank">点个 Star ⭐</a>
|
||||||
|
|
||||||
|
<div class="rows">
|
||||||
|
<img class="qrcode" src="./qrcode.png" alt="请涵曦喝奶茶🧋">
|
||||||
|
</div>
|
||||||
|
<footer>
|
||||||
|
<p>Powered by <a href="https://github.com/hanxi/xiaomusic" target="_blank">xiaomusic</a></p>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
194
xiaomusic/static/default_past/setting.js
Normal file
194
xiaomusic/static/default_past/setting.js
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
$(function(){
|
||||||
|
// 拉取版本
|
||||||
|
$.get("/getversion", function(data, status) {
|
||||||
|
console.log(data, status, data["version"]);
|
||||||
|
$("#version").text(`${data.version}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 遍历所有的select元素,默认选中只有1个选项的
|
||||||
|
const autoSelectOne = () => {
|
||||||
|
$('select').each(function() {
|
||||||
|
// 如果select元素仅有一个option子元素
|
||||||
|
if ($(this).children('option').length === 1) {
|
||||||
|
// 选中这个option
|
||||||
|
$(this).find('option').prop('selected', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function updateCheckbox(selector, mi_did, device_list,accountPassValid) {
|
||||||
|
// 清除现有的内容
|
||||||
|
$(selector).empty();
|
||||||
|
|
||||||
|
// 将 mi_did 字符串通过逗号分割转换为数组,以便于判断默认选中项
|
||||||
|
var selected_dids = mi_did.split(',');
|
||||||
|
|
||||||
|
//如果device_list为空,则可能是未设置小米账号密码或者已设置密码,但是没有过小米验证,此处需要提示用户
|
||||||
|
if (device_list.length == 0) {
|
||||||
|
const loginTips = accountPassValid ? `<div class="login-tips">未发现可用的小爱设备,请检查账号密码是否输错,并关闭加速代理或在<a href="https://www.mi.com">小米官网</a>登陆过人脸或滑块验证。如仍未解决。请根据<a href="https://github.com/hanxi/xiaomusic/issues/99">FAQ</a>的内容解决问题。</div>` : `<div class="login-tips">未发现可用的小爱设备,请先在下面的输入框中设置小米的<b>账号、密码</b></div>`;
|
||||||
|
$(selector).append(loginTips);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$.each(device_list, function(index, device) {
|
||||||
|
var did = device.miotDID;
|
||||||
|
var hardware = device.hardware;
|
||||||
|
var name = device.name;
|
||||||
|
// 创建复选框元素
|
||||||
|
var checkbox = $('<input>', {
|
||||||
|
type: 'checkbox',
|
||||||
|
id: did,
|
||||||
|
value: `${did}`,
|
||||||
|
class: 'custom-checkbox', // 添加样式类
|
||||||
|
// 如果mi_did中包含了该did,则默认选中
|
||||||
|
checked: selected_dids.indexOf(did) !== -1
|
||||||
|
});
|
||||||
|
|
||||||
|
// 创建标签元素
|
||||||
|
var label = $('<label>', {
|
||||||
|
for: did,
|
||||||
|
class: 'checkbox-label', // 添加样式类
|
||||||
|
text: `【${hardware} ${did}】${name}` // 设定标签内容
|
||||||
|
});
|
||||||
|
|
||||||
|
// 将复选框和标签添加到目标选择器元素中
|
||||||
|
$(selector).append(checkbox).append(label);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectedDids(containerSelector) {
|
||||||
|
var selectedDids = [];
|
||||||
|
|
||||||
|
// 仅选择给定容器中选中的复选框
|
||||||
|
$(containerSelector + ' .custom-checkbox:checked').each(function() {
|
||||||
|
var did = this.value;
|
||||||
|
selectedDids.push(did);
|
||||||
|
});
|
||||||
|
|
||||||
|
return selectedDids.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拉取现有配置
|
||||||
|
$.get("/getsetting?need_device_list=true", function(data, status) {
|
||||||
|
console.log(data, status);
|
||||||
|
const accountPassValid = data.account && data.password;
|
||||||
|
updateCheckbox("#mi_did", data.mi_did, data.device_list, accountPassValid);
|
||||||
|
|
||||||
|
// 初始化显示
|
||||||
|
for (const key in data) {
|
||||||
|
const $element = $("#" + key);
|
||||||
|
if ($element.length) {
|
||||||
|
if (data[key] === true) {
|
||||||
|
$element.val('true');
|
||||||
|
} else if (data[key] === false) {
|
||||||
|
$element.val('false');
|
||||||
|
} else {
|
||||||
|
$element.val(data[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
autoSelectOne();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".save-button").on("click", () => {
|
||||||
|
var setting = $('#setting');
|
||||||
|
var inputs = setting.find('input, select, textarea');
|
||||||
|
var data = {};
|
||||||
|
inputs.each(function() {
|
||||||
|
var id = this.id;
|
||||||
|
if (id) {
|
||||||
|
data[id] = $(this).val();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var did_list = getSelectedDids("#mi_did");
|
||||||
|
data["mi_did"] = did_list;
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/savesetting",
|
||||||
|
contentType: "application/json",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
success: (msg) => {
|
||||||
|
alert(msg);
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: (msg) => {
|
||||||
|
alert(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#get_music_list").on("click", () => {
|
||||||
|
var music_list_url = $("#music_list_url").val();
|
||||||
|
console.log("music_list_url", music_list_url);
|
||||||
|
var data = {
|
||||||
|
url: music_list_url,
|
||||||
|
};
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/downloadjson",
|
||||||
|
contentType: "application/json",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
success: (res) => {
|
||||||
|
if (res.ret == "OK") {
|
||||||
|
$("#music_list_json").val(res.content);
|
||||||
|
} else {
|
||||||
|
console.log(res);
|
||||||
|
alert(res.ret);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: (res) => {
|
||||||
|
console.log(res);
|
||||||
|
alert(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#refresh_music_tag").on("click", () => {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/refreshmusictag",
|
||||||
|
contentType: "application/json",
|
||||||
|
success: (res) => {
|
||||||
|
console.log(res);
|
||||||
|
alert(res.ret);
|
||||||
|
},
|
||||||
|
error: (res) => {
|
||||||
|
console.log(res);
|
||||||
|
alert(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#upload_yt_dlp_cookie").on("click", () => {
|
||||||
|
var fileInput = document.getElementById('yt_dlp_cookies_file');
|
||||||
|
var file = fileInput.files[0]; // 获取文件对象
|
||||||
|
if (file) {
|
||||||
|
var formData = new FormData();
|
||||||
|
formData.append("file", file);
|
||||||
|
$.ajax({
|
||||||
|
url: "/uploadytdlpcookie",
|
||||||
|
type: "POST",
|
||||||
|
data: formData,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: function(res) {
|
||||||
|
console.log(res);
|
||||||
|
alert("上传成功");
|
||||||
|
},
|
||||||
|
error: function(jqXHR, textStatus, errorThrown) {
|
||||||
|
console.log(res);
|
||||||
|
alert("上传失败");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
alert("请选择一个文件");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$("#clear_cache").on("click", () => {
|
||||||
|
localStorage.clear();
|
||||||
|
});
|
||||||
|
});
|
165
xiaomusic/static/default_past/style.css
Normal file
165
xiaomusic/static/default_past/style.css
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
.button {
|
||||||
|
line-height: 50px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
button, .button {
|
||||||
|
margin: 10px;
|
||||||
|
width: 100px;
|
||||||
|
height: 50px;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #008CBA;
|
||||||
|
}
|
||||||
|
button:active, .button:active {
|
||||||
|
font-weight:bold;
|
||||||
|
background-color: #007CBA;
|
||||||
|
transform: translateY(2px);
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
input,select {
|
||||||
|
margin-left: 5%;
|
||||||
|
margin-right: 5%;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 400px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rows {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea{
|
||||||
|
margin-left: 5%;
|
||||||
|
margin-right: 5%;
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 400px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-checkbox {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 10px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
vertical-align: middle; /* 确保与标签垂直居中对齐 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 260px;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 0px solid #ccc;
|
||||||
|
border-radius: 3px;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: middle; /* 确保与复选框垂直居中对齐 */
|
||||||
|
margin-left: 1px; /* 给复选框和标签之间一些距离,如果需要的话 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
margin: 10px;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 480px;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes blink {
|
||||||
|
0%, 100% { opacity: 1; }
|
||||||
|
50% { opacity: 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.blink {
|
||||||
|
animation: blink 1s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-tips {
|
||||||
|
color: red;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.login-tips a {
|
||||||
|
color: rgb(9, 105, 218);
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
#valid-host {
|
||||||
|
padding: 20px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#valid-host::backdrop {
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#valid-host form input {
|
||||||
|
width: fit-content;
|
||||||
|
margin: 0;
|
||||||
|
height: fit-content;
|
||||||
|
}
|
||||||
|
#valid-host p {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
#valid-host p span {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
#valid-host a, #valid-host a:visited {
|
||||||
|
color: rgb(9, 105, 218);;
|
||||||
|
text-decoration: underline;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
#valid-host a:hover {
|
||||||
|
color: rgb(9, 95, 198);
|
||||||
|
}
|
||||||
|
#valid-host .btn-list {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#valid-host .btn-list button {
|
||||||
|
width: fit-content;
|
||||||
|
min-width: 60px;
|
||||||
|
height: 40px;
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: #008CBA;
|
||||||
|
}
|
||||||
|
#valid-host .btn-list button:hover {
|
||||||
|
font-weight:bold;
|
||||||
|
background-color: #007CBA;
|
||||||
|
}
|
@ -2,36 +2,38 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<link rel="manifest" href="/static/manifest.json">
|
<link rel="manifest" href="/static/manifest.json" />
|
||||||
<link rel="icon" href="/static/favicon.ico">
|
<link rel="icon" href="/static/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>小爱音箱操控面板</title>
|
<title>小爱音箱操控面板</title>
|
||||||
|
|
||||||
<!-- Google tag (gtag.js) -->
|
<!-- Google tag (gtag.js) -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-Z09NC1K7ZW"></script>
|
||||||
<script>
|
<script>
|
||||||
window.dataLayer = window.dataLayer || [];
|
window.dataLayer = window.dataLayer || [];
|
||||||
function gtag(){dataLayer.push(arguments)};
|
function gtag() {
|
||||||
gtag('js', new Date());
|
dataLayer.push(arguments);
|
||||||
gtag('config', 'G-Z09NC1K7ZW');
|
}
|
||||||
|
gtag("js", new Date());
|
||||||
|
gtag("config", "G-Z09NC1K7ZW");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
if (navigator.serviceWorker != null) {
|
if (navigator.serviceWorker != null) {
|
||||||
navigator.serviceWorker.register('/static/sw.js')
|
navigator.serviceWorker
|
||||||
.then(function(registration) {
|
.register("/static/sw.js")
|
||||||
console.log('Registered events at scope: ', registration.scope);
|
.then(function (registration) {
|
||||||
});
|
console.log("Registered events at scope: ", registration.scope);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container_wrapper">
|
<div class="container_wrapper">
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
<img src="/static/xiaoai.png" alt="">
|
<img src="/static/xiaoai.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
<div class="desc">
|
<div class="desc">
|
||||||
<h1>谁家灯火夜通明</h1>
|
<h1>谁家灯火夜通明</h1>
|
||||||
@ -40,41 +42,224 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="options">
|
<div class="options">
|
||||||
<!-- 选择主题 /static/[theme] -->
|
<!-- 选择主题 /static/[theme] -->
|
||||||
<a href="/static/default/index.html" class="href">默认主题</a>
|
<div class="options_list">
|
||||||
<a href="/static/pure/index.html" class="href">Pure主题</a>
|
<a href="/static/default/index.html">默认主题</a>
|
||||||
<a href="/static/xplayer/index.html" class="href">XMusicPlayer</a>
|
</div>
|
||||||
<div class="weapp">
|
<div class="options_list">
|
||||||
<a href="https://github.com/F-loat/xiaoplayer" class="href" target="_blank">微信小程序</a>
|
<a href="/static/default_past/index.html">怀旧主题</a>
|
||||||
|
</div>
|
||||||
|
<div class="options_list">
|
||||||
|
<a href="/static/pure/index.html">Pure主题</a>
|
||||||
|
</div>
|
||||||
|
<div class="options_list">
|
||||||
|
<a href="/static/xplayer/index.html">XMusicPlayer</a>
|
||||||
|
</div>
|
||||||
|
<div class="options_list weapp">
|
||||||
|
<a href="https://github.com/F-loat/xiaoplayer" target="_blank">微信小程序</a>
|
||||||
<iframe width="240px" height="240px" src="/static/weapp/qrcode.html"></iframe>
|
<iframe width="240px" height="240px" src="/static/weapp/qrcode.html"></iframe>
|
||||||
</div>
|
</div>
|
||||||
<a href="https://afdian.com/a/imhanxi" target="_blank">爱发电</a>
|
<div class="options_list">
|
||||||
<a href="https://github.com/hanxi/xiaomusic" target="_blank">GitHub</a>
|
<a href="https://afdian.com/a/imhanxi" target="_blank">爱发电</a>
|
||||||
|
</div>
|
||||||
|
<div class="options_list">
|
||||||
|
<a href="https://github.com/hanxi/xiaomusic" target="_blank">GitHub</a>
|
||||||
|
</div>
|
||||||
|
<div class="options_list">
|
||||||
|
<a href="https://github.com/hanxi/xiaomusic/issues/211" target="_blank">帮助</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
power by <a href="https://github.com/hanxi/xiaomusic">XiaoMusic</a>
|
Powered by <a href="https://github.com/hanxi/xiaomusic">XiaoMusic</a>
|
||||||
</footer>
|
</footer>
|
||||||
<style>
|
<style>
|
||||||
@font-face{ font-family: "得意黑 斜体"; font-weight: 400; src: url("//at.alicdn.com/wf/webfont/603VmyqiyGMz/gJk2ny0v51vn.woff2") format("woff2"), url("//at.alicdn.com/wf/webfont/603VmyqiyGMz/e2C1wSBHH86h.woff") format("woff"); font-display: swap;} @font-face{ font-family: "阿里妈妈数黑体 Bold"; font-weight: 700; src: url("//at.alicdn.com/wf/webfont/603VmyqiyGMz/4DWYdFK3dz5J.woff2") format("woff2"), url("//at.alicdn.com/wf/webfont/603VmyqiyGMz/V7EBEKlNSdxC.woff") format("woff"); font-display: swap;} body{ background-color: rgb(47, 44, 67); height: 100%; overflow: hidden;}
|
@font-face {
|
||||||
.container_wrapper{display: flex; justify-content: space-around; align-items: center; flex-wrap: wrap; height: 90vh; cursor: default;}
|
font-family: "得意黑 斜体";
|
||||||
h1{ font-weight: bold; color: #a2a9af; max-width: 600px; font-family: '得意黑 斜体', 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; font-size: 2.5em; border-bottom: 1px solid #a2a9af;}
|
font-weight: 400;
|
||||||
.container_wrapper .logo img{ width: 140px; height: auto; filter: drop-shadow(10px 10px 10px rgba(0, 0, 0, 0.5));}
|
src: url("//at.alicdn.com/wf/webfont/603VmyqiyGMz/gJk2ny0v51vn.woff2") format("woff2"),
|
||||||
.desc{ text-align: center; color: #fff; margin: auto 30px; backdrop-filter: blur(5px);}
|
url("//at.alicdn.com/wf/webfont/603VmyqiyGMz/e2C1wSBHH86h.woff") format("woff");
|
||||||
.desc p{ font-size: 1.2em; margin: 0; padding: 0; font-family: '阿里妈妈数黑体 Bold'; font-weight: 800;}
|
font-display: swap;
|
||||||
p.call{ letter-spacing: 0.4em; font-size: 2.2em; line-height: 1.5; font-style: normal;}
|
}
|
||||||
p.answer{ letter-spacing: 0.23em; line-height: 1.5; font-style: normal; color: #a2a9af; margin-top: 10px;}
|
|
||||||
.desc p::before, .desc p::after{ font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; font-size: 1.5em; color: #4c5870;}
|
@font-face {
|
||||||
.desc p::before{ content: "“";} .desc p::after{ content: "”";}
|
font-family: "阿里妈妈数黑体 Bold";
|
||||||
.options{ display: flex; flex-direction: column;}
|
font-weight: 700;
|
||||||
.options a{ color: #a2a9af; text-decoration: none; font-size: 1.1em; position: relative; display: inline; margin: 10px auto;}
|
src: url("//at.alicdn.com/wf/webfont/603VmyqiyGMz/4DWYdFK3dz5J.woff2") format("woff2"),
|
||||||
.options a::before{ content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 2px; background-color: #ebedec; transform-origin: bottom right; transform: scaleX(0); transition: transform 0.3s ease;}
|
url("//at.alicdn.com/wf/webfont/603VmyqiyGMz/V7EBEKlNSdxC.woff") format("woff");
|
||||||
.options a:hover::before{ transform-origin: bottom left; transform: scaleX(1);} .options a:hover{ color:#ebedec;}
|
font-display: swap;
|
||||||
.weapp { position: relative; text-align: center; margin: 10px auto; }
|
}
|
||||||
.weapp:hover iframe { display: block; }
|
|
||||||
.weapp iframe { display: none; border: none; position: absolute; top: -80px; right: 100px; }
|
body {
|
||||||
@media screen and (max-width: 510px) { .weapp iframe { position: fixed; top: 40%; left: 50%; transform: translate(-50%, 0); } }
|
background-color: rgb(47, 44, 67);
|
||||||
footer{ display: flex; justify-content: center; color: #4c5870;} footer a{ color:inherit; text-decoration: none; margin: auto 10px;}
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container_wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
height: 90vh;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #a2a9af;
|
||||||
|
max-width: 600px;
|
||||||
|
font-family: "得意黑 斜体", "Lucida Sans", "Lucida Sans Regular",
|
||||||
|
"Lucida Grande", "Lucida Sans Unicode", Geneva, Verdana, sans-serif;
|
||||||
|
font-size: 2.5em;
|
||||||
|
border-bottom: 1px solid #a2a9af;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container_wrapper .logo img {
|
||||||
|
width: 140px;
|
||||||
|
height: auto;
|
||||||
|
filter: drop-shadow(10px 10px 10px rgba(0, 0, 0, 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
margin: auto 30px;
|
||||||
|
backdrop-filter: blur(5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc p {
|
||||||
|
font-size: 1.2em;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: "阿里妈妈数黑体 Bold";
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.call {
|
||||||
|
letter-spacing: 0.4em;
|
||||||
|
font-size: 2.2em;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.answer {
|
||||||
|
letter-spacing: 0.23em;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-style: normal;
|
||||||
|
color: #a2a9af;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc p::before,
|
||||||
|
.desc p::after {
|
||||||
|
font-family: "Lucida Sans", "Lucida Sans Regular", "Lucida Grande",
|
||||||
|
"Lucida Sans Unicode", Geneva, Verdana, sans-serif;
|
||||||
|
font-size: 1.5em;
|
||||||
|
color: #4c5870;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc p::before {
|
||||||
|
content: "“";
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc p::after {
|
||||||
|
content: "”";
|
||||||
|
}
|
||||||
|
|
||||||
|
.options {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options .options_list {
|
||||||
|
font-size: 1.1em;
|
||||||
|
position: relative;
|
||||||
|
margin: 5px 2px;
|
||||||
|
border: 1px solid #a2a9af;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
color: #a2a9af;
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
width: 120px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options a {
|
||||||
|
color: #a2a9af;
|
||||||
|
text-decoration: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options a::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 2px;
|
||||||
|
background-color: #ebedec;
|
||||||
|
transform-origin: bottom right;
|
||||||
|
transform: scaleX(0);
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.options a:hover::before {
|
||||||
|
transform-origin: bottom left;
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.options a:hover {
|
||||||
|
color: #ebedec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapp:hover iframe {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.weapp iframe {
|
||||||
|
display: none;
|
||||||
|
border: none;
|
||||||
|
position: absolute;
|
||||||
|
top: -80px;
|
||||||
|
right: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 510px) {
|
||||||
|
.weapp iframe {
|
||||||
|
position: fixed;
|
||||||
|
top: 40%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
}
|
||||||
|
.options{
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.options .options_list {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
color: #4c5870;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
margin: auto 10px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
Loading…
Reference in New Issue
Block a user