2012-09-20 56 views
1

我有一個iOS應用程序,在後臺記錄前置攝像頭的視頻,工作正常。但是現在我正嘗試同時播放一段短暫的mp4,並且使用MPMoviePlayerController進行播放會停止捕獲會話。播放電影停止avcapturesession錄音

我試着用AVPlayer代替了相同的結果。 我還設置了[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 仍然沒有運氣。有沒有人面臨和解決同樣的問題。 感謝您的任何建議。

使用ios5 SDK。

#import "ViewController.h" 

@interface ViewController() 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    UIButton *recButton=[[UIButton alloc] initWithFrame:CGRectMake(10,200, 200,40)] ; 
    recButton.backgroundColor = [UIColor blackColor]; 
    [recButton addTarget:self action:@selector(startRecording) forControlEvents:UIControlEventTouchUpInside]; 
    [self.view addSubview:recButton]; 
    isRecording=NO; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
} 

-(void) viewWillAppear:(BOOL)animated 
{ 
    self.navigationController.navigationBarHidden = YES; 
} 

-(void) viewWillDisappear:(BOOL)animated 
{ 
     self.navigationController.navigationBarHidden = NO; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 
     return (interfaceOrientation == UIInterfaceOrientationPortrait); 
    } else { 
     return YES; 
    } 
} 

#pragma mark video playing 
-(void) startRecording 
{ 
    if (isRecording) { 
     [self stopVideoRecording]; 
     isRecording=NO; 
    } 
    else 
    { 
     [self initCaptureSession]; 
     [self startVideoRecording]; 
     isRecording=YES; 
    } 


    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] 
             pathForResource:@"new" 
             ofType:@"mov"]]; 
    [self playMovieAtURL:url]; 
} 

-(void) playMovieAtURL: (NSURL*) theURL { 

    player = 
    [[MPMoviePlayerController alloc] initWithContentURL: theURL ]; 
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; 

    player.scalingMode = MPMovieScalingModeAspectFill; 
    player.controlStyle = MPMovieControlStyleNone; 
    [player prepareToPlay]; 
    // Register for the playback finished notification 
    [[NSNotificationCenter defaultCenter] 
    addObserver: self 
    selector: @selector(myMovieFinishedCallback:) 
    name: MPMoviePlayerPlaybackDidFinishNotification 
    object: player]; 
    [player.view setFrame: self.view.bounds]; 
    [self.view addSubview:player.view]; 
    // Movie playback is asynchronous, so this method returns immediately. 
    [player play]; 
} 

// When the movie is done, release the controller. 
-(void) myMovieFinishedCallback: (NSNotification*) aNotification 
{ 
    MPMoviePlayerController* theMovie = [aNotification object]; 

    [[NSNotificationCenter defaultCenter] 
    removeObserver: self 
    name: MPMoviePlayerPlaybackDidFinishNotification 
    object: theMovie]; 
    [player.view removeFromSuperview]; 
    [self stopVideoRecording]; 
} 

#pragma mark - 

#pragma mark recording 

-(void) initCaptureSession 
{ 
    NSLog(@"Setting up capture session"); 
    captureSession = [[AVCaptureSession alloc] init]; 
    //----- ADD INPUTS ----- 
    NSLog(@"Adding video input"); 

    //ADD VIDEO INPUT 
    AVCaptureDevice *VideoDevice = [self frontFacingCameraIfAvailable ]; 

    //[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    if (VideoDevice) 
    { 
     NSError *error; 
     videoInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:VideoDevice error:&error]; 
     if (!error) 
     { 
      if ([captureSession canAddInput:videoInputDevice]) 
       [captureSession addInput:videoInputDevice]; 
      else 
       NSLog(@"Couldn't add video input"); 
     } 
     else 
     { 
      NSLog(@"Couldn't create video input"); 
     } 
    } 
    else 
    { 
     NSLog(@"Couldn't create video capture device"); 
    } 

    //ADD AUDIO INPUT 
    NSLog(@"Adding audio input"); 
    AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; 
    NSError *error = nil; 
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error]; 
    if (audioInput) 
    { 

     [captureSession addInput:audioInput]; 
    } 

    //----- ADD OUTPUTS --- 
    //ADD MOVIE FILE OUTPUT 
    NSLog(@"Adding movie file output"); 
    movieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; 

