AVCaptureSession中音频无法录制

7
我有一个应用程序,当加载视图时,开始捕获视频和音频,并在完成后将其记录到该应用程序的文档文件夹以及运行它的iPad的相机胶卷中。我已确保为会话添加了音频和视频的输入,但是当我查看保存的视频时,其中没有音频。是否有人能在我的代码中找到任何问题呢?
更新:从未显示任何错误消息。但是,我找到了一个共同点。如果录制时间超过10秒,音频就不会记录。NSLog显示:
“Finished with error: (null)”
-(void)viewWillAppear:(BOOL)animated {
    NSDate *today = [NSDate date];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"MMM d hh:mm:ss a"];
    // display in 12HR/24HR (i.e. 11:25PM or 23:25) format according to User Settings
    NSString *currentTime = [dateFormatter stringFromDate:today];
    NSError* error4 = nil;
    AVAudioSession* audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryAmbient error:&error4];
    OSStatus propertySetError = 0;
    UInt32 allowMixing = true;
    propertySetError |= AudioSessionSetProperty(kAudioSessionProperty_OtherMixableAudioShouldDuck, sizeof(allowMixing), &allowMixing);

    // Activate the audio session
    error4 = nil;
    if (![audioSession setActive:YES error:&error4]) {
        NSLog(@"AVAudioSession setActive:YES failed: %@", [error4 localizedDescription]);
    }
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectoryPath = [paths objectAtIndex:0];

    session = [[AVCaptureSession alloc] init];
    [session beginConfiguration];
    session.sessionPreset = AVCaptureSessionPresetMedium;
    self.navigationController.navigationBarHidden = YES;

    NSError *error = nil;

    AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    NSError *error2 = nil;
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error2];


    AVCaptureDevice *device;
    AVCaptureDevicePosition desiredPosition = AVCaptureDevicePositionBack;
    // find the front facing camera

    device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];


    // get the input device
    AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];




    AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];

    NSString *archives = [documentsDirectoryPath stringByAppendingPathComponent:@"archives"];
    NSString *editedfilename = [[@"ComeOnDown" lastPathComponent] stringByDeletingPathExtension];
    NSString *datestring = [[editedfilename stringByAppendingString:@" "] stringByAppendingString:currentTime];
    NSLog(@"%@", datestring);
    NSString *outputpathofmovie = [[archives stringByAppendingPathComponent:datestring] stringByAppendingString:@".mp4"];
    NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputpathofmovie];
    [session addInput:audioInput];
    [session addInput:deviceInput];
    [session addOutput:movieFileOutput];
    [session commitConfiguration];
    [session startRunning];




    AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
    previewLayer.backgroundColor = [[UIColor blackColor] CGColor];
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    previewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;

     CALayer *rootLayer = [vImagePreview layer];
    [rootLayer setMasksToBounds:YES];
    [previewLayer setFrame:[rootLayer bounds]];
    [rootLayer addSublayer:previewLayer];

    [movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];



    //session = nil;
    if (error) {
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:
                                  [NSString stringWithFormat:@"Failed with error %d", (int)[error code]]
                                                            message:[error localizedDescription]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Dismiss"
                                                  otherButtonTitles:nil];
        [alertView show];

    }
    [super viewWillAppear:YES];

}

-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections {

}
-(void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    NSLog(@"Finished with error: %@", error);
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error {
    //finished
    NSLog(@"Finished");
    NSString *proud = [[NSString alloc] initWithString:[outputFileURL path]];
    UISaveVideoAtPathToSavedPhotosAlbum(proud, self, @selector(video:didFinishSavingWithError: contextInfo:), (__bridge void *)(proud));
}

我真的不觉得使用讽刺的必要。你分配了audioInput,但从未检查error2。考虑到audioInput是你遇到问题的地方,这不是一个合理的建议吗? - jaket
没有任何错误信息显示。然而,我发现了一个共同点。如果录制的音频只有10秒或更短,则可以录制。如果超过11秒,音频将无法录制。 - user717452
3个回答

13
答案是movieFileOutput.movieFragmentInterval = kCMTimeInvalid; 显然默认设置为10,超过此值后,音频将不会记录。参考自AVCaptureSession音频在长视频中不起作用 一旦我发现问题与时间有关,找到答案就很容易了。

谢谢回答。但这没有任何意义。 - Numan Karaaslan
哇,苹果真的这样吗?天哪,我为什么只收到10秒的音频啊。 - Yaroslav Dukal
这对我有效。谢谢。 - jogshardik

1

Swift 4.2

movieFileOutput.movieFragmentInterval = CMTime.invalid

0
videoFileOutput.movieFragmentInterval = kCMTimeInvalid 

这个问题已经为我解决了。

然而,在调用startRecordingToOutputFileURL之后,我不小心设置了movieFragmentInterval。一个痛苦的小时后,我意识到了我的错误。对于像我这样的新手,请注意这个明显的顺序。

videoFileOutput.movieFragmentInterval = kCMTimeInvalid
videoFileOutput.startRecordingToOutputFileURL(filePath, recordingDelegate: recordingDelegate)

它是做什么的?你能解释一下吗? - Yaroslav Dukal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接