From b9398e882a29bab541b481bf5344854bb1ed010c Mon Sep 17 00:00:00 2001 From: lyswhut Date: Fri, 28 Feb 2020 13:19:49 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/components/core/Player.vue | 17 ++ .../components/material/Selection.vue | 161 ++++++++++++++++++ src/renderer/lang/cns/view/setting.json | 2 + src/renderer/lang/cnt/view/setting.json | 2 + src/renderer/lang/en/view/setting.json | 2 + src/renderer/store/mutations.js | 3 + src/renderer/utils/index.js | 3 +- src/renderer/utils/music/tx/tipSearch.js | 30 ++++ src/renderer/views/Setting.vue | 19 +++ 9 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/renderer/components/material/Selection.vue create mode 100644 src/renderer/utils/music/tx/tipSearch.js diff --git a/src/renderer/components/core/Player.vue b/src/renderer/components/core/Player.vue index f519f424..16cbfe96 100644 --- a/src/renderer/components/core/Player.vue +++ b/src/renderer/components/core/Player.vue @@ -150,6 +150,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' @@ -186,8 +189,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 @@ -566,6 +571,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(null) + console.log(device) + this.audio.setSinkId(device.deviceId).catch((err) => { + console.log(err) + this.setMediaDeviceId(null) + }) + }, }, } diff --git a/src/renderer/components/material/Selection.vue b/src/renderer/components/material/Selection.vue new file mode 100644 index 00000000..aefec186 --- /dev/null +++ b/src/renderer/components/material/Selection.vue @@ -0,0 +1,161 @@ + + + + + + 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..5491147b 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: null, }, 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..968321ed 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.mediaDeviceName" item-key="label" 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, + mediaDeviceName: null, }, 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) + }, }, } From 2a66edd1c520bf0ef5192c6a9fa70921699ee3ed Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 7 Mar 2020 11:55:31 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/components/core/Player.vue | 4 ++-- src/renderer/components/material/Selection.vue | 4 ++-- src/renderer/utils/index.js | 2 +- src/renderer/views/Setting.vue | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/renderer/components/core/Player.vue b/src/renderer/components/core/Player.vue index e3967892..6609056b 100644 --- a/src/renderer/components/core/Player.vue +++ b/src/renderer/components/core/Player.vue @@ -582,11 +582,11 @@ export default { if (!mediaDeviceName) return const devices = await navigator.mediaDevices.enumerateDevices() let device = devices.find(device => device.label === mediaDeviceName) - if (!device) return this.setMediaDeviceId(null) + if (!device) return this.setMediaDeviceId('default') console.log(device) this.audio.setSinkId(device.deviceId).catch((err) => { console.log(err) - this.setMediaDeviceId(null) + this.setMediaDeviceId('default') }) }, handleSetTransition() { diff --git a/src/renderer/components/material/Selection.vue b/src/renderer/components/material/Selection.vue index aefec186..8cf08817 100644 --- a/src/renderer/components/material/Selection.vue +++ b/src/renderer/components/material/Selection.vue @@ -40,8 +40,8 @@ export default { label() { if (!this.value) return '' if (!this.itemName) return this.value - const item = this.list.find(l => l.id == this.value) - if (!item) return this.value + const item = this.list.find(l => l[this.itemKey] == this.value) + if (!item) return '' return item[this.itemName] }, }, diff --git a/src/renderer/utils/index.js b/src/renderer/utils/index.js index 5491147b..d4ed8e09 100644 --- a/src/renderer/utils/index.js +++ b/src/renderer/utils/index.js @@ -190,7 +190,7 @@ export const updateSetting = (setting, version) => { highQuality: false, isShowTaskProgess: true, volume: 1, - mediaDeviceId: null, + mediaDeviceId: 'default', }, list: { isShowAlbumName: true, diff --git a/src/renderer/views/Setting.vue b/src/renderer/views/Setting.vue index 968321ed..c2c026b6 100644 --- a/src/renderer/views/Setting.vue +++ b/src/renderer/views/Setting.vue @@ -52,7 +52,7 @@ div.scroll(:class="$style.setting") 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.mediaDeviceName" item-key="label" item-name="label") + 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')") @@ -289,7 +289,7 @@ export default { highQuality: false, isShowTaskProgess: true, volume: 1, - mediaDeviceName: null, + mediaDeviceId: 'default', }, list: { isShowAlbumName: true, From aa5765971e1506bb6373b3b72461c0e2109b8dac Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 7 Mar 2020 13:21:13 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=AE=8C=E5=96=84=E9=80=89=E6=8B=A9?= =?UTF-8?q?=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/assets/styles/variables.less | 2 ++ src/renderer/components/material/Btn.vue | 2 +- src/renderer/components/material/FlowBtn.vue | 2 +- src/renderer/components/material/Input.vue | 2 +- .../components/material/ListButtons.vue | 2 +- .../components/material/SearchInput.vue | 2 +- .../components/material/Selection.vue | 36 +++++++++++++++---- 7 files changed, 36 insertions(+), 12 deletions(-) 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/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 index 8cf08817..49b1e282 100644 --- a/src/renderer/components/material/Selection.vue +++ b/src/renderer/components/material/Selection.vue @@ -2,7 +2,7 @@ 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" @click="handleClick(item)" :title="itemName ? item[itemName] : item") {{itemName ? item[itemName] : item}} + 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}}