// Float64 TotalSeconds = 60;   //Total seconds 
// int32_t preferredTimeScale = 30; //Frames per second 
// CMTime maxDuration = CMTimeMakeWithSeconds(TotalSeconds, preferredTimeScale); //<<SET MAX DURATION 
// movieFileOutput.maxRecordedDuration = maxDuration; 

    movieFileOutput.minFreeDiskSpaceLimit = 1024 * 1024; //<<SET MIN FREE SPACE IN BYTES FOR RECORDING TO CONTINUE ON A VOLUME 

    if ([captureSession canAddOutput:movieFileOutput]) 
     [captureSession addOutput:movieFileOutput]; 

    //SET THE CONNECTION PROPERTIES (output properties) 
    [self CameraSetOutputProperties];   //(We call a method as it also has to be done after changing camera) 

    //----- SET THE IMAGE QUALITY/RESOLUTION ----- 
    //Options: 
    // AVCaptureSessionPresetHigh - Highest recording quality (varies per device) 
    // AVCaptureSessionPresetMedium - Suitable for WiFi sharing (actual values may change) 
    // AVCaptureSessionPresetLow - Suitable for 3G sharing (actual values may change) 
    // AVCaptureSessionPreset640x480 - 640x480 VGA (check its supported before setting it) 
    // AVCaptureSessionPreset1280x720 - 1280x720 720p HD (check its supported before setting it) 
    // AVCaptureSessionPresetPhoto - Full photo resolution (not supported for video output) 
    NSLog(@"Setting image quality"); 
    [captureSession setSessionPreset:AVCaptureSessionPresetMedium]; 
    if ([captureSession canSetSessionPreset:AVCaptureSessionPreset640x480])  //Check size based configs are supported before setting them 
     [captureSession setSessionPreset:AVCaptureSessionPreset640x480]; 
    //----- START THE CAPTURE SESSION RUNNING ----- 
    [captureSession startRunning]; 
} 

//********** CAMERA SET OUTPUT PROPERTIES ********** 
- (void) CameraSetOutputProperties 
{ 
    AVCaptureConnection *CaptureConnection=nil; 
    //SET THE CONNECTION PROPERTIES (output properties) 
    NSComparisonResult order = [[UIDevice currentDevice].systemVersion compare: @"5.0.0" options: NSNumericSearch]; 
    if (order == NSOrderedSame || order == NSOrderedDescending) { 
     // OS version >= 5.0.0 
     CaptureConnection = [movieFileOutput connectionWithMediaType:AVMediaTypeVideo]; 
//  if (CaptureConnection.supportsVideoMinFrameDuration) 
//   CaptureConnection.videoMinFrameDuration = CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND); 
//  if (CaptureConnection.supportsVideoMaxFrameDuration) 
//   CaptureConnection.videoMaxFrameDuration = CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND); 
//  if (CaptureConnection.supportsVideoMinFrameDuration) 
//  { 
//   // CMTimeShow(CaptureConnection.videoMinFrameDuration); 
//   // CMTimeShow(CaptureConnection.videoMaxFrameDuration); 
//  } 
    } else { 
     // OS version < 5.0.0 
     CaptureConnection = [self connectionWithMediaType:AVMediaTypeVideo fromConnections:[movieFileOutput connections]]; 

    } 


    //Set landscape (if required) 
    if ([CaptureConnection isVideoOrientationSupported]) 
    { 
     AVCaptureVideoOrientation orientation = AVCaptureVideoOrientationPortrait;// AVCaptureVideoOrientationLandscapeRight;  //<<<<<SET VIDEO ORIENTATION IF LANDSCAPE 
     [CaptureConnection setVideoOrientation:orientation]; 
    } 

    //Set frame rate (if requried) 
    //CMTimeShow(CaptureConnection.videoMinFrameDuration); 
    //CMTimeShow(CaptureConnection.videoMaxFrameDuration); 


} 
- (void) startVideoRecording 
{ 
     //Create temporary URL to record to 
     NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mov"]; 
     NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath]; 
     NSFileManager *fileManager = [NSFileManager defaultManager]; 
     if ([fileManager fileExistsAtPath:outputPath]) 
     { 
      NSError *error; 
      if ([fileManager removeItemAtPath:outputPath error:&error] == NO) 
      { 
       //Error - handle if requried 
       NSLog(@"file remove error"); 
      } 
     } 
     //Start recording 
     [movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self]; 

} 

