I can only select the portion of the screen to record manually. I want them all exactly the same so that when the videos are played sequentially, it all lines up.

enter image description here

I'm using quicktime and would ideally like to just stick with that if possible.


Here in 2020 - macOS Catalina and later allows the built-in /usr/sbin/screencapture tool has options for specifying the capture area. And if you use it graphically, it remembers the last selection so unless you change it, you can relaunch the app and get the same settings without the details below.

  -R<x,y,w,h> capture screen rect
  -v        capture video recording of the screen

For example:

screencapture -R10,10,500,500 -v cap.mov

There's a bunch of other good stuff in the man page:

man screencapture
  • Yay, my code is now redundant. Perfect, thanks :) – matt burns Oct 28 '20 at 12:00

UPDATE: Answer by @Andre LaBranche is better, go read that

Save this script as caperture.swift:

#!/usr/bin/env xcrun swift
import Foundation

// Start QuickTime Player using AppleScript
func startQT() {
    var scriptToPerform: NSAppleScript?
    let asCommand = "tell application \"QuickTime Player\" \n" +
            " activate \n" +
            " new screen recording \n" +
            " delay 1 \n" +
            " tell application \"System Events\" to key code 49 \n" +
            " delay 1\n" +
            " end tell"

    scriptToPerform = NSAppleScript(source:asCommand)
    var possibleError: NSDictionary?

    if let script = scriptToPerform {
        if let error = possibleError {
            print("ERROR: \(error)")

// Click and drag the mouse as defined by the supplied commandline arguments
func dragMouse() {
    let args = UserDefaults.standard

    let x = CGFloat(args.integer(forKey: "x"))
    let y = CGFloat(args.integer(forKey: "y"))
    let w = CGFloat(args.integer(forKey: "w"))
    let h = CGFloat(args.integer(forKey: "h"))

    let p0 = NSPointToCGPoint(NSMakePoint(x, y))
    let p1 = NSPointToCGPoint(NSMakePoint(x + w, y + h))

    let mouseDown = CGEvent(mouseEventSource: nil, mouseType: CGEventType.leftMouseDown, mouseCursorPosition: p0, mouseButton: CGMouseButton.left)!
    let mouseDrag = CGEvent(mouseEventSource: nil, mouseType: CGEventType.leftMouseDragged, mouseCursorPosition: p1, mouseButton: CGMouseButton.left)!
    let mouseUp = CGEvent(mouseEventSource: nil, mouseType: CGEventType.leftMouseUp, mouseCursorPosition: p1, mouseButton: CGMouseButton.left)!

    let kDelayUSec : useconds_t = 500_000

    mouseDown.post(tap: CGEventTapLocation.cghidEventTap)
    mouseDrag.post(tap: CGEventTapLocation.cghidEventTap)
    mouseUp.post(tap: CGEventTapLocation.cghidEventTap)

if (CommandLine.arguments.count != 9) {
    print("    ./caperture.swift -x 100 -y 100 -w 400 -h 300")
} else {

Once the caperture.swift file is saved. You will need to make sure that it can be executed.

In Terminal.app run the command:

chmod +x caperture.swift

Then you execute it with:

./caperture.swift -x 100 -y 100 -w 400 -h 300

This will start up QuickTime player ready to start recording like this:


It relies on AppleScript and swift so you'll also need xcode installed.

This was really useful for me so I've put it up on github as caperture in case anyone wants to improve it.

  • 1
    I think this might be our first answer with swift code in it! Stellar! – Ian C. Mar 13 '15 at 18:18
  • I edited the answer. But I did not edit an error in your code as it may be intentional for some reason. But the line let p1 = CGPointMake(x + dx, y + dy) should be let p1 = CGPointMake(dx, dy) there is no need to add the integers and doing so throws the bounds to be incorrect of what is placed in the applescript. Example if I use bounds {364, 206, 1038, 726} what I will get is a dragged window {364, 206, 1402, 932} – markhunte Mar 13 '15 at 19:40
  • Thanks Mark. dx and dy actually represent width and height, not the point in bottom right so I have renamed to reflect that. I also folded in your suggestion of merging into a single file. See github.com/mattburns/caperture for current version. Cheers – matt burns Mar 16 '15 at 16:49
  • 1
    Nice one matt. Love this code as it can be used for many things. Thanks. By the way you should accept your own answer... – markhunte Mar 16 '15 at 20:47

There is an App called Screeny that does this as well as many other things. $14.99 and can be purchased from the App store


I like @mat-burns answer a lot.

But since we would be running the Applescript from the command line to execute the swift code anyway I wanted to do it all from a single file.

Adding the Applescript to the swift code:

#!/usr/bin/env xcrun swift
import Foundation

let kDelayUSec : useconds_t = 500_000

func DragMouse(p0: CGPoint, p1: CGPoint) {
    let mouseDown = CGEventCreateMouseEvent(nil, CGEventType(kCGEventLeftMouseDown), p0, CGMouseButton(kCGMouseButtonLeft)).takeUnretainedValue()
    let mouseDrag = CGEventCreateMouseEvent(nil, CGEventType(kCGEventLeftMouseDragged), p1, CGMouseButton(kCGMouseButtonLeft)).takeUnretainedValue()
    let mouseUp = CGEventCreateMouseEvent(nil, CGEventType(kCGEventLeftMouseUp), p1, CGMouseButton(kCGMouseButtonLeft)).takeUnretainedValue()

    CGEventPost(CGEventTapLocation(kCGHIDEventTap), mouseDown)
    CGEventPost(CGEventTapLocation(kCGHIDEventTap), mouseDrag)
    CGEventPost(CGEventTapLocation(kCGHIDEventTap), mouseUp)

func ascript(){

    var scriptToPerform: NSAppleScript?
    let asCommand = "tell application \"QuickTime Player\" \n activate \n new screen recording \n delay 1 \n tell application \"System Events\" to key code 49 \n delay 1\n end tell"

  scriptToPerform = NSAppleScript(source:asCommand)
   var errorInfo = AutoreleasingUnsafeMutablePointer<NSDictionary?>()

    if let script = scriptToPerform {




func main() {
let p0 = CGPointMake( CGFloat(atoi( C_ARGV[1])), CGFloat(atoi( C_ARGV[2])))
let p1 = CGPointMake( CGFloat(atoi( C_ARGV[3])),  CGFloat(atoi( C_ARGV[4])))

DragMouse(p0, p1)

Once the code is saved and we have run /bin/chmod +x ~/scripts/clickdrag.swift to make the script executable

Change ~/scripts/clickdrag.swift to you actual path to the swift file.

We can now run the code from the command line :


Before you would have had to enter the command line like so:

~/scripts/clickdrag.swift -x 364 -y 206 -dx 1038 -dy 726

But if we use the simple way of working out any bounds you need by opening up a finder window and shaping it to the area you want to capture.

Then run this Applescript:

tell application "Finder" to get bounds of window 1

This will return the bounds in the results pane.

-> {364, 206, 1038, 726}

It would be a lot easier to copy and past 364, 206, 1038, 726 into the command as is.

The update above allows you to run the command like so.

~/scripts/clickdrag.swift 364, 206, 1038, 726

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .