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.
I'm using quicktime and would ideally like to just stick with that if possible.
Ask Different is a question and answer site for power users of Apple hardware and software. It only takes a minute to sign up.
Sign up to join this communityI 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.
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
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 {
script.executeAndReturnError(&possibleError)
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)
usleep(kDelayUSec)
mouseDrag.post(tap: CGEventTapLocation.cghidEventTap)
usleep(kDelayUSec)
mouseUp.post(tap: CGEventTapLocation.cghidEventTap)
}
if (CommandLine.arguments.count != 9) {
print("usage:")
print(" ./caperture.swift -x 100 -y 100 -w 400 -h 300")
} else {
startQT()
dragMouse()
}
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.
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
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)
usleep(kDelayUSec)
CGEventPost(CGEventTapLocation(kCGHIDEventTap), mouseDrag)
usleep(kDelayUSec)
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 {
script.executeAndReturnError(errorInfo)
}
}
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)
}
ascript()
main()
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 :
UPDATE
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