update now can connect adb but scrcpy still bug
This commit is contained in:
parent
45851422f7
commit
a95c350844
10 changed files with 116 additions and 132 deletions
|
|
@ -28,5 +28,6 @@ module.exports = {
|
||||||
{ allowConstantExport: true },
|
{ allowConstantExport: true },
|
||||||
],
|
],
|
||||||
"@typescript-eslint/consistent-type-imports": "error",
|
"@typescript-eslint/consistent-type-imports": "error",
|
||||||
|
"react-hooks/exhaustive-deps": "off",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,6 @@
|
||||||
"bracketSpacing": true,
|
"bracketSpacing": true,
|
||||||
"arrowParens": "avoid",
|
"arrowParens": "avoid",
|
||||||
"endOfLine": "lf",
|
"endOfLine": "lf",
|
||||||
"tabWidth": 2
|
"tabWidth": 2,
|
||||||
|
"proseWrap": "preserve"
|
||||||
}
|
}
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
// import type { AdbDaemonWebUsbDevice } from '@yume-chan/adb-daemon-webusb'
|
|
||||||
// import { AdbDaemonWebUsbDeviceManager } from '@yume-chan/adb-daemon-webusb'
|
|
||||||
import { webusb } from 'usb'
|
|
||||||
|
|
||||||
// const WebUsb: WebUSB = new WebUSB({ allowAllDevices: true })
|
|
||||||
// const Manager: AdbDaemonWebUsbDeviceManager = new AdbDaemonWebUsbDeviceManager(
|
|
||||||
// WebUsb
|
|
||||||
// )
|
|
||||||
|
|
||||||
export function getDevices() {
|
|
||||||
// const devices: AdbDaemonWebUsbDevice[] = await Manager.getDevices()
|
|
||||||
// if (!devices.length) {
|
|
||||||
// alert('No device connected')
|
|
||||||
// }
|
|
||||||
|
|
||||||
webusb.requestDevice({ filters: [] }).then(device => {
|
|
||||||
console.log(device)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
||||||
const Header: React.FC = () => {
|
const Header: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
<header className="fixed bg-black w-full z-0 px-4 shadow-sm shadow-slate-500/40 pl-[20rem]">
|
<header className="fixed bg-black w-full z-40 px-4 shadow-sm shadow-slate-500/40 pl-[20rem]">
|
||||||
<h2>Header</h2>
|
<h2>Header</h2>
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { type Adb } from '@yume-chan/adb'
|
||||||
import {
|
import {
|
||||||
type AdbDaemonWebUsbDevice,
|
type AdbDaemonWebUsbDevice,
|
||||||
AdbDaemonWebUsbDeviceManager
|
AdbDaemonWebUsbDeviceManager
|
||||||
|
|
@ -5,14 +6,18 @@ import {
|
||||||
import { create } from 'zustand'
|
import { create } from 'zustand'
|
||||||
|
|
||||||
interface ADB {
|
interface ADB {
|
||||||
|
adb: Adb | undefined
|
||||||
manager: AdbDaemonWebUsbDeviceManager | undefined
|
manager: AdbDaemonWebUsbDeviceManager | undefined
|
||||||
device: AdbDaemonWebUsbDevice | undefined
|
device: AdbDaemonWebUsbDevice | undefined
|
||||||
|
setAdb: (adb: Adb | undefined) => void
|
||||||
setDevice: (device: AdbDaemonWebUsbDevice | undefined) => void
|
setDevice: (device: AdbDaemonWebUsbDevice | undefined) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const useAdb = create<ADB>(set => ({
|
const useAdb = create<ADB>(set => ({
|
||||||
|
adb: undefined,
|
||||||
manager: AdbDaemonWebUsbDeviceManager.BROWSER,
|
manager: AdbDaemonWebUsbDeviceManager.BROWSER,
|
||||||
device: undefined,
|
device: undefined,
|
||||||
|
setAdb: adb => set({ adb }),
|
||||||
setDevice: device => set({ device })
|
setDevice: device => set({ device })
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ const MainLayout = () => {
|
||||||
<div>
|
<div>
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
<Header />
|
<Header />
|
||||||
<main className="fixed pt-14 px-4 pl-[21rem]">
|
<main className="fixed pt-[5rem] pl-[21rem]">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,176 +2,172 @@ import { useShallow } from 'zustand/react/shallow'
|
||||||
import { ADB_DEFAULT_DEVICE_FILTER } from '@yume-chan/adb-daemon-webusb'
|
import { ADB_DEFAULT_DEVICE_FILTER } from '@yume-chan/adb-daemon-webusb'
|
||||||
import AdbWebCredentialStore from '@yume-chan/adb-credential-web'
|
import AdbWebCredentialStore from '@yume-chan/adb-credential-web'
|
||||||
import { Adb, AdbDaemonTransport } from '@yume-chan/adb'
|
import { Adb, AdbDaemonTransport } from '@yume-chan/adb'
|
||||||
import useAdb from '../hooks/adb'
|
import useAdb from '../hooks/useAdb'
|
||||||
import type { AdbScrcpyVideoStream } from '@yume-chan/adb-scrcpy'
|
import type { AdbScrcpyVideoStream } from '@yume-chan/adb-scrcpy'
|
||||||
import { AdbScrcpyClient, AdbScrcpyOptions2_1 } from '@yume-chan/adb-scrcpy'
|
import { AdbScrcpyClient, AdbScrcpyOptions2_1 } from '@yume-chan/adb-scrcpy'
|
||||||
import { WebCodecsDecoder } from '@yume-chan/scrcpy-decoder-webcodecs'
|
import { WebCodecsDecoder } from '@yume-chan/scrcpy-decoder-webcodecs'
|
||||||
import {
|
import {
|
||||||
ScrcpyLogLevel1_18,
|
ScrcpyLogLevel1_18,
|
||||||
ScrcpyOptions2_1,
|
ScrcpyOptions2_2,
|
||||||
ScrcpyVideoCodecId
|
ScrcpyVideoCodecId
|
||||||
} from '@yume-chan/scrcpy'
|
} from '@yume-chan/scrcpy'
|
||||||
import { useState } from 'react'
|
import { useCallback, useRef, useState } from 'react'
|
||||||
|
import {
|
||||||
const ScreenStream: React.FC<{ child: HTMLCanvasElement }> = ({
|
ReadableStream,
|
||||||
child
|
WritableStream,
|
||||||
}: {
|
Consumable,
|
||||||
child: HTMLCanvasElement
|
DecodeUtf8Stream
|
||||||
}) => {
|
} from '@yume-chan/stream-extra'
|
||||||
return <div ref={ref => ref?.appendChild(child)}></div>
|
import { useBeforeUnload } from 'react-router-dom'
|
||||||
}
|
|
||||||
|
|
||||||
const AndroidPage: React.FC = () => {
|
const AndroidPage: React.FC = () => {
|
||||||
const { manager, device, setDevice } = useAdb(
|
const { adb, manager, device, setAdb, setDevice } = useAdb(
|
||||||
useShallow(state => ({
|
useShallow(state => ({
|
||||||
|
adb: state.adb,
|
||||||
manager: state.manager,
|
manager: state.manager,
|
||||||
device: state.device,
|
device: state.device,
|
||||||
|
setAdb: state.setAdb,
|
||||||
setDevice: state.setDevice
|
setDevice: state.setDevice
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
|
|
||||||
const [decoder, setDecoder] = useState<WebCodecsDecoder | undefined>()
|
async function createNewConnection() {
|
||||||
const [client, setClient] = useState<AdbScrcpyClient | undefined>()
|
|
||||||
const [adbClient, setAdbClient] = useState<Adb | undefined>(undefined)
|
|
||||||
|
|
||||||
function attachDevice() {
|
|
||||||
manager
|
|
||||||
?.requestDevice({
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
...ADB_DEFAULT_DEVICE_FILTER,
|
|
||||||
vendorId: 1478
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.then(selectedDevice => {
|
|
||||||
if (!selectedDevice) {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
setDevice(selectedDevice)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function disConnectDevice() {
|
|
||||||
device?.raw.forget()
|
device?.raw.forget()
|
||||||
setDevice(undefined)
|
setDevice(undefined)
|
||||||
}
|
const selectedDevice = await manager?.requestDevice({
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
...ADB_DEFAULT_DEVICE_FILTER,
|
||||||
|
serialNumber: 'd'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
// function reboot() {
|
if (!selectedDevice) {
|
||||||
// device?.connect().then(connection => {
|
return
|
||||||
// const credentialStore: AdbWebCredentialStore = new AdbWebCredentialStore()
|
} else {
|
||||||
|
setDevice(selectedDevice)
|
||||||
|
}
|
||||||
|
|
||||||
// AdbDaemonTransport.authenticate({
|
const connection = await selectedDevice.connect()
|
||||||
// serial: device?.serial,
|
|
||||||
// connection,
|
|
||||||
// credentialStore: credentialStore
|
|
||||||
// }).then(transport => {
|
|
||||||
// const adb: Adb = new Adb(transport)
|
|
||||||
|
|
||||||
// adb.power.reboot().then(() => {
|
|
||||||
// console.log('reboot success')
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
// }
|
|
||||||
|
|
||||||
async function scrcpyConnect() {
|
|
||||||
// const url = new URL('../bin/scrcpy-server.bin', import.meta.url)
|
|
||||||
// const server: ArrayBuffer = await fetch(url).then(res => res.arrayBuffer())
|
|
||||||
|
|
||||||
const connection = await device?.connect()
|
|
||||||
|
|
||||||
const credentialStore: AdbWebCredentialStore = new AdbWebCredentialStore()
|
const credentialStore: AdbWebCredentialStore = new AdbWebCredentialStore()
|
||||||
|
|
||||||
const transport = await AdbDaemonTransport.authenticate({
|
const transport = await AdbDaemonTransport.authenticate({
|
||||||
serial: device!.serial,
|
serial: selectedDevice.serial,
|
||||||
connection: connection!,
|
connection: connection,
|
||||||
credentialStore: credentialStore
|
credentialStore: credentialStore
|
||||||
})
|
})
|
||||||
|
|
||||||
const adb: Adb = new Adb(transport)
|
const adb: Adb = new Adb(transport)
|
||||||
setAdbClient(adb)
|
setAdb(adb)
|
||||||
// await AdbScrcpyClient.pushServer(
|
}
|
||||||
// adb,
|
|
||||||
// new ReadableStream({
|
|
||||||
// start(controller) {
|
|
||||||
// controller.enqueue(new Consumable(new Uint8Array(server)))
|
|
||||||
// controller.close()
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// )
|
|
||||||
|
|
||||||
await adb.subprocess.spawn(
|
const [client, setClient] = useState<AdbScrcpyClient | undefined>()
|
||||||
'CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 2.1'
|
const [decoder, setDecoder] = useState<WebCodecsDecoder | undefined>()
|
||||||
|
const screenRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
|
// when user close or refresh the page, close the adb connection
|
||||||
|
useBeforeUnload(
|
||||||
|
useCallback(() => {
|
||||||
|
client?.close()
|
||||||
|
adb?.close()
|
||||||
|
device?.raw.forget()
|
||||||
|
}, [])
|
||||||
|
)
|
||||||
|
|
||||||
|
async function scrcpyConnect() {
|
||||||
|
const server: ArrayBuffer = await fetch(
|
||||||
|
new URL('../scrcpy/scrcpy_server_v2.2', import.meta.url)
|
||||||
|
).then(res => res.arrayBuffer())
|
||||||
|
|
||||||
|
await AdbScrcpyClient.pushServer(
|
||||||
|
adb!,
|
||||||
|
new ReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
controller.enqueue(new Consumable(new Uint8Array(server)))
|
||||||
|
controller.close()
|
||||||
|
}
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
const scrcpyOption = new ScrcpyOptions2_1({
|
const res = await adb!.subprocess.spawn(
|
||||||
|
'CLASSPATH=/data/local/tmp/scrcpy-server.jar app_process / com.genymobile.scrcpy.Server 2.2'
|
||||||
|
)
|
||||||
|
|
||||||
|
res.stdout.pipeThrough(new DecodeUtf8Stream()).pipeTo(
|
||||||
|
new WritableStream({
|
||||||
|
write(chunk) {
|
||||||
|
console.log(chunk)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const scrcpyOption = new ScrcpyOptions2_2({
|
||||||
audio: false,
|
audio: false,
|
||||||
maxFps: 60,
|
maxFps: 60,
|
||||||
control: false,
|
control: false,
|
||||||
video: true,
|
video: true,
|
||||||
logLevel: ScrcpyLogLevel1_18.Debug,
|
logLevel: ScrcpyLogLevel1_18.Debug,
|
||||||
videoCodec: 'h264',
|
|
||||||
stayAwake: true,
|
stayAwake: true,
|
||||||
cleanup: true
|
cleanup: true
|
||||||
})
|
})
|
||||||
const _client = await AdbScrcpyClient.start(
|
const _client = await AdbScrcpyClient.start(
|
||||||
adb,
|
adb!,
|
||||||
'/data/local/tmp/scrcpy-server.jar',
|
'/data/local/tmp/scrcpy-server.jar',
|
||||||
'2.1',
|
'2.2',
|
||||||
new AdbScrcpyOptions2_1(scrcpyOption)
|
new AdbScrcpyOptions2_1(scrcpyOption)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const videoStream: AdbScrcpyVideoStream | undefined =
|
||||||
|
await _client?.videoStream
|
||||||
|
const _decoder = new WebCodecsDecoder(ScrcpyVideoCodecId.H264)
|
||||||
|
screenRef.current?.appendChild(_decoder.renderer)
|
||||||
|
videoStream?.stream.pipeTo(_decoder.writable)
|
||||||
|
setDecoder(_decoder)
|
||||||
setClient(_client)
|
setClient(_client)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function scrcpyStream() {
|
function disconnectAdb() {
|
||||||
const videoStream: AdbScrcpyVideoStream | undefined =
|
client?.close()
|
||||||
await client?.videoStream
|
adb?.close()
|
||||||
const _decoder = new WebCodecsDecoder(ScrcpyVideoCodecId.H264)
|
setClient(undefined)
|
||||||
videoStream?.stream.pipeTo(_decoder.writable)
|
setAdb(undefined)
|
||||||
setDecoder(_decoder)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrcpyDisconnect() {
|
function scrcpyDisconnect() {
|
||||||
|
decoder?.dispose()
|
||||||
client?.close()
|
client?.close()
|
||||||
setClient(undefined)
|
setClient(undefined)
|
||||||
setDecoder(undefined)
|
setDecoder(undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
function rebootDevice() {
|
function rebootDevice() {
|
||||||
adbClient?.power.reboot()
|
adb?.power.reboot()
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<h1>This is Android Page!!!!!!!</h1>
|
<div className="grid grid-cols-2 gap-4">
|
||||||
{device ? <h2>Device: {device.name}</h2> : <h2>No Device</h2>}
|
<div className="flex flex-col">
|
||||||
<div className="flex flex-row">
|
<button
|
||||||
<button className="btn btn-primary" onClick={attachDevice}>
|
className="btn btn-primary"
|
||||||
Attach Device
|
onClick={adb ? disconnectAdb : createNewConnection}
|
||||||
</button>
|
>
|
||||||
<button className="btn btn-primary" onClick={disConnectDevice}>
|
{adb ? 'Disconnect' : 'Connect'}
|
||||||
Disconnect Device
|
</button>
|
||||||
</button>
|
<button
|
||||||
<button className="btn btn-primary" onClick={rebootDevice}>
|
className="btn btn-primary"
|
||||||
Reboot Device
|
onClick={adb && !client ? scrcpyConnect : scrcpyDisconnect}
|
||||||
</button>
|
>
|
||||||
|
{client ? 'Disconnect' : 'Connect'}
|
||||||
|
</button>
|
||||||
|
{adb ? <button onClick={rebootDevice}>Reboot</button> : ''}
|
||||||
|
</div>
|
||||||
|
<div className="bg-white">{adb && device ? device.name : ''}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row">
|
<div ref={screenRef}></div>
|
||||||
<button className="btn btn-primary" onClick={scrcpyConnect}>
|
</>
|
||||||
Scrcpy Connect
|
|
||||||
</button>
|
|
||||||
<button className="btn btn-primary" onClick={scrcpyStream}>
|
|
||||||
Scrcpy Stream
|
|
||||||
</button>
|
|
||||||
<button className="btn btn-primary" onClick={scrcpyDisconnect}>
|
|
||||||
Scrcpy Disconnect
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
{decoder ? <ScreenStream child={decoder.renderer} /> : ''}
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
BIN
client-electron/src/scrcpy/scrcpy_server_v2.2
Normal file
BIN
client-electron/src/scrcpy/scrcpy_server_v2.2
Normal file
Binary file not shown.
BIN
client-electron/src/scrcpy/scrcpy_server_v2.3.1
Normal file
BIN
client-electron/src/scrcpy/scrcpy_server_v2.3.1
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue