From 9b7f6a98c28b44fcb9cc8cc8d9011ebe335ba73a Mon Sep 17 00:00:00 2001 From: viarotel Date: Thu, 7 Nov 2024 15:14:52 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Fix=20device=20support=20?= =?UTF-8?q?audio=20and=20video=20encoding=20cannot=20be=20parsed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/exposes/scrcpy/helper.js | 70 +++++++++++++++++++ electron/exposes/scrcpy/index.js | 22 ++---- .../components/SelectAudioCodec/index.vue | 6 +- .../components/SelectVideoCodec/index.vue | 6 +- 4 files changed, 80 insertions(+), 24 deletions(-) diff --git a/electron/exposes/scrcpy/helper.js b/electron/exposes/scrcpy/helper.js index 650b49ae..c47bdad0 100644 --- a/electron/exposes/scrcpy/helper.js +++ b/electron/exposes/scrcpy/helper.js @@ -56,3 +56,73 @@ export function getDisplayOverlay(serial) { || '' return value } + +/** + * Parse scrcpy codec output into structured data + * @param {*} rawText + * @returns + */ +export function parseScrcpyCodecList(rawText) { + try { + const result = { + video: [], + audio: [], + } + + // 分行处理 + const lines = rawText.split('\n') + + // 遍历每一行 + for (const line of lines) { + const trimmedLine = line.trim() + + // 跳过空行和不包含编码器信息的行 + if (!trimmedLine || !trimmedLine.startsWith('--')) { + continue + } + + // 提取所有的键值对 + const pairs = trimmedLine.match(/--[\w-]+=[\w.-]+/g) + if (!pairs || pairs.length < 2) + continue + + // 将键值对转换为对象 + const info = pairs.reduce((acc, pair) => { + const [key, value] = pair.substring(2).split('=') + acc[key] = value + return acc + }, {}) + + // 根据键名判断类型并保存数据 + if (info['video-codec'] && info['video-encoder']) { + result.video.push({ + type: 'video', + codec: info['video-codec'], + encoder: info['video-encoder'], + }) + } + else if (info['audio-codec'] && info['audio-encoder']) { + result.audio.push({ + type: 'audio', + codec: info['audio-codec'], + encoder: info['audio-encoder'], + }) + } + } + + // 验证结果是否为空 + if (result.video.length === 0 && result.audio.length === 0) { + throw new Error('No valid codec information found in the log content') + } + + return result + } + catch (error) { + console.error('Error parsing codec information:', error) + return { + video: [], + audio: [], + error: error.message, + } + } +} diff --git a/electron/exposes/scrcpy/index.js b/electron/exposes/scrcpy/index.js index f8865b71..506c987f 100644 --- a/electron/exposes/scrcpy/index.js +++ b/electron/exposes/scrcpy/index.js @@ -5,7 +5,7 @@ import appStore from '$electron/helpers/store.js' import { sleep } from '$renderer/utils/index.js' import commandHelper from '$renderer/utils/command/index.js' -import { getDisplayOverlay, parseScrcpyAppList } from './helper.js' +import { getDisplayOverlay, parseScrcpyAppList, parseScrcpyCodecList } from './helper.js' let adbkit @@ -84,26 +84,12 @@ async function execShell(command) { async function getEncoders(serial) { const res = await execShell(`--serial="${serial}" --list-encoders`) + const stdout = res.stdout - // 提取视频编码器列表 - const videoEncoderRegex - = /--video-codec=([\w-]+)\s+--video-encoder='([^']+)'/g - const videoEncoders = [...stdout.matchAll(videoEncoderRegex)].map( - ([, codec, encoder]) => ({ decoder: codec, encoder }), - ) + const value = parseScrcpyCodecList(stdout) - // 提取音频编码器列表 - const audioEncoderRegex - = /--audio-codec=([\w-]+)\s+--audio-encoder='([^']+)'/g - const audioEncoders = [...stdout.matchAll(audioEncoderRegex)].map( - ([, codec, encoder]) => ({ decoder: codec, encoder }), - ) - - const value = { - audio: audioEncoders, - video: videoEncoders, - } + console.log('value', value) return value } diff --git a/src/components/Preference/components/PreferenceForm/components/SelectAudioCodec/index.vue b/src/components/Preference/components/PreferenceForm/components/SelectAudioCodec/index.vue index 481c5708..639f966d 100644 --- a/src/components/Preference/components/PreferenceForm/components/SelectAudioCodec/index.vue +++ b/src/components/Preference/components/PreferenceForm/components/SelectAudioCodec/index.vue @@ -53,8 +53,8 @@ export default { }, set(value) { this.$emit('update:model-value', value) - const [decoder, encoder] = value.split(' & ') - this.preferenceData['--audio-codec'] = decoder + const [codec, encoder] = value.split(' & ') + this.preferenceData['--audio-codec'] = codec this.preferenceData['--audio-encoder'] = encoder }, }, @@ -71,7 +71,7 @@ export default { const res = await this.$scrcpy.getEncoders(deviceId) this.deviceOptions = res?.audio?.map((item) => { - const value = `${item.decoder} & ${item.encoder}` + const value = `${item.codec} & ${item.encoder}` return { label: value, value, diff --git a/src/components/Preference/components/PreferenceForm/components/SelectVideoCodec/index.vue b/src/components/Preference/components/PreferenceForm/components/SelectVideoCodec/index.vue index 75a24dd0..129e40c8 100644 --- a/src/components/Preference/components/PreferenceForm/components/SelectVideoCodec/index.vue +++ b/src/components/Preference/components/PreferenceForm/components/SelectVideoCodec/index.vue @@ -53,8 +53,8 @@ export default { }, set(value) { this.$emit('update:model-value', value) - const [decoder, encoder] = value.split(' & ') - this.preferenceData['--video-codec'] = decoder + const [codec, encoder] = value.split(' & ') + this.preferenceData['--video-codec'] = codec this.preferenceData['--video-encoder'] = encoder }, }, @@ -71,7 +71,7 @@ export default { const res = await this.$scrcpy.getEncoders(deviceId) this.deviceOptions = res?.video?.map((item) => { - const value = `${item.decoder} & ${item.encoder}` + const value = `${item.codec} & ${item.encoder}` return { label: value, value,