Skip to content

Commit

Permalink
perf: ♻️ optimize Codec
Browse files Browse the repository at this point in the history
  • Loading branch information
viarotel committed Nov 2, 2023
1 parent 5331eb1 commit 6154ffc
Show file tree
Hide file tree
Showing 13 changed files with 369 additions and 69 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ module.exports = {
'import/default': 'off',

'vue/no-mutating-props': 'off',
'vue/no-use-v-if-with-v-for': 'off',
},
}
54 changes: 53 additions & 1 deletion electron/exposes/scrcpy/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { spawn } from 'node:child_process'
import util from 'node:util'
import { exec as _exec, spawn } from 'node:child_process'
import appStore from '@electron/helpers/store.js'
import { adbPath, scrcpyPath } from '@electron/configs/index.js'

const exec = util.promisify(_exec)

const shell = async (command, { stdout, stderr } = {}) => {
const spawnPath = appStore.get('common.scrcpyPath') || scrcpyPath
const ADB = appStore.get('common.adbPath') || adbPath
const args = command.split(' ')

console.log('scrcpy.shell.spawnPath', spawnPath)
console.log('scrcpy.shell.ADB', ADB)
console.log('scrcpy.shell.args', args)

const scrcpyProcess = spawn(`"${spawnPath}"`, args, {
env: { ...process.env, ADB },
Expand Down Expand Up @@ -52,6 +56,54 @@ const shell = async (command, { stdout, stderr } = {}) => {
})
}

const execShell = async (command) => {
const spawnPath = appStore.get('common.scrcpyPath') || scrcpyPath
const ADB = appStore.get('common.adbPath') || adbPath

console.log('scrcpy.execShell.spawnPath', spawnPath)
console.log('scrcpy.execShell.ADB', ADB)
console.log('scrcpy.shell.command', command)

const res = exec(`"${spawnPath}" ${command}`, {
env: { ...process.env, ADB },
shell: true,
encoding: 'utf8',
})

return res
}

const getEncoders = async (serial) => {
const res = await execShell(`--serial="${serial}" --list-encoders`)
// console.log('getEncoders.res', res)
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 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('getEncoders.value', value)

return value
}

export default () => ({
shell,
execShell,
getEncoders,
})
89 changes: 89 additions & 0 deletions src/components/Preference/AudioCodecSelect/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<template>
<el-select
v-bind="data.props || {}"
:model-value="modelValue"
class="!w-full"
:title="$t(data.placeholder)"
:placeholder="$t(data.placeholder)"
@change="onChange"
>
<el-option
v-for="(item, index) in options"
:key="index"
:label="$t(item.label)"
:value="item.value"
>
</el-option>
</el-select>
</template>

<script>
export default {
props: {
modelValue: {
type: String,
value: '',
},
data: {
type: Object,
default: () => ({}),
},
deviceScope: {
type: String,
value: '',
},
preferenceData: {
type: Object,
default: () => ({}),
},
},
emits: ['update:model-value'],
data() {
return {
deviceOptions: [],
}
},
computed: {
options() {
return this.deviceOptions.length ? this.deviceOptions : this.data.options
},
},
watch: {
deviceScope: {
handler(value) {
if (value === 'global') {
this.deviceOptions = []
return
}
this.getDeviceOptions()
},
},
},
methods: {
async getDeviceOptions() {
const res = await this.$scrcpy.getEncoders(this.deviceScope)
this.deviceOptions = res?.audio?.map((item) => {
const value = `${item.decoder} & ${item.encoder}`
return {
label: value,
value,
}
})
console.log('deviceOptions', this.deviceOptions)
},
onChange(value) {
// console.log('value', value)
this.$emit('update:model-value', value)
const [decoder, encoder] = value.split(' & ')
this.preferenceData['--audio-codec'] = decoder
this.preferenceData['--audio-encoder'] = encoder
},
},
}
</script>
<style></style>
89 changes: 89 additions & 0 deletions src/components/Preference/VideoCodecSelect/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<template>
<el-select
v-bind="data.props || {}"
:model-value="modelValue"
class="!w-full"
:title="$t(data.placeholder)"
:placeholder="$t(data.placeholder)"
@change="onChange"
>
<el-option
v-for="(item, index) in options"
:key="index"
:label="$t(item.label)"
:value="item.value"
>
</el-option>
</el-select>
</template>

<script>
export default {
props: {
modelValue: {
type: String,
value: '',
},
data: {
type: Object,
default: () => ({}),
},
deviceScope: {
type: String,
value: '',
},
preferenceData: {
type: Object,
default: () => ({}),
},
},
emits: ['update:model-value'],
data() {
return {
deviceOptions: [],
}
},
computed: {
options() {
return this.deviceOptions.length ? this.deviceOptions : this.data.options
},
},
watch: {
deviceScope: {
handler(value) {
if (value === 'global') {
this.deviceOptions = []
return
}
this.getDeviceOptions()
},
},
},
methods: {
async getDeviceOptions() {
const res = await this.$scrcpy.getEncoders(this.deviceScope)
this.deviceOptions = res?.video?.map((item) => {
const value = `${item.decoder} & ${item.encoder}`
return {
label: value,
value,
}
})
console.log('deviceOptions', this.deviceOptions)
},
onChange(value) {
// console.log('value', value)
this.$emit('update:model-value', value)
const [decoder, encoder] = value.split(' & ')
this.preferenceData['--video-codec'] = decoder
this.preferenceData['--video-encoder'] = encoder
},
},
}
</script>
<style></style>
2 changes: 1 addition & 1 deletion src/components/Preference/__composables__/OTG/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { watchEffect } from 'vue'

export function useOTG(data) {
export function useOtg(data) {
watchEffect(() => {
if (data.value['--hid-keyboard'] || data.value['--hid-mouse']) {
data.value['--otg'] = true
Expand Down
23 changes: 19 additions & 4 deletions src/components/Preference/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
>
<el-row :gutter="20">
<el-col
v-for="(item_1, index_1) of item?.children || {}"
v-for="(item_1, index_1) of subModel(item)"
:key="index_1"
:span="12"
:offset="0"
Expand Down Expand Up @@ -170,6 +170,8 @@
v-else
v-model="preferenceData[item_1.field]"
:data="item_1"
:device-scope="deviceScope"
:preference-data="preferenceData"
></component>
</el-form-item>
</el-col>
Expand All @@ -184,24 +186,28 @@
<script>
import { debounce } from 'lodash-es'
import { ref } from 'vue'
import { useOTG } from './__composables__/OTG/index.js'
import { useOtg } from './__composables__/otg/index.js'
import LanguageSelect from './LanguageSelect/index.vue'
import PathInput from './PathInput/index.vue'
import VideoCodecSelect from './VideoCodecSelect/index.vue'
import AudioCodecSelect from './AudioCodecSelect/index.vue'
import LoadingIcon from '@/components/Device/ControlBar/LoadingIcon/index.vue'
import { usePreferenceStore } from '@/store/index.js'
export default {
components: {
LanguageSelect,
PathInput,
VideoCodecSelect,
AudioCodecSelect,
},
setup() {
const preferenceStore = usePreferenceStore()
const preferenceData = ref(preferenceStore.data)
const deviceScope = ref(preferenceStore.deviceScope)
useOTG(preferenceData)
useOtg(preferenceData)
return {
preferenceData,
Expand All @@ -218,7 +224,6 @@ export default {
label: `${item.id}${item.$name}${
item.$remark ? `${item.$remark}` : ''
}`,
value: item.id,
}))
Expand Down Expand Up @@ -269,6 +274,16 @@ export default {
this.getDisplay()
},
methods: {
subModel(item) {
const children = item?.children || {}
const value = {}
Object.entries(children).forEach(([key, data]) => {
if (!data.hidden) {
value[key] = data
}
})
return value
},
handleResetAll() {
this.$store.preference.reset(this.deviceScope)
this.preferenceData = this.$store.preference.data
Expand Down
6 changes: 2 additions & 4 deletions src/locales/languages/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,8 @@
"preferences.video.bit.placeholder": "Default 4M, equal to 4000000",
"preferences.video.refresh-rate.name": "Frame Rate",
"preferences.video.refresh-rate.placeholder": "Default 60",
"preferences.video.decoder.name": "Video Decoder",
"preferences.video.decoder.placeholder": "Default h264",
"preferences.video.encoder.name": "Video Encoder",
"preferences.video.encoder.placeholder": "Default device encoder",
"preferences.video.codec.name": "Video Codec",
"preferences.video.codec.placeholder": "Default H.264",
"preferences.video.screen-rotation.name": "Rotation",
"preferences.video.screen-rotation.placeholder": "Default device rotation",
"preferences.video.screen-cropping.name": "Crop",
Expand Down
Loading

0 comments on commit 6154ffc

Please sign in to comment.