-(void) stopVideoRecording 
{ 
    [movieFileOutput stopRecording]; 

} 
//********** DID FINISH RECORDING TO OUTPUT FILE AT URL **********/ 
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput 
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL 
     fromConnections:(NSArray *)connections 
       error:(NSError *)error 
{ 

    NSLog(@"didFinishRecordingToOutputFileAtURL - enter"); 

    BOOL RecordedSuccessfully = YES; 
    if ([error code] != noErr) 
    { 
     // A problem occurred: Find out if the recording was successful. 
     id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey]; 
     if (value) 
     { 
      RecordedSuccessfully = [value boolValue]; 
     } 
    } 
    if (RecordedSuccessfully) 
    { 
     //----- RECORDED SUCESSFULLY ----- 
     NSLog(@"didFinishRecordingToOutputFileAtURL - success"); 
     ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init]; 
     if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputFileURL]) 
     { 
      [library writeVideoAtPathToSavedPhotosAlbum:outputFileURL 
             completionBlock:^(NSURL *assetURL, NSError *error) 
      { 
       if (error) 
       { 
        NSLog(@"File save error"); 
       } 
       else 
       { 
        recordedVideoURL=assetURL; 
       } 
      }]; 
     } 
     else { 

      NSString *assetURL=[self copyFileToDocuments:outputFileURL]; 
      if(assetURL!=nil) 
      { 
       recordedVideoURL=[NSURL URLWithString:assetURL]; 
      } 
     } 
    } 
} 

- (NSString*) copyFileToDocuments:(NSURL *)fileURL 
{ 
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    [dateFormatter setDateFormat:@"yyyy-MM-dd_HH-mm-ss"]; 
    NSString *destinationPath = [documentsDirectory stringByAppendingFormat:@"/output_%@.mov", [dateFormatter stringFromDate:[NSDate date]]]; 
    NSError *error; 
    if (![[NSFileManager defaultManager] copyItemAtURL:fileURL toURL:[NSURL fileURLWithPath:destinationPath] error:&error]) { 
     NSLog(@"File save error %@", [error localizedDescription]); 
     return nil; 

    } 
    return destinationPath; 
} 

- (AVCaptureConnection *)connectionWithMediaType:(NSString *)mediaType fromConnections:(NSArray *)connections 
{ 
    for (AVCaptureConnection *connection in connections) { 
     for (AVCaptureInputPort *port in [connection inputPorts]) { 
      if ([[port mediaType] isEqual:mediaType]) { 
       return connection; 
      } 
     } 
    } 
    return nil; 
} 

- (AVCaptureDevice *)frontFacingCameraIfAvailable 
{ 
    // look at all the video devices and get the first one that's on the front 
    NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; 
    AVCaptureDevice *captureDevice = nil; 
    for (AVCaptureDevice *device in videoDevices) 
    { 
     if (device.position == AVCaptureDevicePositionFront) 
     { 
      captureDevice = device; 
      break; 
     } 
    } 

    // couldn't find one on the front, so just get the default video device. 
    if (! captureDevice) 
    { 
     captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    } 

    return captureDevice; 
} 
#pragma mark - 

@end 

回答

0

我有這樣的問題太多,我不知道如何解決,但我知道問題出在這裏:

[captureSession addInput:audioInput]; 

如果刪除行的代碼,這將是工作好吧,我認爲這是音頻混合或一些音頻問題。

我仍然在找到答案。

我在這裏找到了答案:answer,它的工作!

但你還記得加AudioToolbox.framework,也許對你有幫助。