录制的视频有时显示,有时不显示

Recorded video sometimes displaying, sometimes not

我有一个视图控制器,它记录用户的(正面)视频。使用以下代码:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *basePath = [paths objectAtIndex:0];
NSString *outputPath = [[NSString alloc] initWithFormat:@"%@", [basePath stringByAppendingPathComponent:@"output.mp4"]];
if ([[NSFileManager defaultManager] isDeletableFileAtPath:outputPath])
    [[NSFileManager defaultManager] removeItemAtPath:outputPath error:NULL];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
[movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];
self.outputURL = outputURL;

其中 movieFileOutput 是一个 AVCaptureMovieFileOutput 对象。我可以向您展示相机 configuration/setup 代码(这不是图像选择器控制器或任何 Apple UI;这会在用户与完全不同的屏幕交互时在后台拍摄用户)但总的来说,我知道它有效。

之后,调用 [movieFileOutput stopRecording];,用户被导航到一个新屏幕,播放刚刚发生的录音。我将 outputURL 对象传递给这个 新初始化的 视图控制器,其中 VC 使用以下代码播放它:

self.player = [[MPMoviePlayerController alloc] initWithContentURL:self.outputURL];
self.player.view.frame = CGRectMake(0, 0, self.view.frame.size.width, 320);
self.player.movieSourceType = MPMovieSourceTypeFile;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlaybackComplete:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.player];
self.player.controlStyle = MPMovieControlStyleNone;
self.player.shouldAutoplay = YES;
[self.player setFullscreen:YES animated:NO];
[self.player prepareToPlay];
[self.view addSubview:[self.player view]];
[self.player play];

所以,第一次,一切正常。该应用程序录制视频,然后显示下一个屏幕,并显示视频。但是,如果您单击 "Discard" 按钮,它会一直返回到应用程序的开始,然后再次执行整个过程,它会 not 起作用,而不是播放器显示黑屏。话虽如此,我打印出路径上的数据长度,它 总是 一个很大的数字(因此该路径上存在一些东西)。

奇怪的是,我决定像这样打印 NSData 对象本身:

NSLog(@"%@", [NSData dataWithContentsOfURL:self.outputURL]);

并且确实打印了一个非常大的字符串(也许是字节?不确定)。 然而,出于某种原因,现在一切正常...当我添加这个 NSLog() 时,错误不再出现。当我删除它时,它再次出现!我已经严格.

测试了这个

但仍然有一些奇怪的时间包含这个 NSLog() 播放 3 次后黑屏。我很困惑为什么会出现这个错误,以及在地球上包含 NSLog() 会如何改变任何行为。

有什么想法吗?

我的猜测是您需要等待文件被保存。

AVCaptureFileOutput 的文档说:

When recording is stopped either by calling this method, by changing files using startRecordingToOutputFileURL:recordingDelegate:, or because of an error, the remaining data that needs to be included to the file will be written in the background. Therefore, before using the file, you must wait until the delegate that was specified in startRecordingToOutputFileURL:recordingDelegate: is notified when all data has been written to the file using the captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error: method.