2016-09-17 12 views
2

나는 Cocoa 환경에 존재하지 않는 프로그램을위한 플러그인을 작성하고있다. (C++ 명령 행 프로그램을 생각해 보자.) 관심이 있다면, 이것이 v8 노드 애드온 시스템입니다. 나는 아마 그래서이 물건을 할 수있는 새로운 pthread에 시작됩니다 실제로비 코코아 응용 프로그램에서 Foundation에 전화를 걸 때 NSRunLoop이 필요합니까?

void start(/*entry*/) 
{ 
    // No run loop is *necessarily* present. 
    AVCaptureSession * session = ... 
} 

void stop (/*entry*/) 
{ 
    // etc.. 
} 

: 나는, 그래서 본질적 등, 같은 것을 화면을 기록, 따라서 AVCaptureSession의 사용을 만들기 위해이 플러그인을하고 싶습니다 그 중 어느 것도 차단하고 있지 않다는 것입니다. 내 질문은 주변 재단 인프라를 얼마나 설정해야하는지입니다. 나는 인상을하지 않을 경우 AVCapture에서 등 어떤 trickiness이 실패 할 수 있음을, 나는 거의 확실 @autoreleasepool을 {} 필요하지만, 실제로 스레드에서 실행되도록 내 자신의 기본 NSRunLoop를 시작해야합니다

BOOL isStillRecording = YES; 
void start(/*entry*/) 
{ 
    // setup avcapture and what have you. 
    NSRunLoop *theRL = [NSRunLoop new]; 
    while (isStillRecording && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]); 
} 

void stop(/**entry**/) 
{ 
    // kill avcapture, maybe through async_dispatch to not stop on the start up. 
    isStillRecording = NO; 
} 

답변

0

업데이트 사실, 나는 그것을 되 찾습니다. AVCaptureFileOutput과 같은 일부 대리인 콜백을 얻기 위해 현재 runloop을 사용해야하는 것 같습니다. 이 화면과 마이크 벌금 QuickTime 동영상을 생성합니다

#import <AVFoundation/AVFoundation.h> 

@interface Capturer() <AVCaptureFileOutputRecordingDelegate> 

@property(nonatomic) AVCaptureSession *session; 
@property(nonatomic) AVCaptureMovieFileOutput *movieOutput; 
@property(nonatomic, copy) void(^finishBlock)(NSError*); 

@end 

@implementation Capturer 
- (instancetype)init 
{ 
    self = [super init]; 
    if (self) { 
     [self setup]; 
    } 
    return self; 
} 

- (void)setup { 
    self.session = [[AVCaptureSession alloc] init]; 

    // capture the screen 
    CGDirectDisplayID displayId = CGMainDisplayID(); 
    AVCaptureScreenInput *screenInput = [[AVCaptureScreenInput alloc] initWithDisplayID:displayId]; 

    [self.session addInput:screenInput]; 

    // capture microphone input 
    AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; 
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil]; 
    [self.session addInput:audioInput]; 

    self.movieOutput = [[AVCaptureMovieFileOutput alloc] init]; 

    [self.session addOutput:self.movieOutput]; 
} 

- (void)start { 
    [self.session startRunning]; 
    NSURL *movieURL = [[NSURL fileURLWithPath:[[NSFileManager defaultManager] currentDirectoryPath]] URLByAppendingPathComponent:@"output.mov"]; 
    [[NSFileManager defaultManager] removeItemAtURL:movieURL error:nil]; 
    NSLog(@"recording to %@", movieURL.path); 
    [self.movieOutput startRecordingToOutputFileURL:movieURL recordingDelegate:self]; 
} 

- (void)stop:(void (^)(NSError *))finishBlock { 
    self.finishBlock = finishBlock; 
    [self.movieOutput stopRecording]; 
} 

// MARK: AVCaptureFileOutputRecordingDelegate 
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error { 
    NSLog(@"Finished recording to %@ with error %@", outputFileURL.path, error); 
    [self.session stopRunning]; 
    self.finishBlock(error); 
} 

@end 


int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     Capturer *c = [[Capturer alloc] init]; 
     NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 

     [c start]; 

     // record 10s' worth 
     __block BOOL finished = NO; 
     [c performSelector:@selector(stop:) withObject:^(NSError *error) { 
      finished = YES; 
     } afterDelay:10]; 

     // cribbed from https://gist.github.com/syzdek/3220789 
     while(!finished && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:2]]) NSLog(@"waiting"); 

    } 
    return 0; 
} 

이전

내가 명령 줄 응용 프로그램에서 AVFoundation을 사용했습니다 내가 NSRunLoop 필요하지 않았다. 내가 만들

  1. 에 필요] @autoreleasepool (당신이 말한대로) AVFoundation
  2. 매우 비동기 처리가 완료되기 전에 내가 출구를하지 않았다 확인하기 위해 세마포어를 사용합니다.