Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
QTCapturePlugin/MyCaptureView.m
/* |
File: MyCaptureView.h |
Abstract: A WebKit Plug-in showing how to use the QTCapture framework |
to perform video/audio capture and recording to a QuickTime movie. |
Version: 1.0 |
Disclaimer: IMPORTANT: This Apple software is supplied to you by |
Apple Inc. ("Apple") in consideration of your agreement to the |
following terms, and your use, installation, modification or |
redistribution of this Apple software constitutes acceptance of these |
terms. If you do not agree with these terms, please do not use, |
install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and |
subject to these terms, Apple grants you a personal, non-exclusive |
license, under Apple's copyrights in this original Apple software (the |
"Apple Software"), to use, reproduce, modify and redistribute the Apple |
Software, with or without modifications, in source and/or binary forms; |
provided that if you redistribute the Apple Software in its entirety and |
without modifications, you must retain this notice and the following |
text and disclaimers in all such redistributions of the Apple Software. |
Neither the name, trademarks, service marks or logos of Apple Inc. |
may be used to endorse or promote products derived from the Apple |
Software without specific prior written permission from Apple. Except |
as expressly stated in this notice, no other rights or licenses, express |
or implied, are granted by Apple herein, including but not limited to |
any patent rights that may be infringed by your derivative works or by |
other works in which the Apple Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE |
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION |
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS |
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND |
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL |
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, |
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED |
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), |
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGE. |
Copyright (C) 2007 Apple Inc. All Rights Reserved. |
*/ |
#import "MyCaptureView.h" |
#import "Plugin.h" |
// Strings which indicate the current state for the input device |
const NSString * MyCaptureViewDisconnected = @"A device was disconnected"; |
const NSString * MyCaptureViewConnected = @"A device was connected"; |
const NSString * MyCaptureViewRecording = @"Recording"; |
const NSString * MyCaptureViewFinishedRecording = @"Finished recording"; |
@implementation MyCaptureView |
/* we'll use awakeFromNib to setup QTCapture notifications for |
device connections/disconnection */ |
- (void)awakeFromNib |
{ |
PDEBUG(); |
if(!mCaptureSession) |
{ |
// Create the capture session |
mCaptureSession = [[QTCaptureSession alloc] init]; |
} |
// We want to get notified when devices are connected or disconnected |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceWasConnected:) name: QTCaptureDeviceWasConnectedNotification object:nil]; |
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceWasDisconnected:) name: QTCaptureDeviceWasDisconnectedNotification object:nil]; |
// begin capture |
[self captureInit]; |
} |
- (void) dealloc |
{ |
PDEBUG(); |
[self captureDelete]; /* stop doing capture, and perform clean-up */ |
[mCaptureSession release]; |
[super dealloc]; |
} |
/* JavaScript calls can only be made from the main Plugin class. |
This routine is called by the Plugin class to specify a method which |
can be used for this purpose. */ |
-(void)setPlugInCallback:(SEL)selector onTarget:(id)target |
{ |
PDEBUG(); |
mNotificationTarget = selector; |
mNotificationObject = target; |
} |
#pragma mark Capture |
/* Begin capture |
We'll create a capture session with the following device inputs & outputs: |
- video device input |
- audio device input |
- movie file output |
then start capturing. |
*/ |
-(void)captureInit |
{ |
PDEBUG(); |
if ([mCaptureSession isRunning] == NO) |
{ |
BOOL success = NO; |
NSError *error; |
// Find a video device |
QTCaptureDevice *videoDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo]; |
success = [videoDevice open:&error]; |
// If a video input device can't be found or opened, try to find and open a muxed input device |
if (!success) |
{ |
videoDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed]; |
success = [videoDevice open:&error]; |
} |
if (!success) |
{ |
videoDevice = nil; |
// Handle error |
goto bail; |
} |
// Connect inputs and outputs to the session |
if (videoDevice) |
{ |
//Add the video device to the session as a device input |
mCaptureVideoDeviceInput = [[QTCaptureDeviceInput alloc] initWithDevice:videoDevice]; |
success = [mCaptureSession addInput:mCaptureVideoDeviceInput error:&error]; |
if (!success) |
{ |
// Handle error |
goto bail; |
} |
// If the video device doesn't also supply audio, add an audio device input to the session |
if (![videoDevice hasMediaType:QTMediaTypeSound] && ![videoDevice hasMediaType:QTMediaTypeMuxed]) |
{ |
QTCaptureDevice *audioDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeSound]; |
success = [audioDevice open:&error]; |
if (!success) |
{ |
audioDevice = nil; |
// Handle error |
goto bail; |
} |
if (audioDevice) |
{ |
mCaptureAudioDeviceInput = [[QTCaptureDeviceInput alloc] initWithDevice:audioDevice]; |
success = [mCaptureSession addInput:mCaptureAudioDeviceInput error:&error]; |
if (!success) |
{ |
// Handle error |
goto bail; |
} |
} |
} |
// Create the movie file output and add it to the session |
mCaptureMovieFileOutput = [[QTCaptureMovieFileOutput alloc] init]; |
success = [mCaptureSession addOutput:mCaptureMovieFileOutput error:&error]; |
if (!success) |
{ |
// Handle error |
goto bail; |
} |
// Set the QTCaptureFileOutput delegate so our QTCaptureFileOutputDelegate routine |
// didFinishRecordingToOutputFileAtURL will get called during recording. |
// Note: |
// You must also go into Interface Builder and connect the delegate outlet of the |
// QTCaptureView to File's Owner. |
[mCaptureMovieFileOutput setDelegate:self]; |
// Associate the capture view in the UI with the session |
[mCaptureView setCaptureSession:mCaptureSession]; |
// Start capturing! |
[mCaptureSession startRunning]; |
} |
return; /* QTCapture initialization was a success! */ |
} |
bail: /* error! */ |
; |
} |
/* stop capturing, and remove all device inputs/outputs */ |
-(void)captureDelete |
{ |
PDEBUG(); |
/* stop capturing */ |
[mCaptureSession stopRunning]; |
/* remove video device inputs */ |
if ([[mCaptureVideoDeviceInput device] isOpen]) |
{ |
[[mCaptureVideoDeviceInput device] close]; |
[mCaptureSession removeInput:mCaptureVideoDeviceInput]; |
[mCaptureVideoDeviceInput release]; |
mCaptureVideoDeviceInput = nil; |
} |
/* remove audio device inputs */ |
if ([[mCaptureAudioDeviceInput device] isOpen]) |
{ |
[[mCaptureAudioDeviceInput device] close]; |
[mCaptureSession removeInput:mCaptureAudioDeviceInput]; |
[mCaptureAudioDeviceInput release]; |
mCaptureAudioDeviceInput = nil; |
} |
/* remove file outputs */ |
if (mCaptureMovieFileOutput) |
{ |
[mCaptureMovieFileOutput setDelegate:nil]; |
[mCaptureSession removeOutput:mCaptureMovieFileOutput]; |
[mCaptureMovieFileOutput release]; |
mCaptureMovieFileOutput = nil; |
} |
} |
/* start capturing */ |
-(void)startCapture |
{ |
if ([mCaptureSession isRunning] == NO) |
{ |
if (([[mCaptureVideoDeviceInput device] isOpen] == YES) && ([[mCaptureAudioDeviceInput device] isOpen] == YES)) |
{ |
[mCaptureSession startRunning]; |
} |
} |
} |
/* stop capturing */ |
-(void)stopCapture |
{ |
if ([mCaptureSession isRunning] == YES) |
{ |
[mCaptureSession stopRunning]; |
} |
} |
#pragma mark Devices |
/* called by QTCapture when a device is connected */ |
-(void)deviceWasConnected:(NSNotification *)notification |
{ |
PDEBUG(); |
[mNotificationObject performSelector:(SEL)mNotificationTarget withObject:MyCaptureViewConnected]; |
// begin capturing again if we are not currently doing so |
if ([mCaptureSession isRunning] == NO) |
{ |
[self captureInit]; |
} |
} |
/* called by QTCapture when a device is disconnected */ |
-(void)deviceWasDisconnected:(NSNotification *)notification |
{ |
PDEBUG(); |
[mNotificationObject performSelector:(SEL)mNotificationTarget withObject:MyCaptureViewDisconnected]; |
// tear down our current capture session if the device we were using for capture has been disconnected |
if ([mCaptureSession isRunning] == YES) |
{ |
if (([[mCaptureVideoDeviceInput device] isOpen] == NO)|| ([[mCaptureAudioDeviceInput device] isOpen] == NO)) |
{ |
[self captureDelete]; |
} |
} |
} |
#pragma mark Recording |
// Add these start and stop recording actions, and specify the output destination for your recorded media. The output is a QuickTime movie. |
- (void)startRecord |
{ |
PDEBUG(); |
[mCaptureMovieFileOutput recordToOutputFileURL:[NSURL fileURLWithPath:@"/Users/Shared/My Recorded Movie.mov"]]; |
} |
- (void)stopRecord |
{ |
PDEBUG(); |
[mCaptureMovieFileOutput recordToOutputFileURL:nil]; |
} |
#pragma mark QTCapture Delegates |
/* QTCapture Delegates */ |
/* Delegate called by QTCapture when recording starts */ |
- (void)captureOutput:(QTCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL forConnections:(NSArray *)connections |
{ |
PDEBUG(); |
// Call JavaScript to specify that recording has started |
[mNotificationObject performSelectorOnMainThread:(SEL)mNotificationTarget withObject:MyCaptureViewRecording waitUntilDone:NO]; |
} |
/* Delegate called by QTCapture when recording to the output file is finished. */ |
- (void)captureOutput:(QTCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL forConnections:(NSArray *)connections dueToError:(NSError *)error |
{ |
PDEBUG(); |
// Call JavaScript to specify that recording has finished |
[mNotificationObject performSelectorOnMainThread:(SEL)mNotificationTarget withObject:MyCaptureViewFinishedRecording waitUntilDone:NO]; |
// Open the newly recorded file (/Users/Shared/My Recorded Movie.mov) |
[[NSWorkspace sharedWorkspace] openURL:outputFileURL]; |
} |
@end |
Copyright © 2007 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2007-08-27