Skip to content

Commit a8a037e

Browse files
committed
countdown etc
1 parent 2ad3df8 commit a8a037e

File tree

5 files changed

+123
-48
lines changed

5 files changed

+123
-48
lines changed

index.js

Lines changed: 58 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
const { spawn } = require("child_process")
21
const { join } = require("path")
32

43
const chalk = require("kleur")
5-
const { spawnSafeSync } = require("./src/spawnSafeSync")
6-
const { getDevice } = require("./src/getDevice")
4+
const { init, adb, adbAsync } = require("./src/adb")
5+
const { existsSync } = require("fs")
6+
const { countdown } = require("./src/countdown")
77

88
const version = require(join(__dirname, "./package.json")).version
99

@@ -18,31 +18,25 @@ process.stdin.resume()
1818
process.stdin.setEncoding("utf8")
1919

2020
/**
21-
* @returns {"1" | "0"}
21+
* @returns {boolean}
2222
*/
2323
function getVisibleTouches() {
24-
// @ts-ignore
25-
return spawnSafeSync("adb", [
26-
"shell",
27-
"settings",
28-
"get",
29-
"system",
30-
"show_touches",
31-
]).stdout.toString()
24+
return (
25+
adb(
26+
"shell",
27+
"settings",
28+
"get",
29+
"system",
30+
"show_touches",
31+
).stdout.toString() === "1"
32+
)
3233
}
3334

3435
/**
3536
* @param {boolean} visible
3637
*/
3738
function setVisibleTouches(visible) {
38-
spawnSafeSync("adb", [
39-
"shell",
40-
"settings",
41-
"put",
42-
"system",
43-
"show_touches",
44-
visible ? "1" : "0",
45-
])
39+
adb("shell", "settings", "put", "system", "show_touches", visible ? "1" : "0")
4640
}
4741

