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) + }, }, }