Reputation: 42267
I am attempting to implement the AVFoundation example code found here in an Xcode project: http://developer.apple.com/library/mac/#qa/qa1740/_index.html#//apple_ref/doc/uid/DTS40011007
The only modifications I have made were to remove references to autorelease, release, and retain because I have automatic reference counting enabled for the project. Having successfully resolved those build errors, I am now getting "Undefined symbols for architecture x86_64".
I am running on Mountain Lion 10.8, and get no errors when importing AVFoundation.h into my headers file, but it seems like the AV* symbols are not being found?
Below is the error log, .h, and .m code. Could someone more knowledgable help me identify where the issue(s) lie?
Log:
Undefined symbols for architecture x86_64:
"_AVCaptureSessionPresetMedium", referenced from:
-[Recorder screenRecording:] in screenAppDelegate.o
"_OBJC_CLASS_$_AVCaptureMovieFileOutput", referenced from:
objc-class-ref in screenAppDelegate.o
"_OBJC_CLASS_$_AVCaptureScreenInput", referenced from:
objc-class-ref in screenAppDelegate.o
"_OBJC_CLASS_$_AVCaptureSession", referenced from:
objc-class-ref in screenAppDelegate.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
.h
#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface screenAppDelegate : NSObject <NSApplicationDelegate>
@end
@interface Recorder : NSObject <AVCaptureFileOutputRecordingDelegate> {
@private AVCaptureSession *mSession;
AVCaptureMovieFileOutput *mMovieFileOutput;
NSTimer *mTimer;
}
-(void)screenRecording:(NSURL *)destPath;
@end
.m
#import "screenAppDelegate.h"
@implementation screenAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
}
@end
@implementation Recorder
-(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.
CGDirectDisplayID displayId = kCGDirectMainDisplay;
// Create a ScreenInput with the display and add it to the session
AVCaptureScreenInput *input = [[AVCaptureScreenInput alloc] initWithDisplayID:displayId];
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];
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];
}
-(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;
}
Upvotes: 2
Views: 5958
Reputation:
It's not enough to import header files, you also have to add the AVFoundation framework to your project. This error comes from the linker, not from the compiler itself - the AVFoundation headers could be found and the compilation of your source files was successful, but the linker couldn't make an executable out of the resulting object files as you haven't told it (through Xcode's settings) to link against the AVFoundation framework.
See this article on the compilation process to understand why this happens.
Upvotes: 6