I am trying to get Apple's AVScreenShack example project running on OS X 10.8.2.
When I run the application and trigger the recording (calling startRecording
), a strange sequence of events follows:
- The application continues to use ~40% CPU (presumably necessary to display the video preview in the application window)
- The delegate method
captureOutput:didStartRecordingToOutputFileAtURL:fromConnections:
is never called
When I trigger stopRecording
:
- The application continues to use ~40% CPU
- The "about to stop"
NSLog
call shows that thecaptureMovieFileOutput
object carries a valid file URL (pointing to a temporary file on the desktop) - The delegate method
captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:
is never called - No file is created on the desktop, even after several minutes
I see no errors in the output console. Is there some way I can effectively debug this further?
The relevant code follows. I haven't modified it (but have omitted unnecessary portions of it here).
- (BOOL)createCaptureSession:(NSError **)outError
{
NSLog(@"createCaptureSession start");
/* Create a capture session. */
self.captureSession = [[AVCaptureSession alloc] init];
// ...
/* Add the main display as a capture input. */
display = CGMainDisplayID();
self.captureScreenInput = [[AVCaptureScreenInput alloc]
initWithDisplayID:display];
if ([self.captureSession canAddInput:self.captureScreenInput]) {
[self.captureSession addInput:self.captureScreenInput];
} else {
return NO;
}
/* Add a movie file output + delegate. */
captureMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
[captureMovieFileOutput setDelegate:self];
if ([self.captureSession canAddOutput:captureMovieFileOutput]) {
[self.captureSession addOutput:captureMovieFileOutput];
} else {
return NO;
}
/* Register for notifications of errors during the capture session so we
can display an alert. */
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(captureSessionRuntimeErrorDidOccur:)
name:AVCaptureSessionRuntimeErrorNotification
object:self.captureSession];
NSLog(@"createCaptureSession finish w/o errors");
return YES;
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
didStartRecordingToOutputFileAtURL:(NSURL *)fileURL
fromConnections:(NSArray *)connections {
NSLog(@"starting output");
NSLog(@"%@", captureMovieFileOutput.outputFileURL);
}
/* Informs the delegate when all pending data has been written to the output file. */
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(@"didFinish");
if (error)
{
[self presentError:error];
return;
}
[[NSWorkspace sharedWorkspace] openURL:outputFileURL];
}
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
NSLog(@"about to start running the session %@", self.captureSession);
/* Start the capture session running. */
[self.captureSession startRunning];
}
/* Called when the user presses the 'Start' button to start a recording. */
- (IBAction)startRecording:(id)sender
{
NSLog(@"startRecording");
char *tempNameBytes = tempnam([[@"~/Desktop/" stringByStandardizingPath]
fileSystemRepresentation], "AVScreenShack_");
NSString *tempName = [[NSString alloc]
initWithBytesNoCopy:tempNameBytes
length:strlen(tempNameBytes)
encoding:NSUTF8StringEncoding
freeWhenDone:YES];
/* Starts recording to a given URL. */
[captureMovieFileOutput
startRecordingToOutputFileURL:[NSURL fileURLWithPath:[tempName stringByAppendingPathExtension:@"mov"]]
recordingDelegate:self];
}
/* Called when the user presses the 'Stop' button to stop a recording. */
- (IBAction)stopRecording:(id)sender
{
NSLog(@"about to stop from URL: %@", captureMovieFileOutput.outputFileURL);
[captureMovieFileOutput stopRecording];
}
/* Called when the document is closed. */
- (void)close
{
NSLog(@"about to stop from URL: %@", captureMovieFileOutput.outputFileURL);
/* Stop the capture session running. */
[self.captureSession stopRunning];
[super close];
}
The log output from the above program follows. Notice that the "didFinish" log call was never made, nor was "starting output."
2013-04-20 16:00:01.908 AVScreenShack[8950:303] createCaptureSession start
2013-04-20 16:00:01.912 AVScreenShack[8950:303] createCaptureSession finish w/o errors
2013-04-20 16:00:02.131 AVScreenShack[8950:303] about to start running the session <AVCaptureSession: 0x100618e70 [AVCaptureSessionPresetHigh]>
2013-04-20 16:00:10.936 AVScreenShack[8950:303] startRecording
2013-04-20 16:00:10.936 AVScreenShack[8950:303] Minimum Frame Duration: 0.066667, Crop Rect: {{0, 0}, {0, 0}}, Scale Factor: 1.000000, Capture Mouse Clicks: No, Capture Mouse Cursor: Yes, Remove Duplicate Frames: Yes
2013-04-20 16:00:15.648 AVScreenShack[8950:303] about to stop from URL: file://localhost/Users/jon/Desktop/AVScreenShack_Y2DUaA.mov