4842
const ESCAPE_KEYS = {
@@ -64,12 +58,12 @@ const ENTER_KEYS = {
6458

6559
/**
6660
* @param {string} outFile
67-
* @returns {Promise<void>}
61+
* @returns {Promise<{escaped: boolean}>}
6862
*/
6963
function recordVideo(outFile) {
7064
return new Promise((resolve, reject) => {
7165
const internalFilePath = `/sdcard/android-screen-recording.mp4`
72-
const recordProc = spawn("adb", ["shell", "screenrecord", internalFilePath])
66+
const recordProc = adbAsync("shell", "screenrecord", internalFilePath)
7367
let err = ""
7468
recordProc.stderr.on("data", (data) => {
7569
err += data.toString()
@@ -82,13 +76,17 @@ function recordVideo(outFile) {
8276
}
8377
process.stdin.removeListener("data", handleKeyPress)
8478
console.log("\n ", chalk.green("✔"), "Cut! 🎬", "\n")
85-
console.log("Transferring video from phone...\n")
86-
await new Promise((r) => setTimeout(r, 2000))
87-
spawnSafeSync("adb", ["pull", internalFilePath, outFile])
88-
spawnSafeSync("adb", ["shell", "rm", internalFilePath])
89-
resolve()
79+
if (!escaped) {
80+
console.log("Transferring video from phone...\n")
81+
await new Promise((r) => setTimeout(r, 2000))
82+
adb("pull", internalFilePath, outFile)
83+
} else {
84+
console.log("Cancelling...")
85+
}
86+
adb("shell", "rm", internalFilePath)
87+
resolve({ escaped })
9088
})
91-
console.log("\n ", chalk.red("⦿"), "Recording...", "\n")
89+
console.log(" ", chalk.red("⦿"), "Recording...", "\n")
9290
printCallToAction()
9391

9492
// on any data into stdin
@@ -134,24 +132,42 @@ function printCallToAction() {
134132
}
135133

136134
async function run() {
137-
const device = await getDevice()
138-
console.log({device})
139-
process.exit(1)
140-
const outPath = "./recording.mp4"
141-
setVisibleTouches(true)
142-
143135
try {
144-
await recordVideo(outPath)
145-
console.log("That's a wrap!", chalk.bold(outPath))
146-
console.log()
136+
await init()
137+
await countdown()
138+
139+
const date = new Date()
140+
const year = date.getFullYear()
141+
const month = date.getMonth() + 1
142+
const day = date.getDate()
143+
144+
let outPath = `./recording.${year}-${month}-${day}.00.mp4`
145+
let i = 1
146+
while (existsSync(outPath)) {
147+
outPath = `./recording.${year}-${month}-${day}.${i
148+
.toString()
149+
.padStart(2, "0")}.mp4`
150+
i++
151+
}
152+
setVisibleTouches(true)
153+
154+
try {
155+
const result = await recordVideo(outPath)
156+
if (!result.escaped) {
157+
console.log("That's a wrap!", chalk.bold(outPath))
158+
}
159+
console.log()
160+
} catch (e) {
161+
console.error("failed in main loop", e)
162+
}
163+
164+
setVisibleTouches(false)
165+
166+
process.exit(0)
147167
} catch (e) {
148168
console.error(e)
169+
process.exit(1)
149170
}
150-
151-
setVisibleTouches(false)
152-
153-
process.exit(0)
154171
}
155172

156173
run()
157-
// getVisibleTouches()

src/adb.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const { spawn } = require("child_process")
2+
const { getDevice } = require("./getDevice")
3+
const { spawnSafeSync } = require("./spawnSafeSync")
4+
5+
let device = ""
6+
7+
module.exports.adb = (/** @type {string[]} */ ...args) =>
8+
spawnSafeSync("adb", ["-s", device, ...args])
9+
10+
module.exports.adbAsync = (/** @type {string[]} */ ...args) =>
11+
spawn("adb", ["-s", device, ...args])
12+
13+
module.exports.init = async () => {
14+
device = await getDevice()
15+
}

src/countdown.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const countdownString = "3...2...1..."
2+
3+
module.exports.countdown = async () => {
4+
return new Promise((r) => {
5+
const startTime = Date.now()
6+
function tick() {
7+
const now = Date.now()
8+
const elapsed = now - startTime
9+
const ratio = elapsed / 3000
10+
const numCharsOfCountdownStringToUse = Math.floor(
11+
countdownString.length * ratio,
12+
)
13+
const countdownSoFar = countdownString.slice(
14+
0,
15+
numCharsOfCountdownStringToUse,
16+
)
17+
process.stdout.write(` 🎬 Get ready! ${countdownSoFar}\r`)
18+
if (ratio >= 1) {
19+
process.stdout.write("\033[K")
20+
clearInterval(interval)
21+
r(null)
22+
}
23+
}
24+
const interval = setInterval(tick, 50)
25+
})
26+
}

src/getDevice.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const { spawnSafeSync } = require("./spawnSafeSync")
2-
const { bgRed, bold, bgBlue, cyan, gray, magenta } = require("kleur")
2+
const { bgRed, bold, bgBlue, cyan, gray } = require("kleur")
33

44
const ERROR = bgRed(" ERROR ")
55

@@ -57,7 +57,7 @@ function parseDeviceLine(line) {
5757
* @returns {Promise<number>}
5858
*/
5959
async function selectOption(title, options) {
60-
return new Promise((resolve, reject) => {
60+
return new Promise((resolve) => {
6161
console.log()
6262
console.log(" ", bgBlue(` ${title} `))
6363
console.log()
@@ -78,6 +78,7 @@ async function selectOption(title, options) {
7878
const reset = () => {
7979
process.stdout.write("\r\033[K")
8080
process.stdout.write("\033[1A\r")
81+
process.stdout.write("\033[K")
8182
process.stdout.write("\033[1A\r")
8283
for (let i = 0; i < options.length; i++) {
8384
process.stdout.write("\033[1A\r")
@@ -90,15 +91,22 @@ async function selectOption(title, options) {
9091
* @param {string} key
9192
*/
9293
function handleKeyPress(key) {
93-
key = key.toString()
9494
if (key === "\r") {
9595
// enter!
96-
process.stdout.removeListener("data", handleKeyPress)
96+
process.stdin.removeListener("data", handleKeyPress)
97+
98+
reset()
99+
process.stdout.write("\033[1A\r")
100+
process.stdout.write("\033[K")
101+
process.stdout.write("\033[1A\r")
102+
process.stdout.write("\033[K")
103+
97104
resolve(selection)
98105
} else if (key === "\u001b[B") {
99106
// arrow down!
100107
selection = Math.min(selection + 1, options.length - 1)
101108
reset()
109+
102110
draw()
103111
} else if (key === "\u001b[A") {
104112
// arrow up!
@@ -109,7 +117,7 @@ async function selectOption(title, options) {
109117
process.exit(1)
110118
}
111119
}
112-
process.stdout.on("data", handleKeyPress)
120+
process.stdin.on("data", handleKeyPress)
113121
})
114122
}
115123

src/spawnSafeSync.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ const defaultOptions = {
1010

1111
const { spawnSync } = require("child_process")
1212

13+
class ConsoleError {
14+
/**
15+
* @param {import('node:child_process').SpawnSyncReturns<Buffer>} result
16+
*/
17+
constructor(result) {
18+
this.result = result
19+
}
20+
}
21+
module.exports.ConsoleError = ConsoleError
22+
1323
module.exports.spawnSafeSync = (
1424
/** @type {string} */ command,
1525
/** @type {string[]} */ args,
@@ -26,7 +36,7 @@ module.exports.spawnSafeSync = (
2636
}
2737
}
2838
if (mergedOptions.throwOnError) {
29-
throw result
39+
throw new ConsoleError(result)
3040
}
3141
}
3242
return result

0 commit comments

Comments
 (0)