新增 设置-播放设置-使用设备能处理的最大声道数输出音频 设置(#1873)
parent
793b5a679c
commit
e4de4b8c1b
|
@ -1,5 +1,6 @@
|
||||||
### 新增
|
### 新增
|
||||||
|
|
||||||
|
- 新增 设置-播放设置-使用设备能处理的最大声道数输出音频 设置并默认启用(#1873)
|
||||||
- 允许添加 `m4a`、`oga` 格式的本地歌曲到列表中(#1864)
|
- 允许添加 `m4a`、`oga` 格式的本地歌曲到列表中(#1864)
|
||||||
- 开放API支持跨域请求(#1872 @Ceale)
|
- 开放API支持跨域请求(#1872 @Ceale)
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
### 变更
|
### 变更
|
||||||
|
|
||||||
- 设置-播放设置-优先播放320k音质选项改为“优先播放的音质”,允许选择更高优先播放的音质,如果歌曲及音源支持的话(#1839)
|
- 设置-播放设置-优先播放320k音质选项改为“优先播放的音质”,允许选择更高优先播放的音质,如果歌曲及音源支持的话(#1839)
|
||||||
|
- 设置-播放设置-使用设备能处理的最大声道数输出音频 设置默认启用,此前固定为2声道输出
|
||||||
|
|
||||||
### 开放API变更
|
### 开放API变更
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ const defaultSetting: LX.AppSetting = {
|
||||||
'player.isMute': false,
|
'player.isMute': false,
|
||||||
'player.playbackRate': 1,
|
'player.playbackRate': 1,
|
||||||
'player.preservesPitch': true,
|
'player.preservesPitch': true,
|
||||||
|
'player.isMaxOutputChannelCount': true,
|
||||||
'player.mediaDeviceId': 'default',
|
'player.mediaDeviceId': 'default',
|
||||||
'player.isMediaDeviceRemovedStopPlay': false,
|
'player.isMediaDeviceRemovedStopPlay': false,
|
||||||
'player.isShowLyricTranslation': false,
|
'player.isShowLyricTranslation': false,
|
||||||
|
|
|
@ -123,6 +123,11 @@ declare global {
|
||||||
*/
|
*/
|
||||||
'player.preservesPitch': boolean
|
'player.preservesPitch': boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用设备能处理的最大声道数输出音频
|
||||||
|
*/
|
||||||
|
'player.isMaxOutputChannelCount': boolean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 音频输出设备id
|
* 音频输出设备id
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -513,6 +513,7 @@
|
||||||
"setting__play_lyric_roma": "Show lyrics roman",
|
"setting__play_lyric_roma": "Show lyrics roman",
|
||||||
"setting__play_lyric_s2t": "Convert the playing and downloading lyrics to Traditional Chinese",
|
"setting__play_lyric_s2t": "Convert the playing and downloading lyrics to Traditional Chinese",
|
||||||
"setting__play_lyric_transition": "Show lyrics translation",
|
"setting__play_lyric_transition": "Show lyrics translation",
|
||||||
|
"setting__play_max_output_channel_count": "Output audio using the maximum number of channels the device can handle",
|
||||||
"setting__play_mediaDevice": "Audio output",
|
"setting__play_mediaDevice": "Audio output",
|
||||||
"setting__play_mediaDevice_remove_stop_play": "Pause the song when the current sound output device is changed",
|
"setting__play_mediaDevice_remove_stop_play": "Pause the song when the current sound output device is changed",
|
||||||
"setting__play_mediaDevice_title": "Select a media device for audio output",
|
"setting__play_mediaDevice_title": "Select a media device for audio output",
|
||||||
|
|
|
@ -513,6 +513,7 @@
|
||||||
"setting__play_lyric_roma": "显示歌词罗马音(如果可用)",
|
"setting__play_lyric_roma": "显示歌词罗马音(如果可用)",
|
||||||
"setting__play_lyric_s2t": "将播放与下载的歌词转换为繁体中文",
|
"setting__play_lyric_s2t": "将播放与下载的歌词转换为繁体中文",
|
||||||
"setting__play_lyric_transition": "显示歌词翻译(如果可用)",
|
"setting__play_lyric_transition": "显示歌词翻译(如果可用)",
|
||||||
|
"setting__play_max_output_channel_count": "使用设备能处理的最大声道数输出音频",
|
||||||
"setting__play_mediaDevice": "音频输出",
|
"setting__play_mediaDevice": "音频输出",
|
||||||
"setting__play_mediaDevice_remove_stop_play": "当前的声音输出设备被改变时暂停播放歌曲",
|
"setting__play_mediaDevice_remove_stop_play": "当前的声音输出设备被改变时暂停播放歌曲",
|
||||||
"setting__play_mediaDevice_title": "选择声音输出的媒体设备",
|
"setting__play_mediaDevice_title": "选择声音输出的媒体设备",
|
||||||
|
|
|
@ -513,6 +513,7 @@
|
||||||
"setting__play_lyric_roma": "顯示歌詞羅馬音(如果可用)",
|
"setting__play_lyric_roma": "顯示歌詞羅馬音(如果可用)",
|
||||||
"setting__play_lyric_s2t": "將播放與下載的歌詞轉換為繁體中文",
|
"setting__play_lyric_s2t": "將播放與下載的歌詞轉換為繁體中文",
|
||||||
"setting__play_lyric_transition": "顯示歌詞翻譯(如果可用)",
|
"setting__play_lyric_transition": "顯示歌詞翻譯(如果可用)",
|
||||||
|
"setting__play_max_output_channel_count": "使用設備能處理的最大聲道數輸出音頻",
|
||||||
"setting__play_mediaDevice": "音訊輸出",
|
"setting__play_mediaDevice": "音訊輸出",
|
||||||
"setting__play_mediaDevice_remove_stop_play": "當前的聲音輸出裝置被改變時暫停播放歌曲",
|
"setting__play_mediaDevice_remove_stop_play": "當前的聲音輸出裝置被改變時暫停播放歌曲",
|
||||||
"setting__play_mediaDevice_title": "選擇聲音輸出的媒體設備",
|
"setting__play_mediaDevice_title": "選擇聲音輸出的媒體設備",
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { watch } from '@common/utils/vueTools'
|
||||||
|
import { setMaxOutputChannelCount } from '@renderer/plugins/player'
|
||||||
|
|
||||||
|
import { appSetting } from '@renderer/store/setting'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
// console.log(appSetting['player.soundEffect.panner.enable'])
|
||||||
|
setMaxOutputChannelCount(appSetting['player.isMaxOutputChannelCount'])
|
||||||
|
|
||||||
|
watch(() => appSetting['player.isMaxOutputChannelCount'], (val) => {
|
||||||
|
setMaxOutputChannelCount(val)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -41,24 +41,24 @@ export default () => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleDeviceChangeStopPlay = (label: string) => {
|
const handleDeviceChange = (label: string) => {
|
||||||
// console.log(device)
|
// console.log(device)
|
||||||
// console.log(appSetting['player.isMediaDeviceRemovedStopPlay'], isPlay.value, label, prevDeviceLabel)
|
// console.log(appSetting['player.isMediaDeviceRemovedStopPlay'], isPlay.value, label, prevDeviceLabel)
|
||||||
if (
|
if (label != prevDeviceLabel) {
|
||||||
appSetting['player.isMediaDeviceRemovedStopPlay'] &&
|
window.app_event.playerDeviceChanged()
|
||||||
isPlay.value &&
|
|
||||||
label != prevDeviceLabel
|
if (appSetting['player.isMediaDeviceRemovedStopPlay'] && isPlay.value) {
|
||||||
) {
|
|
||||||
window.lx.isPlayedStop = true
|
window.lx.isPlayedStop = true
|
||||||
pause()
|
pause()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleMediaListChange = async() => {
|
const handleMediaListChange = async() => {
|
||||||
const mediaDeviceId = appSetting['player.mediaDeviceId']
|
const mediaDeviceId = appSetting['player.mediaDeviceId']
|
||||||
const device = await getMediaDevice(mediaDeviceId)
|
const device = await getMediaDevice(mediaDeviceId)
|
||||||
|
|
||||||
handleDeviceChangeStopPlay(device.label)
|
handleDeviceChange(device.label)
|
||||||
|
|
||||||
if (device.deviceId == mediaDeviceId) prevDeviceLabel = device.label
|
if (device.deviceId == mediaDeviceId) prevDeviceLabel = device.label
|
||||||
else void setMediaDevice(device.deviceId, device.label)
|
else void setMediaDevice(device.deviceId, device.label)
|
||||||
|
|
|
@ -32,6 +32,7 @@ import { HOTKEY_PLAYER } from '@common/hotKey'
|
||||||
import { playNext, pause, playPrev, togglePlay, collectMusic, uncollectMusic, dislikeMusic } from '@renderer/core/player'
|
import { playNext, pause, playPrev, togglePlay, collectMusic, uncollectMusic, dislikeMusic } from '@renderer/core/player'
|
||||||
import usePlaybackRate from './usePlaybackRate'
|
import usePlaybackRate from './usePlaybackRate'
|
||||||
import useSoundEffect from './useSoundEffect'
|
import useSoundEffect from './useSoundEffect'
|
||||||
|
import useMaxOutputChannelCount from './useMaxOutputChannelCount'
|
||||||
import { setPowerSaveBlocker } from '@renderer/core/player/utils'
|
import { setPowerSaveBlocker } from '@renderer/core/player/utils'
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +44,7 @@ export default () => {
|
||||||
usePlayEvent()
|
usePlayEvent()
|
||||||
useLyric()
|
useLyric()
|
||||||
useVolume()
|
useVolume()
|
||||||
|
useMaxOutputChannelCount()
|
||||||
useSoundEffect()
|
useSoundEffect()
|
||||||
usePlaybackRate()
|
usePlaybackRate()
|
||||||
useWatchList()
|
useWatchList()
|
||||||
|
|
|
@ -124,6 +124,10 @@ export class AppEvent extends Event {
|
||||||
this.emit('playerWaiting')
|
this.emit('playerWaiting')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playerDeviceChanged() {
|
||||||
|
this.emit('playerDeviceChanged')
|
||||||
|
}
|
||||||
|
|
||||||
// 激活进度条动画事件
|
// 激活进度条动画事件
|
||||||
activePlayProgressTransition() {
|
activePlayProgressTransition() {
|
||||||
this.emit('activePlayProgressTransition')
|
this.emit('activePlayProgressTransition')
|
||||||
|
|
|
@ -54,6 +54,7 @@ let pitchShifterNode: AudioWorkletNode
|
||||||
let pitchShifterNodePitchFactor: AudioParam
|
let pitchShifterNodePitchFactor: AudioParam
|
||||||
let pitchShifterNodeLoadStatus: 'none' | 'loading' | 'unconnect' | 'connected' = 'none'
|
let pitchShifterNodeLoadStatus: 'none' | 'loading' | 'unconnect' | 'connected' = 'none'
|
||||||
let pitchShifterNodeTempValue = 1
|
let pitchShifterNodeTempValue = 1
|
||||||
|
let defaultChannelCount = 2
|
||||||
export const soundR = 0.5
|
export const soundR = 0.5
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,6 +112,7 @@ const initAdvancedAudioFeatures = () => {
|
||||||
if (audioContext) return
|
if (audioContext) return
|
||||||
if (!audio) throw new Error('audio not defined')
|
if (!audio) throw new Error('audio not defined')
|
||||||
audioContext = new window.AudioContext()
|
audioContext = new window.AudioContext()
|
||||||
|
defaultChannelCount = audioContext.destination.channelCount
|
||||||
|
|
||||||
initAnalyser()
|
initAnalyser()
|
||||||
initBiquadFilter()
|
initBiquadFilter()
|
||||||
|
@ -134,6 +136,32 @@ export const getAudioContext = () => {
|
||||||
return audioContext
|
return audioContext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let unsubMediaListChangeEvent: (() => void) | null = null
|
||||||
|
export const setMaxOutputChannelCount = (enable: boolean) => {
|
||||||
|
if (enable) {
|
||||||
|
initAdvancedAudioFeatures()
|
||||||
|
audioContext.destination.channelCount = audioContext.destination.maxChannelCount
|
||||||
|
audioContext.destination.channelCountMode = 'max'
|
||||||
|
// navigator.mediaDevices.addEventListener('devicechange', handleMediaListChange)
|
||||||
|
if (!unsubMediaListChangeEvent) {
|
||||||
|
let handleMediaListChange = () => {
|
||||||
|
setMaxOutputChannelCount(true)
|
||||||
|
}
|
||||||
|
window.app_event.on('playerDeviceChanged', handleMediaListChange)
|
||||||
|
unsubMediaListChangeEvent = () => {
|
||||||
|
window.app_event.off('playerDeviceChanged', handleMediaListChange)
|
||||||
|
unsubMediaListChangeEvent = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsubMediaListChangeEvent?.()
|
||||||
|
if (audioContext && audioContext.destination.channelCountMode != 'explicit') {
|
||||||
|
audioContext.destination.channelCount = defaultChannelCount
|
||||||
|
// audioContext.destination.channelInterpretation
|
||||||
|
audioContext.destination.channelCountMode = 'explicit'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const getAnalyser = (): AnalyserNode | null => {
|
export const getAnalyser = (): AnalyserNode | null => {
|
||||||
initAdvancedAudioFeatures()
|
initAdvancedAudioFeatures()
|
||||||
|
|
|
@ -21,6 +21,8 @@ dd
|
||||||
base-checkbox(id="setting_player_lyric_play_lxlrc" :model-value="appSetting['player.isPlayLxlrc']" :label="$t('setting__play_lyric_lxlrc')" @update:model-value="updateSetting({'player.isPlayLxlrc': $event})")
|
base-checkbox(id="setting_player_lyric_play_lxlrc" :model-value="appSetting['player.isPlayLxlrc']" :label="$t('setting__play_lyric_lxlrc')" @update:model-value="updateSetting({'player.isPlayLxlrc': $event})")
|
||||||
.gap-top
|
.gap-top
|
||||||
base-checkbox(id="setting_player_showTaskProgess" :model-value="appSetting['player.isShowTaskProgess']" :label="$t('setting__play_task_bar')" @update:model-value="updateSetting({'player.isShowTaskProgess': $event})")
|
base-checkbox(id="setting_player_showTaskProgess" :model-value="appSetting['player.isShowTaskProgess']" :label="$t('setting__play_task_bar')" @update:model-value="updateSetting({'player.isShowTaskProgess': $event})")
|
||||||
|
.gap-top
|
||||||
|
base-checkbox(id="setting_player_isMaxOutputChannelCount" :model-value="appSetting['player.isMaxOutputChannelCount']" :label="$t('setting__play_max_output_channel_count')" @update:model-value="updateSetting({'player.isMaxOutputChannelCount': $event})")
|
||||||
.gap-top
|
.gap-top
|
||||||
base-checkbox(id="setting_player_isMediaDeviceRemovedStopPlay" :model-value="appSetting['player.isMediaDeviceRemovedStopPlay']" :label="$t('setting__play_mediaDevice_remove_stop_play')" @update:model-value="updateSetting({'player.isMediaDeviceRemovedStopPlay': $event})")
|
base-checkbox(id="setting_player_isMediaDeviceRemovedStopPlay" :model-value="appSetting['player.isMediaDeviceRemovedStopPlay']" :label="$t('setting__play_mediaDevice_remove_stop_play')" @update:model-value="updateSetting({'player.isMediaDeviceRemovedStopPlay': $event})")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue