mirror of
https://github.com/viarotel-org/escrcpy.git
synced 2024-11-15 03:07:41 +01:00
refactor: ♻️ Split Action Bar Function
This commit is contained in:
parent
6154ffcfae
commit
99ed1aeef7
@ -102,8 +102,27 @@ const getEncoders = async (serial) => {
|
||||
return value
|
||||
}
|
||||
|
||||
const mirror = async (serial, { title, args = '', ...options } = {}) => {
|
||||
return shell(
|
||||
`--serial="${serial}" --window-title="${title}" ${args}`,
|
||||
options,
|
||||
)
|
||||
}
|
||||
|
||||
const record = async (
|
||||
serial,
|
||||
{ title, args = '', savePath, ...options } = {},
|
||||
) => {
|
||||
return shell(
|
||||
`--serial="${serial}" --window-title="${title}" --record="${savePath}" ${args}`,
|
||||
options,
|
||||
)
|
||||
}
|
||||
|
||||
export default () => ({
|
||||
shell,
|
||||
execShell,
|
||||
getEncoders,
|
||||
mirror,
|
||||
record,
|
||||
})
|
||||
|
98
src/components/Device/ControlBar/AppInstall/index.vue
Normal file
98
src/components/Device/ControlBar/AppInstall/index.vue
Normal file
@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div class="" @click="handleInstall(device)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LoadingIcon from '@/components/Device/ControlBar/LoadingIcon/index.vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
device: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
preferenceData(...args) {
|
||||
return this.$store.preference.getData(...args)
|
||||
},
|
||||
async handleInstall(device) {
|
||||
let files = null
|
||||
|
||||
try {
|
||||
files = await this.$electron.ipcRenderer.invoke('show-open-dialog', {
|
||||
properties: ['openFile', 'multiSelections'],
|
||||
filters: [
|
||||
{
|
||||
name: this.$t('device.control.install.placeholder'),
|
||||
extensions: ['apk'],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
if (!files) {
|
||||
return false
|
||||
}
|
||||
|
||||
const messageEl = this.$message({
|
||||
message: this.$t('device.control.install.progress', {
|
||||
deviceName: device.$name,
|
||||
}),
|
||||
icon: LoadingIcon,
|
||||
duration: 0,
|
||||
})
|
||||
|
||||
let failCount = 0
|
||||
|
||||
for (let index = 0; index < files.length; index++) {
|
||||
const item = files[index]
|
||||
await this.$adb.install(device.id, item).catch((e) => {
|
||||
console.warn(e)
|
||||
++failCount
|
||||
})
|
||||
}
|
||||
|
||||
messageEl.close()
|
||||
|
||||
const totalCount = files.length
|
||||
const successCount = totalCount - failCount
|
||||
|
||||
if (successCount) {
|
||||
if (totalCount > 1) {
|
||||
this.$message.success(
|
||||
this.$t('device.control.install.success', {
|
||||
deviceName: device.$name,
|
||||
totalCount,
|
||||
successCount,
|
||||
failCount,
|
||||
}),
|
||||
)
|
||||
}
|
||||
else {
|
||||
this.$message.success(
|
||||
this.$t('device.control.install.success.single', {
|
||||
deviceName: device.$name,
|
||||
}),
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
this.$message.warning(this.$t('device.control.install.error'))
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
49
src/components/Device/ControlBar/Gnirehtet/index.vue
Normal file
49
src/components/Device/ControlBar/Gnirehtet/index.vue
Normal file
@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="" @click="handleGnirehtet(device)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LoadingIcon from '@/components/Device/ControlBar/LoadingIcon/index.vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
device: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
preferenceData(...args) {
|
||||
return this.$store.preference.getData(...args)
|
||||
},
|
||||
async handleGnirehtet(device) {
|
||||
const messageEl = this.$message({
|
||||
message: this.$t('device.control.gnirehtet.progress', {
|
||||
deviceName: device.$name,
|
||||
}),
|
||||
icon: LoadingIcon,
|
||||
duration: 0,
|
||||
})
|
||||
|
||||
try {
|
||||
await this.$gnirehtet.run(device.id)
|
||||
this.$message.success(this.$t('device.control.gnirehtet.success'))
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
messageEl.close()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
83
src/components/Device/ControlBar/Screenshot/index.vue
Normal file
83
src/components/Device/ControlBar/Screenshot/index.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<div class="" @click="handleScreenCap(device)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import LoadingIcon from '@/components/Device/ControlBar/LoadingIcon/index.vue'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
device: {
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
preferenceData(...args) {
|
||||
return this.$store.preference.getData(...args)
|
||||
},
|
||||
async handleScreenCap(device) {
|
||||
const messageEl = this.$message({
|
||||
message: this.$t('device.control.capture.progress', {
|
||||
deviceName: device.$name,
|
||||
}),
|
||||
icon: LoadingIcon,
|
||||
duration: 0,
|
||||
})
|
||||
|
||||
const fileName = `${device.$remark ? `${device.$remark}-` : ''}${
|
||||
device.$name
|
||||
}-${this.$replaceIP(device.id)}-screencap-${dayjs().format(
|
||||
'YYYY-MM-DD-HH-mm-ss',
|
||||
)}.png`
|
||||
|
||||
const deviceConfig = this.preferenceData(device.id)
|
||||
const savePath = this.$path.resolve(deviceConfig.savePath, fileName)
|
||||
|
||||
try {
|
||||
await this.$adb.screencap(device.id, { savePath })
|
||||
this.handleScreencapSuccess(savePath)
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
messageEl.close()
|
||||
},
|
||||
async handleScreencapSuccess(savePath) {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t('device.control.capture.success.message'),
|
||||
this.$t('device.control.capture.success.message.title'),
|
||||
{
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
closeOnClickModal: false,
|
||||
type: 'success',
|
||||
},
|
||||
)
|
||||
|
||||
await this.$electron.ipcRenderer.invoke(
|
||||
'show-item-in-folder',
|
||||
savePath,
|
||||
)
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -4,33 +4,51 @@
|
||||
class="bg-primary-100 dark:bg-gray-800 -my-[8px] flex flex-nowrap overflow-hidden"
|
||||
title="滚动查看被遮盖的菜单"
|
||||
>
|
||||
<el-button
|
||||
<component
|
||||
:is="item.component || 'div'"
|
||||
v-for="(item, index) in controlModel"
|
||||
:key="index"
|
||||
type="primary"
|
||||
plain
|
||||
class="!border-none !mx-0 bg-transparent !rounded-0 flex-none"
|
||||
:disabled="device.$unauthorized"
|
||||
:title="item.tips ? $t(item.tips) : ''"
|
||||
@wheel.prevent="onWheel"
|
||||
@click="handleClick(item)"
|
||||
class="flex-none"
|
||||
v-bind="{
|
||||
device,
|
||||
...(item.command
|
||||
? {
|
||||
onClick: () => handleShell(item),
|
||||
}
|
||||
: {}),
|
||||
}"
|
||||
>
|
||||
<template #icon>
|
||||
<svg-icon v-if="item.svgIcon" :name="item.svgIcon"></svg-icon>
|
||||
<el-icon v-else-if="item.elIcon" class="">
|
||||
<component :is="item.elIcon" />
|
||||
</el-icon>
|
||||
</template>
|
||||
{{ $t(item.label) }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
class="!border-none !mx-0 bg-transparent !rounded-0"
|
||||
:disabled="device.$unauthorized"
|
||||
:title="item.tips ? $t(item.tips) : ''"
|
||||
@wheel.prevent="onWheel"
|
||||
>
|
||||
<template #icon>
|
||||
<svg-icon v-if="item.svgIcon" :name="item.svgIcon"></svg-icon>
|
||||
<el-icon v-else-if="item.elIcon" class="">
|
||||
<component :is="item.elIcon" />
|
||||
</el-icon>
|
||||
</template>
|
||||
{{ $t(item.label) }}
|
||||
</el-button>
|
||||
</component>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import dayjs from 'dayjs'
|
||||
import LoadingIcon from './LoadingIcon/index.vue'
|
||||
import Screenshot from './Screenshot/index.vue'
|
||||
import AppInstall from './AppInstall/index.vue'
|
||||
import Gnirehtet from './Gnirehtet/index.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Screenshot,
|
||||
AppInstall,
|
||||
Gnirehtet,
|
||||
},
|
||||
props: {
|
||||
device: {
|
||||
type: Object,
|
||||
@ -75,19 +93,19 @@ export default {
|
||||
{
|
||||
label: 'device.control.capture',
|
||||
elIcon: 'Crop',
|
||||
handle: this.handleScreenCap,
|
||||
component: 'Screenshot',
|
||||
tips: '',
|
||||
},
|
||||
{
|
||||
label: 'device.control.install',
|
||||
svgIcon: 'install',
|
||||
handle: this.handleInstall,
|
||||
component: 'AppInstall',
|
||||
tips: '',
|
||||
},
|
||||
{
|
||||
label: 'device.control.gnirehtet',
|
||||
elIcon: 'Link',
|
||||
handle: this.handleGnirehtet,
|
||||
component: 'Gnirehtet',
|
||||
tips: 'device.control.gnirehtet.tips',
|
||||
},
|
||||
],
|
||||
@ -99,164 +117,8 @@ export default {
|
||||
const container = this.$refs.wheelContainer
|
||||
container.scrollLeft += event.deltaY
|
||||
},
|
||||
preferenceData(...args) {
|
||||
return this.$store.preference.getData(...args)
|
||||
},
|
||||
async handleGnirehtet(device) {
|
||||
const messageEl = this.$message({
|
||||
message: this.$t('device.control.gnirehtet.progress', {
|
||||
deviceName: device.$name,
|
||||
}),
|
||||
icon: LoadingIcon,
|
||||
duration: 0,
|
||||
})
|
||||
|
||||
try {
|
||||
await this.$gnirehtet.run(device.id)
|
||||
this.$message.success(this.$t('device.control.gnirehtet.success'))
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
messageEl.close()
|
||||
},
|
||||
async handleInstall(device) {
|
||||
let files = null
|
||||
|
||||
try {
|
||||
files = await this.$electron.ipcRenderer.invoke('show-open-dialog', {
|
||||
properties: ['openFile', 'multiSelections'],
|
||||
filters: [
|
||||
{
|
||||
name: this.$t('device.control.install.placeholder'),
|
||||
extensions: ['apk'],
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
if (!files) {
|
||||
return false
|
||||
}
|
||||
|
||||
const messageEl = this.$message({
|
||||
message: this.$t('device.control.install.progress', {
|
||||
deviceName: device.$name,
|
||||
}),
|
||||
icon: LoadingIcon,
|
||||
duration: 0,
|
||||
})
|
||||
|
||||
let failCount = 0
|
||||
|
||||
for (let index = 0; index < files.length; index++) {
|
||||
const item = files[index]
|
||||
await this.$adb.install(device.id, item).catch((e) => {
|
||||
console.warn(e)
|
||||
++failCount
|
||||
})
|
||||
}
|
||||
|
||||
messageEl.close()
|
||||
|
||||
const totalCount = files.length
|
||||
const successCount = totalCount - failCount
|
||||
|
||||
if (successCount) {
|
||||
if (totalCount > 1) {
|
||||
this.$message.success(
|
||||
this.$t('device.control.install.success', {
|
||||
deviceName: device.$name,
|
||||
totalCount,
|
||||
successCount,
|
||||
failCount,
|
||||
}),
|
||||
)
|
||||
}
|
||||
else {
|
||||
this.$message.success(
|
||||
this.$t('device.control.install.success.single', {
|
||||
deviceName: device.$name,
|
||||
}),
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
this.$message.warning(this.$t('device.control.install.error'))
|
||||
},
|
||||
handleClick(row) {
|
||||
if (row.command) {
|
||||
this.$adb.deviceShell(this.device.id, row.command)
|
||||
}
|
||||
else if (row.handle) {
|
||||
row.handle(this.device)
|
||||
}
|
||||
else {
|
||||
return false
|
||||
}
|
||||
},
|
||||
async handleScreenCap(device) {
|
||||
const messageEl = this.$message({
|
||||
message: this.$t('device.control.capture.progress', {
|
||||
deviceName: device.$name,
|
||||
}),
|
||||
icon: LoadingIcon,
|
||||
duration: 0,
|
||||
})
|
||||
|
||||
const fileName = `${device.$remark ? `${device.$remark}-` : ''}${
|
||||
device.$name
|
||||
}-${this.$replaceIP(device.id)}-screencap-${dayjs().format(
|
||||
'YYYY-MM-DD-HH-mm-ss',
|
||||
)}.png`
|
||||
|
||||
const deviceConfig = this.preferenceData(device.id)
|
||||
const savePath = this.$path.resolve(deviceConfig.savePath, fileName)
|
||||
|
||||
try {
|
||||
await this.$adb.screencap(device.id, { savePath })
|
||||
this.handleScreencapSuccess(savePath)
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
|
||||
messageEl.close()
|
||||
},
|
||||
async handleScreencapSuccess(savePath) {
|
||||
try {
|
||||
await this.$confirm(
|
||||
this.$t('device.control.capture.success.message'),
|
||||
this.$t('device.control.capture.success.message.title'),
|
||||
{
|
||||
confirmButtonText: this.$t('common.confirm'),
|
||||
cancelButtonText: this.$t('common.cancel'),
|
||||
closeOnClickModal: false,
|
||||
type: 'success',
|
||||
},
|
||||
)
|
||||
|
||||
await this.$electron.ipcRenderer.invoke(
|
||||
'show-item-in-folder',
|
||||
savePath,
|
||||
)
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
this.$message.warning(error.message)
|
||||
}
|
||||
}
|
||||
handleShell(row) {
|
||||
this.$adb.deviceShell(this.device.id, row.command)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -297,16 +297,16 @@ export default {
|
||||
this.toggleRowExpansion(row, true)
|
||||
|
||||
const savePath = this.getRecordPath(row)
|
||||
|
||||
try {
|
||||
const command = `--serial="${row.id}" --window-title="${
|
||||
row.$remark ? `${row.$remark}-` : ''
|
||||
}${row.$name}-${row.id}-🎥${this.$t(
|
||||
'device.record.progress',
|
||||
)}..." --record="${savePath}" ${this.scrcpyArgs(row.id)}`
|
||||
|
||||
console.log('handleRecord.command', command)
|
||||
|
||||
await this.$scrcpy.shell(command, { stdout: this.onStdout })
|
||||
await this.$scrcpy.record(row.id, {
|
||||
title: `${row.$remark ? `${row.$remark}-` : ''}${row.$name}-${
|
||||
row.id
|
||||
}-🎥${this.$t('device.record.progress')}...`,
|
||||
savePath,
|
||||
args: this.scrcpyArgs(row.id),
|
||||
stdout: this.onStdout,
|
||||
})
|
||||
|
||||
await this.$confirm(
|
||||
this.$t('device.record.success.message'),
|
||||
@ -337,12 +337,13 @@ export default {
|
||||
this.toggleRowExpansion(row, true)
|
||||
|
||||
try {
|
||||
await this.$scrcpy.shell(
|
||||
`--serial="${row.id}" --window-title="${
|
||||
row.$remark ? `${row.$remark}-` : ''
|
||||
}${row.$name}-${row.id}" ${this.scrcpyArgs(row.id)}`,
|
||||
{ stdout: this.onStdout },
|
||||
)
|
||||
await this.$scrcpy.mirror(row.id, {
|
||||
title: `${row.$remark ? `${row.$remark}-` : ''}${row.$name}-${
|
||||
row.id
|
||||
}`,
|
||||
args: this.scrcpyArgs(row.id),
|
||||
stdout: this.onStdout,
|
||||
})
|
||||
}
|
||||
catch (error) {
|
||||
if (error.message) {
|
||||
|
@ -138,8 +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.codec.name": "Video Codec",
|
||||
"preferences.video.codec.placeholder": "Default H.264",
|
||||
"preferences.video.video-code.name": "Video Codec",
|
||||
"preferences.video.video-code.placeholder": "Default H.264",
|
||||
"preferences.video.screen-rotation.name": "Rotation",
|
||||
"preferences.video.screen-rotation.placeholder": "Default device rotation",
|
||||
"preferences.video.screen-cropping.name": "Crop",
|
||||
@ -179,12 +179,21 @@
|
||||
"preferences.record.format.name": "Format",
|
||||
"preferences.record.format.placeholder": "Default *.mp4",
|
||||
"preferences.audio.name": "Audio",
|
||||
"preferences.audio.disable.name": "Disable Audio",
|
||||
"preferences.audio.disable.placeholder": "Disable audio stream",
|
||||
"preferences.audio.audio-source.name": "Audio Source",
|
||||
"preferences.audio.audio-source.placeholder": "Default Device Audio Output",
|
||||
"preferences.audio.audio-source.tips": "Tip: Selecting 'Microphone' as the source will allow you to record audio.",
|
||||
"preferences.audio.audio-source.mic": "Microphone",
|
||||
"preferences.audio.audio-code.name": "Audio Codec",
|
||||
"preferences.audio.audio-code.placeholder": "Default Opus",
|
||||
"preferences.audio.audio-bit-rate.name": "Audio Bit Rate",
|
||||
"preferences.audio.audio-bit-rate.placeholder": "Default 128000bps",
|
||||
"preferences.audio.audio-bit-rate.tips": "Note: This option does not apply to RAW audio codecs.",
|
||||
"preferences.audio.audio-buffer.name": "Audio Buffer",
|
||||
"preferences.audio.audio-buffer.placeholder": "Default 0ms",
|
||||
"preferences.audio.audio-output-buffer.name": "Audio Output Buffer",
|
||||
"preferences.audio.audio-output-buffer.placeholder": "Default 5ms",
|
||||
"preferences.audio.disable.name": "Disable Audio",
|
||||
"preferences.audio.disable.placeholder": "Disable audio stream",
|
||||
"preferences.otg.name": "OTG",
|
||||
"preferences.otg.enable.name": "Enable OTG",
|
||||
"preferences.otg.enable.placeholder": "Enable or disable OTG",
|
||||
|
@ -139,8 +139,8 @@
|
||||
"preferences.video.bit.placeholder": "默认值为 4M,等同于 4000000",
|
||||
"preferences.video.refresh-rate.name": "刷新率",
|
||||
"preferences.video.refresh-rate.placeholder": "默认值为 60",
|
||||
"preferences.video.codec.name": "视频编码",
|
||||
"preferences.video.codec.placeholder": "默认为 H.264",
|
||||
"preferences.video.video-code.name": "视频编码",
|
||||
"preferences.video.video-code.placeholder": "默认为 H.264",
|
||||
"preferences.video.screen-rotation.name": "屏幕旋转",
|
||||
"preferences.video.screen-rotation.placeholder": "默认值为设备屏幕旋转角度",
|
||||
"preferences.video.screen-cropping.name": "屏幕裁剪",
|
||||
@ -186,8 +186,8 @@
|
||||
"preferences.audio.audio-source.placeholder": "默认为设备音频输出",
|
||||
"preferences.audio.audio-source.tips": "技巧:如果将来源设为麦克风将可以在录制时将声音录制下来",
|
||||
"preferences.audio.audio-source.mic": "麦克风",
|
||||
"preferences.audio.audio-codec.name": "音频编解码器",
|
||||
"preferences.audio.audio-codec.placeholder": "默认为 Opus",
|
||||
"preferences.audio.audio-code.name": "音频编码",
|
||||
"preferences.audio.audio-code.placeholder": "默认为 Opus",
|
||||
"preferences.audio.audio-bit-rate.name": "音频比特率",
|
||||
"preferences.audio.audio-bit-rate.placeholder": "默认为 128000bps",
|
||||
"preferences.audio.audio-bit-rate.tips": "注意:此选项不适用于 RAW 音频编解码器",
|
||||
|
@ -16,11 +16,11 @@ export default {
|
||||
],
|
||||
},
|
||||
audioCode: {
|
||||
label: 'preferences.audio.audio-codec.name',
|
||||
label: 'preferences.audio.audio-code.name',
|
||||
field: '--audio-code',
|
||||
type: 'AudioCodecSelect',
|
||||
value: '',
|
||||
placeholder: 'preferences.audio.audio-codec.placeholder',
|
||||
placeholder: 'preferences.audio.audio-code.placeholder',
|
||||
options: [
|
||||
{
|
||||
label: 'opus & c2.android.opus.encoder',
|
||||
|
@ -26,11 +26,11 @@ export default {
|
||||
append: 'fps',
|
||||
},
|
||||
videoCode: {
|
||||
label: 'preferences.video.codec.name',
|
||||
label: 'preferences.video.video-code.name',
|
||||
field: '--video-code',
|
||||
type: 'VideoCodecSelect',
|
||||
value: '',
|
||||
placeholder: 'preferences.video.codec.placeholder',
|
||||
placeholder: 'preferences.video.video-code.placeholder',
|
||||
options: [
|
||||
{
|
||||
label: 'h265 & OMX.qcom.video.encoder.avc',
|
||||
|
Loading…
Reference in New Issue
Block a user