How to capture screen activity to a movie file using AV Foundation on OS X 10.7 Lion and later
Q: How do I capture screen activity to a QuickTime movie on OS X 10.7 Lion and later?
A: On OS X 10.7 Lion and later, the way to make a movie of screen activity is to use AV Foundation.
Important: AV Foundation grabs the screen repeatedly. If you want to capture a static image instead of a real-time movie, a more efficient way is to call CGDisplayCreateImage orCGDisplayCreateImageForRect, for example:
// Create an image from the entire main display
CGImageRef image = CGDisplayCreateImage(kCGDirectMainDisplay);
See How to take an image snapshot of the screen on Mac OS X Lion for more information.
To perform a real-time screen capture and save it to a QuickTime movie file, you need minimally three AV objects:
-
An
AVCaptureSessionobject, which coordinates the flow of data from AV input sources to outputs. -
An
AVCaptureScreenInputobject, which is the input data source that provides video data from the given display. -
An
AVCaptureMovieFileOutputobject, which is the output destination for you to write captured media data to a QuickTime movie file.
Note: By default, AVCaptureScreenInput captures the entire screen. You may set its cropRect property to limit the capture rectangle to a subsection of the screen.
In the following example, the code creates a capture session, adds a screen input to provide video frames, adds an output destination to save captured frames, starts the flow of data from the input to the output, and stops the flow in 5 seconds. By letting the class conform to the AVCaptureFileOutputRecordingDelegate protocol and setting the recording delegate properly, you can monitor when the recording is finished via the delegate method.
Note: To capture both a main and secondary display at the same time, use two active capture sessions, one for each display. On OS X, AVCaptureMovieFileOutput only supports writing to a single video track.
Listing 1 Conforming to the AVCaptureFileOutputRecordingDelegate protocol
#import <Foundation/Foundation.h> |
#import <AVFoundation/AVFoundation.h> |
| |
@interface Recorder : NSObject <AVCaptureFileOutputRecordingDelegate> { |
@private |
AVCaptureSession *mSession; |
AVCaptureMovieFileOutput *mMovieFileOutput; |
NSTimer *mTimer; |
} |
| |
-(void)screenRecording:(NSURL *)destPath; |
| |
@end |
Listing 2 Screen recording example
-(void)screenRecording:(NSURL *)destPath |
{ |
// Create a capture session |
mSession = [[AVCaptureSession alloc] init]; |
| |
// Set the session preset as you wish |
mSession.sessionPreset = AVCaptureSessionPresetMedium; |
| |
// If you're on a multi-display system and you want to capture a secondary display, |
// you can call CGGetActiveDisplayList() to get the list of all active displays. |
// For this example, we just specify the main display. |
// To capture both a main and secondary display at the same time, use two active |
// capture sessions, one for each display. On Mac OS X, AVCaptureMovieFileOutput |
// only supports writing to a single video track. |
CGDirectDisplayID displayId = kCGDirectMainDisplay; |
| |
// Create a ScreenInput with the display and add it to the session |
AVCaptureScreenInput *input = [[[AVCaptureScreenInput alloc] initWithDisplayID:displayId] autorelease]; |
if (!input) { |
[mSession release]; |
mSession = nil; |
return; |
} |
if ([mSession canAddInput:input]) |
[mSession addInput:input]; |
| |
// Create a MovieFileOutput and add it to the session |
mMovieFileOutput = [[[AVCaptureMovieFileOutput alloc] init] autorelease]; |
if ([mSession canAddOutput:mMovieFileOutput]) |
[mSession addOutput:mMovieFileOutput]; |
| |
// Start running the session |
[mSession startRunning]; |
| |
// Delete any existing movie file first |
if ([[NSFileManager defaultManager] fileExistsAtPath:[destPath path]]) |
{ |
NSError *err; |
if (![[NSFileManager defaultManager] removeItemAtPath:[destPath path] error:&err]) |
{ |
NSLog(@"Error deleting existing movie %@",[err localizedDescription]); |
} |
} |
| |
// Start recording to the destination movie file |
// The destination path is assumed to end with ".mov", for example, @"/users/master/desktop/capture.mov" |
// Set the recording delegate to self |
[mMovieFileOutput startRecordingToOutputFileURL:destPath recordingDelegate:self]; |
| |
// Fire a timer in 5 seconds |
mTimer = [[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(finishRecord:) userInfo:nil repeats:NO] retain]; |
} |
| |
-(void)finishRecord:(NSTimer *)timer |
{ |
// Stop recording to the destination movie file |
[mMovieFileOutput stopRecording]; |
| |
[mTimer release]; |
mTimer = nil; |
} |
| |
// AVCaptureFileOutputRecordingDelegate methods |
| |
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error |
{ |
NSLog(@"Did finish recording to %@ due to error %@", [outputFileURL description], [error description]); |
| |
// Stop running the session |
[mSession stopRunning]; |
| |
// Release the session |
[mSession release]; |
mSession = nil; |
} |
Document Revision History
| Date | Notes |
|---|---|
| 2015-05-20 | Added additional notes about capturing the main and secondary displays at the same time. Other miscellaneous changes. |
| 2011-08-10 | Corrected a link. |
| 2011-05-13 | New document that shows how to capture screen activity to a movie file using AV Foundation on OS X 10.7 Lion and later. |

本文介绍如何使用AVFoundation在OSX 10.7 Lion及更高版本上录制屏幕活动为QuickTime电影文件。通过创建AVCaptureSession、AVCaptureScreenInput和AVCaptureMovieFileOutput对象,可以实现屏幕录制并保存到指定路径。
207

被折叠的 条评论
为什么被折叠?



