Skip to content

Commit

Permalink
Use the new Decodable Swift protocol to handle options
Browse files Browse the repository at this point in the history
Fixes #8
  • Loading branch information
sindresorhus committed Sep 15, 2017
1 parent 79b24c8 commit 471c635
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 41 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ Number of frames per seconds.

##### cropArea

Type: `Object` `string`<br>
Default: `'none'`
Type: `Object`<br>
Default: `null`

Record only an area of the screen. Accepts an object with `x`, `y`, `width`, `height` properties.

Expand Down Expand Up @@ -116,8 +116,8 @@ Display to record.

##### audioSourceId

Type: `Object` `string`<br>
Default: `'none'`
Type: `string`<br>
Default: `null`

Audio source to include in the screen recording. Should be one of the `id`'s from `aperture.getAudioSources()`.

Expand Down
20 changes: 9 additions & 11 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,24 @@ class Aperture {

startRecording({
fps = 30,
cropArea = 'none',
cropArea = undefined,
showCursor = true,
highlightClicks = false,
displayId = 'main',
audioSourceId = 'none'
audioSourceId = undefined
} = {}) {
return new Promise((resolve, reject) => {
if (this.recorder !== undefined) {
reject(new Error('Call `.stopRecording()` first'));
return;
}

this.tmpPath = tempy.file({extension: 'mp4'});

if (highlightClicks === true) {
showCursor = true;
}

this.tmpPath = tempy.file({extension: 'mp4'});

if (typeof cropArea === 'object') {
if (typeof cropArea.x !== 'number' ||
typeof cropArea.y !== 'number' ||
Expand All @@ -41,21 +41,19 @@ class Aperture {
reject(new Error('Invalid `cropArea` option object'));
return;
}

cropArea = `${cropArea.x}:${cropArea.y}:${cropArea.width}:${cropArea.height}`;
}

const recorderOpts = [
this.tmpPath,
const recorderOpts = {
destination: this.tmpPath,
fps,
cropArea,
showCursor,
highlightClicks,
displayId,
audioSourceId
];
audioDeviceId: audioSourceId
};

this.recorder = execa(BIN, recorderOpts);
this.recorder = execa(BIN, [JSON.stringify(recorderOpts)]);

const timeout = setTimeout(() => {
// `.stopRecording()` was called already
Expand Down
64 changes: 38 additions & 26 deletions swift/aperture/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,51 @@ import Foundation
import AVFoundation

var recorder: Recorder!
let arguments = CommandLine.arguments.dropFirst()

func quit(_: Int32) {
recorder.stop()
}

func record() throws {
// TODO: Use JSON and `Codable` here when Swift 4 is out
struct CropArea: Decodable {
let x: CGFloat
let y: CGFloat
let width: CGFloat
let height: CGFloat
}

struct Options: Decodable {
let destination: String // TODO: Figure out a way to make this decodable into an `URL`
let fps: Int
let cropArea: CropArea? // TODO: Figure out a way to make this decodable into a `CGRect`
let showCursor: Bool
let highlightClicks: Bool
let displayId: String
let audioDeviceId: String?
}

let args = CommandLine.arguments
let destination = args[1]
let fps = args[2]
let cropArea = args[3]
let showCursor = args[4]
let highlightClicks = args[5]
let displayId = args[6]
let audioDeviceId = args[7]
func record() throws {
let json = arguments.first!.data(using: .utf8)!
let options = try JSONDecoder().decode(Options.self, from: json)

var cropRect: CGRect?
if cropArea != "none" {
let points = cropArea.components(separatedBy: ":").map { Double($0)! }
cropRect = CGRect(x: points[0], y: points[1], width: points[2], height: points[3])
if let cropArea = options.cropArea {
cropRect = CGRect(
x: cropArea.x,
y: cropArea.y,
width: cropArea.width,
height: cropArea.height
)
}

recorder = try Recorder(
destination: URL(fileURLWithPath: destination),
fps: Int(fps)!,
destination: URL(fileURLWithPath: options.destination),
fps: options.fps,
cropRect: cropRect,
showCursor: showCursor == "true",
highlightClicks: highlightClicks == "true",
displayId: displayId == "main" ? CGMainDisplayID() : CGDirectDisplayID(displayId)!,
audioDevice: audioDeviceId == "none" ? nil : .default(for: .audio)
showCursor: options.showCursor,
highlightClicks: options.highlightClicks,
displayId: options.displayId == "main" ? CGMainDisplayID() : CGDirectDisplayID(options.displayId)!,
audioDevice: options.audioDeviceId != nil ? AVCaptureDevice(uniqueID: options.audioDeviceId!) : .default(for: .audio)
)

recorder.onStart = {
Expand Down Expand Up @@ -70,16 +84,14 @@ func usage() {
)
}

let numberOfArgs = CommandLine.arguments.count

if numberOfArgs == 8 {
try record()
if arguments.first == "list-audio-devices" {
// Use stderr because of unrelated stuff being outputted on stdout
printErr(try toJson(DeviceList.audio()))
exit(0)
}

if numberOfArgs == 2 && CommandLine.arguments[1] == "list-audio-devices" {
// Use stderr because of unrelated stuff being outputted on stdout
printErr(try toJson(DeviceList.audio()))
if arguments.first != nil {
try record()
exit(0)
}

Expand Down

0 comments on commit 471c635

Please sign in to comment.