diff --git a/src/renderer/assets/styles/variables.less b/src/renderer/assets/styles/variables.less
index 2c526a9f..b33da89b 100644
--- a/src/renderer/assets/styles/variables.less
+++ b/src/renderer/assets/styles/variables.less
@@ -578,3 +578,5 @@
@radius-progress-border: 5px;
@transition-theme: .4s ease;
+
+@form-radius: 3px;
diff --git a/src/renderer/components/core/Player.vue b/src/renderer/components/core/Player.vue
index fcdfdf2e..6609056b 100644
--- a/src/renderer/components/core/Player.vue
+++ b/src/renderer/components/core/Player.vue
@@ -153,6 +153,9 @@ export default {
'setting.player.togglePlayMethod'(n) {
this.audio.loop = n === 'singleLoop'
},
+ 'setting.player.mediaDeviceName'(n) {
+ this.setMediaDevice()
+ },
list(n, o) {
if (n === o) {
let index = this.listId == 'download'
@@ -192,8 +195,10 @@ export default {
]),
...mapMutations(['setVolume']),
...mapMutations('list', ['updateMusicInfo']),
+ ...mapMutations(['setMediaDeviceId']),
init() {
this.audio = document.createElement('audio')
+ this.setMediaDevice()
this.volume = this.audio.volume = this.setting.player.volume
this.audio.controls = false
this.audio.autoplay = true
@@ -572,6 +577,18 @@ export default {
this.mediaBuffer.timeout = null
this.mediaBuffer.playTime = 0
},
+ async setMediaDevice() {
+ let mediaDeviceName = this.setting.player.mediaDeviceName
+ if (!mediaDeviceName) return
+ const devices = await navigator.mediaDevices.enumerateDevices()
+ let device = devices.find(device => device.label === mediaDeviceName)
+ if (!device) return this.setMediaDeviceId('default')
+ console.log(device)
+ this.audio.setSinkId(device.deviceId).catch((err) => {
+ console.log(err)
+ this.setMediaDeviceId('default')
+ })
+ },
handleSetTransition() {
this.isActiveTransition = true
// console.log('active transition')
diff --git a/src/renderer/components/material/Btn.vue b/src/renderer/components/material/Btn.vue
index 45811c1a..f464d7bd 100644
--- a/src/renderer/components/material/Btn.vue
+++ b/src/renderer/components/material/Btn.vue
@@ -24,7 +24,7 @@ export default {
.btn {
display: inline-block;
border: none;
- border-radius: 3px;
+ border-radius: @form-radius;
cursor: pointer;
padding: 8px 15px;
color: @color-btn;
diff --git a/src/renderer/components/material/FlowBtn.vue b/src/renderer/components/material/FlowBtn.vue
index 65d6b28c..56a270a3 100644
--- a/src/renderer/components/material/FlowBtn.vue
+++ b/src/renderer/components/material/FlowBtn.vue
@@ -78,7 +78,7 @@ export default {
button {
background-color: transparent;
border: none;
- border-radius: 3px;
+ border-radius: @form-radius;
margin-right: 5px;
cursor: pointer;
padding: 4px 7px;
diff --git a/src/renderer/components/material/Input.vue b/src/renderer/components/material/Input.vue
index 80102493..478e12e2 100644
--- a/src/renderer/components/material/Input.vue
+++ b/src/renderer/components/material/Input.vue
@@ -49,7 +49,7 @@ export default {
.input {
display: inline-block;
border: none;
- border-radius: 3px;
+ border-radius: @form-radius;
padding: 7px 8px;
color: @color-btn;
outline: none;
diff --git a/src/renderer/components/material/ListButtons.vue b/src/renderer/components/material/ListButtons.vue
index 62c68346..baf9e72f 100644
--- a/src/renderer/components/material/ListButtons.vue
+++ b/src/renderer/components/material/ListButtons.vue
@@ -91,7 +91,7 @@ export default {
button {
background-color: transparent;
border: none;
- border-radius: 3px;
+ border-radius: @form-radius;
margin-right: 5px;
cursor: pointer;
padding: 4px 7px;
diff --git a/src/renderer/components/material/SearchInput.vue b/src/renderer/components/material/SearchInput.vue
index cbfa3ccd..c9e19cd0 100644
--- a/src/renderer/components/material/SearchInput.vue
+++ b/src/renderer/components/material/SearchInput.vue
@@ -133,7 +133,7 @@ export default {
@import '../../assets/styles/layout.less';
.search {
- border-radius: 3px;
+ border-radius: @form-radius;
transition: box-shadow .4s ease, background-color @transition-theme;
display: flex;
flex-flow: column nowrap;
diff --git a/src/renderer/components/material/Selection.vue b/src/renderer/components/material/Selection.vue
new file mode 100644
index 00000000..49b1e282
--- /dev/null
+++ b/src/renderer/components/material/Selection.vue
@@ -0,0 +1,183 @@
+
+ div(:class="[$style.select, show ? $style.active : '']")
+ div(:class="$style.label" ref="dom_btn" @click="handleShow") {{label}}
+ ul(:class="$style.list")
+ li(v-for="item in list" :class="(itemKey ? item[itemKey] : item) == value ? $style.active : null" @click="handleClick(item)" :title="itemName ? item[itemName] : item") {{itemName ? item[itemName] : item}}
+
+
+
+
+
+
diff --git a/src/renderer/lang/cns/view/setting.json b/src/renderer/lang/cns/view/setting.json
index 4659b848..2f7246b7 100644
--- a/src/renderer/lang/cns/view/setting.json
+++ b/src/renderer/lang/cns/view/setting.json
@@ -26,6 +26,8 @@
"play_quality": "优先播放高品质音乐",
"play_task_bar_title": "在任务栏上显示当前歌曲播放进度",
"play_task_bar": "任务栏播放进度条",
+ "play_mediaDevice_title": "选择声音输出的媒体设备",
+ "play_mediaDevice": "音频输出",
"list": "列表设置",
"list_source_title": "是否显示歌曲源",
diff --git a/src/renderer/lang/cnt/view/setting.json b/src/renderer/lang/cnt/view/setting.json
index 7cb5dd32..cfcdb19c 100644
--- a/src/renderer/lang/cnt/view/setting.json
+++ b/src/renderer/lang/cnt/view/setting.json
@@ -25,6 +25,8 @@
"play_quality": "優先播放高品質音樂",
"play_task_bar_title": "在任務欄上顯示當前歌曲播放進度",
"play_task_bar": "任務欄播放進度條",
+ "play_mediaDevice_title": "選擇聲音輸出的媒體設備",
+ "play_mediaDevice": "音頻輸出",
"list": "列表設置",
"list_source_title": "是否顯示歌曲源",
"list_source": "是否顯示歌曲源(僅對我的音樂分類有效)",
diff --git a/src/renderer/lang/en/view/setting.json b/src/renderer/lang/en/view/setting.json
index c844dc10..c4cd7aab 100644
--- a/src/renderer/lang/en/view/setting.json
+++ b/src/renderer/lang/en/view/setting.json
@@ -26,6 +26,8 @@
"play_quality": "Prioritize high-quality music",
"play_task_bar_title": "Show current song playback progress on taskbar",
"play_task_bar": "Taskbar playback progress bar",
+ "play_mediaDevice_title": "Select the media device for sound output",
+ "play_mediaDevice": "Audio output",
"list": "List settings",
"list_source_title": "Whether to show song sources",
diff --git a/src/renderer/store/mutations.js b/src/renderer/store/mutations.js
index bc51f3c0..a737a238 100644
--- a/src/renderer/store/mutations.js
+++ b/src/renderer/store/mutations.js
@@ -42,4 +42,7 @@ export default {
setVolume(state, val) {
state.setting.player.volume = val
},
+ setMediaDeviceId(state, val) {
+ state.setting.player.mediaDeviceId = val
+ },
}
diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js
index 5f9706ef..d4ed8e09 100644
--- a/src/renderer/utils/index.js
+++ b/src/renderer/utils/index.js
@@ -177,7 +177,7 @@ export const isChildren = (parent, children) => {
* @param {*} setting
*/
export const updateSetting = (setting, version) => {
- const defaultVersion = '1.0.16'
+ const defaultVersion = '1.0.17'
if (!version) {
if (setting) {
version = setting.version
@@ -190,6 +190,7 @@ export const updateSetting = (setting, version) => {
highQuality: false,
isShowTaskProgess: true,
volume: 1,
+ mediaDeviceId: 'default',
},
list: {
isShowAlbumName: true,
diff --git a/src/renderer/utils/music/tx/tipSearch.js b/src/renderer/utils/music/tx/tipSearch.js
new file mode 100644
index 00000000..23f397e6
--- /dev/null
+++ b/src/renderer/utils/music/tx/tipSearch.js
@@ -0,0 +1,30 @@
+import { httpFetch } from '../../request'
+
+
+export default {
+ regExps: {
+ relWord: /RELWORD=(.+)/,
+ },
+ requestObj: null,
+ tempSearch(str) {
+ this.cancelTempSearch()
+ this.requestObj = httpFetch(`https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg?is_xml=0&format=json&key=${encodeURIComponent(str)}&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq&needNewCode=0`, {
+ headers: {
+ Referer: 'https://y.qq.com/portal/player.html',
+ },
+ })
+ return this.requestObj.promise.then(({ statusCode, body }) => {
+ if (statusCode != 200 || body.code != 0) return Promise.reject(new Error('请求失败'))
+ return body.data
+ })
+ },
+ handleResult(rawData) {
+ return rawData.map(info => `${info.name} - ${info.singer}`)
+ },
+ cancelTempSearch() {
+ if (this.requestObj && this.requestObj.cancelHttp) this.requestObj.cancelHttp()
+ },
+ async search(str) {
+ return this.tempSearch(str).then(result => this.handleResult(result.song.itemlist))
+ },
+}
diff --git a/src/renderer/views/Setting.vue b/src/renderer/views/Setting.vue
index 15e7a84d..c2c026b6 100644
--- a/src/renderer/views/Setting.vue
+++ b/src/renderer/views/Setting.vue
@@ -49,6 +49,11 @@ div.scroll(:class="$style.setting")
h3 {{$t('view.setting.play_task_bar')}}
div
material-checkbox(id="setting_player_showTaskProgess" v-model="current_setting.player.isShowTaskProgess" :label="$t('view.setting.is_enable')")
+ dd(:title="$t('view.setting.play_mediaDevice_title')")
+ h3 {{$t('view.setting.play_mediaDevice')}}
+ div
+ material-selection(:list="mediaDevices" @change="handleMediaDeviceChange" v-model="current_setting.player.mediaDeviceId" item-key="deviceId" item-name="label")
+
dt {{$t('view.setting.list')}}
dd(:title="$t('view.setting.list_source_title')")
h3 {{$t('view.setting.list_source')}}
@@ -283,6 +288,8 @@ export default {
togglePlayMethod: 'random',
highQuality: false,
isShowTaskProgess: true,
+ volume: 1,
+ mediaDeviceId: 'default',
},
list: {
isShowAlbumName: true,
@@ -320,6 +327,7 @@ export default {
},
languageList,
cacheSize: '0 B',
+ mediaDevices: [],
}
},
watch: {
@@ -346,10 +354,12 @@ export default {
methods: {
...mapMutations(['setSetting', 'setSettingVersion', 'setVersionModalVisible']),
...mapMutations('list', ['setList']),
+ ...mapMutations(['setMediaDeviceId']),
init() {
this.current_setting = JSON.parse(JSON.stringify(this.setting))
if (!window.currentWindowSizeId) window.currentWindowSizeId = this.setting.windowSizeId
this.getCacheSize()
+ this.getMediaDevice()
},
handleChangeSavePath() {
selectDir({
@@ -552,6 +562,15 @@ export default {
handleLangChange(id) {
this.$i18n.locale = id
},
+ async getMediaDevice() {
+ const devices = await navigator.mediaDevices.enumerateDevices()
+ const audioDevices = devices.filter(device => device.kind === 'audiooutput')
+ this.mediaDevices = audioDevices
+ console.log(this.mediaDevices)
+ },
+ handleMediaDeviceChange(audioDevice) {
+ this.setMediaDeviceId(audioDevice.deviceId)
+ },
},
}