2011-12-15 183 views
0

我使用AVfoudnation錄製了音頻/視頻。在開始捕捉視頻/音頻之前,我需要使用系統聲音播放聲音。這是第一次正常工作,但當我第二次嘗試時,系統奧迪不玩。我的猜測是AVfoundation中的某些內容沒有正確發佈。捕捉音頻/視頻後無法播放系統聲音

在我的應用程序deletage,我有這樣的代碼中的applicationDidFinishLaunching方法:

VKRSAppSoundPlayer *aPlayer = [[VKRSAppSoundPlayer alloc] init]; 
[aPlayer addSoundWithFilename:@"sound1" andExtension:@"caf"]; 
self.appSoundPlayer = aPlayer; 
[aPlayer release]; 

而且這種方法

- (void)playSound:(NSString *)sound 
{ 
    [appSoundPlayer playSound:sound]; 
} 

正如你可以看到我使用VKRSAppSoundPlayer,它的偉大工程!

在視圖中,我有這樣的代碼:

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

    [session beginConfiguration]; 
    if([session canSetSessionPreset:AVCaptureSessionPreset640x480]) 
     session.sessionPreset = AVCaptureSessionPresetMedium; 

    [session commitConfiguration]; 


    CALayer *viewLayer = [videoPreviewView layer]; 

    AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session]; 

    captureVideoPreviewLayer.frame = viewLayer.bounds; 

    [viewLayer addSublayer:captureVideoPreviewLayer]; 

    self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:[self frontFacingCameraIfAvailable] error:nil]; 
    self.audioInput = [AVCaptureDeviceInput deviceInputWithDevice:[self audioDevice] error:nil]; 

    if(videoInput){ 
     self.videoOutput = [[AVCaptureMovieFileOutput alloc] init]; 

     [session addOutput:videoOutput]; 
     //[videoOutput release]; 

     if([session canAddInput:videoInput]){ 
      //[session beginConfiguration]; 
      [session addInput:videoInput]; 

     } 
     //[videoInput release]; 

     [session removeInput:[self audioInput]]; 
     if([session canAddInput:audioInput]){ 
      [session addInput:audioInput]; 
     } 
     //[audioInput release]; 


     if([session canAddInput:audioInput]) 
      [session addInput:audioInput]; 


     NSLog(@"startRunning!"); 
     [session startRunning]; 

     [self startRecording]; 


     if(![self recordsVideo]) 
      [self showAlertWithTitle:@"Video Recording Unavailable" msg:@"This device can't record video."]; 

    } 
} 

- (void) stopSession 
{ 
    [session stopRunning]; 
    [session release]; 
} 


- (AVCaptureDevice *)frontFacingCameraIfAvailable 
{ 
    NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDevice *captureDevice = nil; 

    Boolean cameraFound = false; 

    for (AVCaptureDevice *device in videoDevices) 
    { 
     NSLog(@"1 frontFacingCameraIfAvailable %d", device.position); 
     if (device.position == AVCaptureDevicePositionBack){ 
      NSLog(@"1 frontFacingCameraIfAvailable FOUND"); 

      captureDevice = device; 
      cameraFound = true; 
      break; 
     } 
    } 

    if(cameraFound == false){ 
     for (AVCaptureDevice *device in videoDevices) 
     { 
      NSLog(@"2 frontFacingCameraIfAvailable %d", device.position); 
      if (device.position == AVCaptureDevicePositionFront){ 
       NSLog(@"2 frontFacingCameraIfAvailable FOUND"); 

       captureDevice = device; 
       break; 
      } 
     } 
    } 

    return captureDevice; 
} 

- (AVCaptureDevice *) audioDevice 
{ 
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio]; 
    if ([devices count] > 0) { 
     return [devices objectAtIndex:0]; 
    } 
    return nil; 
} 

- (void) startRecording 
{ 
#if _Multitasking_ 
    if ([[UIDevice currentDevice] isMultitaskingSupported]) { 
     [self setBackgroundRecordingID:[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}]]; 
    } 
#endif 

    [videoOutput startRecordingToOutputFileURL:[self generatenewVideoPath] 
          recordingDelegate:self]; 
} 

- (void) stopRecording 
{ 
    [videoOutput stopRecording]; 

} 

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput 
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL 
     fromConnections:(NSArray *)connections error:(NSError *)error 
{ 
    NSFileManager *man = [[NSFileManager alloc] init]; 
    NSDictionary *attrs = [man attributesOfItemAtPath: [outputFileURL path] error: NULL]; 
    NSString *fileSize = [NSString stringWithFormat:@"%llu", [attrs fileSize]]; 


    // close this screen 
    [self exitScreen]; 
} 

-(BOOL)recordsVideo 
{ 
    AVCaptureConnection *videoConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo 
                    fromConnections:[videoOutput connections]]; 
    return [videoConnection isActive]; 
} 

-(BOOL)recordsAudio 
{ 
    AVCaptureConnection *audioConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeAudio 
                    fromConnections:[videoOutput connections]]; 
    return [audioConnection isActive]; 
} 

如果我[videoInput釋放];和[audioInput發佈];我收到了錯誤的訪問錯誤。這就是爲什麼他們被評論。這可能是問題的一部分。

如果我嘗試播放系統聲音n次,它會奏效,但是如果我先錄製腳本,那麼在此之後就不會起作用。

任何想法?

+0

你需要更好地理解self.iVar意味着什麼,以及什麼意味着什麼。釋放遞減保留計數,如果0使對象有資格取消分配。使用self.iVar(假設你已經聲明它是一個屬性)保留了這個iVar,所以你可以在那之後發佈它。但我不認爲這是你的音頻問題。 – Rayfleck 2011-12-15 17:50:30

回答

0

釋放AVCaptureSession正確的方法是:

- (void) destroySession { 

    // Notify the view that the session will end 
    if ([delegate respondsToSelector:@selector(captureManagerSessionWillEnd:)]) { 
     [delegate captureManagerSessionWillEnd:self]; 
    } 

    // remove the device inputs 
    [session removeInput:[self videoInput]]; 
    [session removeInput:[self audioInput]]; 

    // release 
    [session release]; 

    // remove AVCamRecorder 
    [recorder release]; 

    // Notify the view that the session has ended 
    if ([delegate respondsToSelector:@selector(captureManagerSessionEnded:)]) { 
     [delegate captureManagerSessionEnded:self]; 
    } 
} 

如果您有某種形式的釋放問題(壞的訪問),我可以建議採取你的代碼了當前的「混亂」項目到其他一些新項目並在那裏調試問題。

當我遇到類似的問題時,我只是這樣做了。我在Github上分享了它,你可能會發現這個項目很有用:AVCam-CameraReleaseTest