Mac OSX で Web カメラのリストを取る
iMovie がカメラを認識しない
でも、何をどう解決すればいいのかも分からない><
という訳で
色々調べながらカメラを検出するコードを書いてみた
もちろん、エラー処理はない。
#import <Cocoa/Cocoa.h> #import <QuickTime/QuickTime.h> int main(int argc, char *argv[]) { // メモリプール NSAutoreleasePool* arp = [[NSAutoreleasePool alloc] init]; // 準備 SeqGrabComponent sg = OpenDefaultComponent(SeqGrabComponentType, 0); SGInitialize(sg); SGChannel ch = nil; SGNewChannel(sg, VideoMediaType, &ch); // デバイスリストの取得 SGDeviceList list = nil; SGGetChannelDeviceList(ch, sgDeviceListIncludeInputs, &list); // リストの走査 int i; for (i = 0; i < sgDeviceListIncludeInputs; i++) { short n; SGGetChannelDeviceAndInputNames(ch, nil, nil, &n); // デバイス名の取得 SGDeviceName name = (SGDeviceName) (*list)->entry[i]; SGDeviceInputList inputs = name.inputs; char* str = (inputs == nil) ? name.name : (*inputs)->entry[n].name; // 表示 NSLog([NSString stringWithCString: str + 1 length: str[0] ]); } // 後始末 SGDisposeDeviceList(sg, list); SGDisposeChannel(sg, ch); [arp release]; return 0; }
で実行すると
ファイル名は、 hoge.m だとして
$ gcc -lobjc hoge.m -framework Cocoa -framework QuickTime $ ./a.out 2008-06-09 19:21:53.879 a.out[2933:10b] Opening shmem segment /com.allocinit.CTCtrl 2008-06-09 19:21:53.881 a.out[2933:10b] Opening shmem segment /com.allocinit.CTImg0 2008-06-09 19:21:53.882 a.out[2933:10b] Opening shmem segment /com.allocinit.CTImg1 2008-06-09 19:21:53.888 a.out[2933:10b] CamTwist 2008-06-09 19:21:53.889 a.out[2933:10b] DV Video 2008-06-09 19:21:53.898 a.out[2933:10b] IIDC FireWire Video 2008-06-09 19:21:53.906 a.out[2933:10b] Built-in iSight
おおお!
ちゃんと CamTwist とか Built-in iSight とか表示されていますね。
さて
SGGetChannelDeviceList という関数でデバイスの一覧を取得していると分かった!
でも、これが分かったところでどうすればいいんだ><!
Objective-C めも
Hello world!
#import <stdio.h> #import <objc/Object.h> @interface Test : Object - (void) msg; @end @implementation Test - (void) msg { printf("Hello world!\n"); } @end int main(int argc, char** argv) { id obj = [Test alloc]; [obj msg]; return 0; }
$ gcc hello.m -lobjc
NSString を使ってみる
#import <stdio.h> #import <objc/Object.h> #import <Foundation/NSString.h> @interface Test : Object { id name; } - (void) msg; @end @implementation Test - (void) setName:(NSString*)name_ { [name release]; name = name_; } - (void) msg { NSLog(@"Hello %@!\n", name); } @end int main(int argc, char** argv) { id obj0 = [Test alloc]; [obj0 setName:@"amachang"]; id obj1 = [Test alloc]; [obj1 setName:@"prochang"]; [obj0 msg]; [obj1 msg]; return 0; }
$ gcc hello.m -lobjc -framework Foundation
Object より NSObject のほうがいいのかな?
- Object で release を呼び出してみると warning が出た
- NSObject にしたら大丈夫だった
NSAutoreleasePool と autorelease
#import <Foundation/NSObject.h> #import <Foundation/NSAutoreleasePool.h> @interface Foo : NSObject @end @implementation Foo -(void) dealloc { NSLog(@"dealloc Foo"); [super dealloc]; } @end int main(int argc, char** argv) { id arp = [[NSAutoreleasePool alloc] init]; id obj0 = [[Foo alloc] init]; [obj0 autorelease]; id obj1 = [[Foo alloc] init]; [obj1 autorelease]; NSLog(@"release arp"); [arp release]; return 0; }
$ gcc hello.m -lobjc -framework Foundation && ./a.out 2008-04-21 17:20:03.198 a.out[30050:10b] release arp 2008-04-21 17:20:03.200 a.out[30050:10b] dealloc Foo 2008-04-21 17:20:03.201 a.out[30050:10b] dealloc Foo
ダックタイピング
#import <Foundation/NSObject.h> #import <Foundation/NSAutoreleasePool.h> @interface Foo : NSObject @end @implementation Foo -(id) msg { NSLog(@"foo"); return self; } @end @interface Bar : NSObject @end @implementation Bar -(id) msg { NSLog(@"bar"); return self; } @end int main(int argc, char** argv) { srand(time(NULL)); [[[[rand()%2 ? [Foo class] : [Bar class] alloc] init] msg] release]; return 0; }