Skip to content

Commit e08ac85

Browse files
authored
Rewrite Android video shell service (#46)
1 parent c984d61 commit e08ac85

File tree

1 file changed

+19
-50
lines changed

1 file changed

+19
-50
lines changed

src/services/android-video-shell.service.ts

Lines changed: 19 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import { isMac } from '../helpers/utils'
2-
import { spawn, ChildProcess, execSync } from 'child_process'
1+
import { exec, ChildProcess, execSync } from 'child_process'
32
import * as os from 'os'
43
import * as fs from 'fs'
54

65
import { randomString } from '../helpers/random'
76
import { Device } from './device.service'
8-
import { getFfmpegBin } from './ffmpeg.service'
97

108
export default class AndroidVideoShell {
119
process: ChildProcess | null = null
@@ -18,6 +16,8 @@ export default class AndroidVideoShell {
1816

1917
device: Device
2018

19+
pid?: string
20+
2121
constructor(options: { device: Device; verbose?: boolean }) {
2222
this.fileName = `${randomString()}-raw.mp4`
2323
this.path = `${os.tmpdir()}/${this.fileName}`
@@ -26,59 +26,26 @@ export default class AndroidVideoShell {
2626
}
2727

2828
record() {
29-
this.process = spawn('adb', [
30-
'-s',
31-
this.device.id,
32-
'shell',
33-
'screenrecord',
34-
`/sdcard/${this.fileName}`,
35-
'--output-format',
36-
'h264',
37-
])
38-
39-
this.log(`Recording started in ${this.path}.`)
40-
41-
this.process.stdout!.on('data', (data) => {
42-
console.log(`[process] stdout: ${data}`)
43-
})
44-
45-
this.process.stderr!.on('data', (data) => {
46-
console.log(`[process] stderr: ${data}`)
47-
})
29+
this.process = exec(`adb -s ${this.device.id} shell screenrecord /sdcard/${this.fileName} --output-format mp4 --verbose`)
30+
console.log(`Recording started in ${this.path}.`)
4831

49-
this.process.on('error', (error) => {
50-
console.log(`[process] error: ${error.message}`)
51-
})
52-
}
53-
// adb shell screenrecord --output-format=h264 --size 1440x2560 - > ./screenrecord.raw
54-
//
32+
this.pid = execSync(`adb -s ${this.device.id} shell pidof screenrecord`).toString().trim().split(' ')[0]
33+
this.log(`Android screenrecord process spawned. PID: ${this.pid}`)
5534

56-
speedUpRequired = () => {
57-
return this.device.isEmulator && isMac()
35+
this.process.stdout!.on('data', (data) => this.log(`stdout: ${data}`))
36+
this.process.stderr!.on('data', (data) => this.log(`stderr: ${data}`))
37+
this.process.on('error', (error) => this.log(`error: ${error.message}`))
5838
}
5939

6040
save = async (): Promise<string> => {
6141
return new Promise((resolve) => {
62-
if (this.process) {
63-
this.process.kill('SIGINT')
64-
this.log('[process] SIGINT time.')
65-
66-
this.process.on('close', async (/* code: number */) => {
67-
// TODO: investigate why this process ends with a null exit code and reject promise if we can get a proper exit code
68-
execSync(
69-
`adb -s ${this.device.id} pull /sdcard/${this.fileName} ${this.path}.h264`
70-
)
71-
this.log('[process] File saved and ready to upload!')
72-
73-
let speedOption = ''
42+
this.log(`Killing Android screenrecord process. PID: ${this.pid}`)
43+
execSync(`adb -s ${this.device.id} shell kill -SIGINT ${this.pid}`)
7444

75-
if (this.speedUpRequired()) {
76-
speedOption = '-vf "setpts=1.6*PTS"'
77-
}
78-
79-
execSync(
80-
`${getFfmpegBin()} -vcodec h264 -i ${this.path}.h264 ${speedOption} -r 30 ${this.path}`
81-
)
45+
if (this.process) {
46+
this.process.on('close', async () => {
47+
execSync(`adb -s ${this.device.id} pull /sdcard/${this.fileName} ${this.path}`)
48+
console.log('File saved and ready to upload!')
8249
resolve(this.path)
8350
})
8451
}
@@ -88,7 +55,9 @@ export default class AndroidVideoShell {
8855
async destroy() {
8956
this.log('Destroying temporary video file')
9057
await fs.unlinkSync(this.path)
91-
// TODO: also destroy the video file on the android side
58+
59+
this.log('Destroying temporary video file on Android')
60+
execSync(`adb -s ${this.device.id} shell rm /sdcard/${this.fileName}`)
9261
}
9362

9463
private log(text: string) {

0 commit comments

Comments
 (0)