๐ฅ๏ธ๐ฅ JavaScript๋ก ์๋ ํ๋ฉด ๋ นํ
10208 ๋จ์ด opensourcejavascriptmac
defaults
recording feature ์ ๋น๋ํ ๋ ๊ด๋ฆฌ์ ์์
์ ์ต๋ํ ์๋ํํ๊ณ ์ถ์์ต๋๋ค. ์ฆ, ์คํฌ๋ฆฐ์ท๊ณผ ๋
น์์ ์คํฌ๋ฆฝํ
ํ๊ณ ์ macOS ๋ฒ์ ์ด ๋์ฌ ๋ ๋ค์ ์คํํ๊ณ ์ถ์ต๋๋ค. ๋์๊ฒ ๋ง์ ๋์์ด ๋ ๋ ๊ฐ์ง ํจํค์ง๋ฅผ ์ฐพ์์ต๋๋ค.robot.js ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๋ง์ฐ์ค๋ฅผ ์ด๋ํ๊ณ ํค๋ณด๋๋ฅผ ์ฌ์ฉํฉ๋๋ค(๋ชจ๋ OS์์ ์๋ํด์ผ ํจ).
์ฌ์ฉ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const aperture = require('aperture')()
const robot = require('robotjs')
const delay = require('delay')
const { compressVideo } = require('../../utils')
async function record() {
// ...
robot.moveMouse(pos1.x, pos1.y)
// Action!
await aperture.startRecording({ highlightClicks: true, cropArea })
robot.moveMouseSmooth(pos2.x, pos2.y, 2)
await delay(1000)
robot.moveMouseSmooth(pos3.x, pos3.y, 5)
await delay(100)
robot.moveMouseSmooth(pos1.x, pos1.y, 10)
await delay(500)
const tmpRecordingPath = await aperture.stopRecording()
// End recording
try {
await compressVideo(tmpRecordingPath, outputPath)
} catch (compressVideoError) {
throw new Error(compressVideoError)
}
}
์ฌ๊ธฐ์ ๋ฌด์จ ์ผ์ด ์ผ์ด๋๋์ง ์ค๋ช ํฉ์๋ค.
robot.moveMouse(pos1.x, pos1.y)
robot.js
moveMouse
๋ฉ์๋... ๋ง์ฐ์ค๋ฅผ ์์ง์ฌ ๋ณด์ธ์. ์ง์ฒด ์์ด ๋ฐ๋ก ํด์ค๋ค.x
๊ฐ์ ํ๋ฉด์ ์ผ์ชฝ ํ
๋๋ฆฌ์์ ์ค์ ๋ฉ๋๋ค. y
๊ฐ์ ์์ชฝ ํ
๋๋ฆฌ์์ ๊ฐ์ ธ์จ ๊ฒ์
๋๋ค.robot.moveMouseSmooth(pos2.x, pos2.y, 2)
moveMouseSmooth
"์ธ๊ฐ์ฒ๋ผ"ํฉ๋๋ค. ์๋ฒฝํ์ง๋ ์์ง๋ง ์ถฉ๋ถํฉ๋๋ค. ์ธ ๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ ๋ง์ฐ์ค ์ด๋ ์๋๋ฅผ ์กฐ์ ํฉ๋๋ค.๋ง์ง๋ง ์์ ์ด ๋ค๋ฅธ ์์ ์ ์ํํ๊ธฐ ์ ์ ์ข ๋ฃ๋์๋์ง ํ์ธํ๊ธฐ ์ํด delay ์ ์ฌ์ฉํ์ฌ ์์ ์ฌ์ด์ ์ฝ๊ฐ์ ์ง์ฐ์ ์ถ๊ฐํฉ๋๋ค.
๋ด๊ฐ ์ฌ์ฉํ ๋ค๋ฅธ robots.js ๋ฐฉ๋ฒ:
const { width, height } = robot.getScreenSize()
robot.keyTap('g', ['command', 'shift'])
const pic = robot.screen.capture(x, y, width, height)
๊ฐ๋จํฉ๋๋ค!
Aperture๋ก ๋์ด๊ฐ์๋ค.
Aperture๋ ๋ฐ์ด๋ ์ฑ๋ฅ์ผ๋ก AVFoundation framework์ ์ฌ์ฉํ๋ ์ ์์ค Swift ์คํฌ๋ฆฝํธ์ ๋๋ค. Kap ์ด๋ผ๋ ์คํ ์์ค ์คํฌ๋ฆฐ ๋ ์ฝ๋ ์๊ตฌ ์ฌํญ์ ์ถฉ์กฑํ๋๋ก ์ ์๋์์ต๋๋ค.
Node API๋ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค.
const options = {
cropArea: {
x: pos2.x - recordWidth / 2, y: 0,
width: recordWidth, height: recordHeight
},
highlightClicks: true
}
await aperture.startRecording(options)
CropArea
x
๊ฐ์ ํ๋ฉด์ ์ผ์ชฝ ํ
๋๋ฆฌ์์ ์ค์ ๋ฉ๋๋ค. ์๋์ชฝ ํ
๋๋ฆฌ์ y
๊ฐ์
๋๋ค. robots.js์ ๋์ผํ ์ฐธ์กฐ๊ฐ ์๋๋ฏ๋ก ์ฃผ์ํด์ผ ํ์ต๋๋ค!const tmpRecordingPath = await aperture.stopRecording()
//=> '/private/var/folders/3x/jf5977fn79jbglr7rk0tq4d00000gn/T/cdf4f7df426c97880f8c10a1600879f7.mp4'
stopRecording
๋ฉ์๋๋ ๋น๋์ค๊ฐ ์ ์ฅ๋๋ ๊ฒฝ๋ก๋ฅผ ์ ๊ณตํฉ๋๋ค.๊ทธ๋ฐ ๋ค์ ํ๋ฉด ๋ นํ๋ฅผ ์ฌํ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ ๊ฒฝ์ฐ์๋ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ๊ณ ์์ถํ๊ณ ๋ค๋ฅธ ํด๋๋ก ์ด๋ํ๋ ๋ฐฉ๋ฒ์ ๋ง๋ค์์ต๋๋ค.
๋ถํํ๋, ํด๊ฒฐ ์ํ์ ์ํ ๊ฐ๋ ฅํ ์๋ฃจ์ ์ ์ฐพ์ง ๋ชปํ์ต๋๋ค. ๋ฐ๋ผ์ ๋ค๋ฅธ ์ค์ ์์ ๊ฒฐ๊ณผ๊ฐ 100% ๋์ผํ๋ค๊ณ ๋ณด์ฅํ ์ ์์ต๋๋ค.
๊ทธ๊ฒ ๋ค์ผ! ๊ฐ๋จํ์ง ์์ต๋๊น? ์๊ฒฌ ์น์ ์์ ์ด๋ป๊ฒ ์๊ฐํ๋์ง ์๋ ค์ฃผ์ญ์์ค ๐
์๋ ํ๋ฉด ๋ นํ์ ๋ํด ๋ ์์ธํ ์๊ณ ์ถ๋ค๋ฉด macOS defaults recorder !
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฅ๏ธ๐ฅ JavaScript๋ก ์๋ ํ๋ฉด ๋ นํ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/yannbertrand/automated-screen-recording-with-javascript-18heํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค