2012-05-10 3 views
2

다음 코드를 사용하여 AVCaptureSession을 설정하고 비디오 파일을 녹화 한 다음 다시 재생합니다. 때로는 제대로 작동하고 재생 중에 검은 색 화면이 나타나는 경우가 있습니다. 내가 알 수있는 한 그것은 완전히 무작위이다.AVCaptureSession의 이상한 버그

버그가 발생하면 quicktime에서 파일을 열려고하면 "파일을 열 수 없습니다. 형식을 인식 할 수 없습니다"라는 메시지가 나타납니다. 이것은 내가 재생 문제가 아닌 녹음 문제를 믿게합니다.

또한 마이크 입력을 추가하는 코드 부분을 주석 처리하면 버그가 발생하지 않지만 내 비디오 파일에는 물론 오디오 트랙이 없습니다 ... 그래서 아마 오디오 피드가 임의로 손상됩니다. 어떤 이유로 파일?

- (void)viewDidLoad { 
[super viewDidLoad]; 

.... 

captureSession = [[AVCaptureSession alloc] init]; 
[captureSession setSessionPreset:AVCaptureSessionPresetHigh]; 

NSArray *devices = [AVCaptureDevice devices]; 
AVCaptureDevice *frontCamera; 
AVCaptureDevice *mic = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; 

for (AVCaptureDevice *device in devices) { 

    NSLog(@"Device name: %@", [device localizedName]); 

    if ([device hasMediaType:AVMediaTypeVideo]) 
    { 
     if ([device position] == AVCaptureDevicePositionFront) { 
      NSLog(@"Device position : front"); 
      frontCamera = device; 
     } 
    } 
} 

NSError *error = nil; 

AVCaptureDeviceInput * microphone_input = [AVCaptureDeviceInput deviceInputWithDevice:mic error:&error]; 

AVCaptureDeviceInput *frontFacingCameraDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:frontCamera error:&error]; 

if (!error) 
{ 
    if ([captureSession canAddInput:frontFacingCameraDeviceInput]) 
    { 
     [captureSession addInput:frontFacingCameraDeviceInput]; 
    } 

    if([captureSession canAddInput:microphone_input]) 
    { 
     [captureSession addInput:microphone_input]; 
    } 

} 
[captureSession startRunning]; 
} 

기록을 누르면, 내가 가진 "movie.mov"파일에 기록합니다

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
NSString *pathString = [documentsDirectory stringByAppendingPathComponent:@"movie.mov"]; 
NSURL *pathUrl = [NSURL fileURLWithPath:pathString]; 

mPlayer = [AVPlayer playerWithURL:pathUrl]; 

[self.video setPlayer:self.mPlayer]; 
[video setVideoFillMode:@"AVLayerVideoGravityResizeAspectFill"]; 
[self.mPlayer play]; 
: 재생을 누를 때

movieOutput = [[AVCaptureMovieFileOutput alloc]init]; 
[captureSession addOutput:movieOutput]; 
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
NSString *pathString = [documentsDirectory stringByAppendingPathComponent:@"movie.mov"]; 
NSURL *pathUrl = [NSURL fileURLWithPath:pathString]; 

[movieOutput startRecordingToOutputFileURL:pathUrl recordingDelegate:self]; 

그리고, 내가 가진 동영상 파일을 재생

필자는 잠시 동안 여기에 있었고 알아낼 수 없었습니다. 실제로는 매우 무작위입니다. 어떤 도움을 주셔서 감사합니다!

EDIT : movie.mov 파일이 이미있는 경우 새 녹음을 시작하기 전에 삭제합니다.

EDIT2 : 문제 해결 : [movieOutput startRecordingToOutputFileURL:pathUrl recordingDelegate:self]; 엑스 코드 나이 줄에 경고 "ID '호환되지 않는 유형의 매개 변수'의 ViewController * const_strong 보내기"

이 EDIT3에게 제공합니다 : 그것은 라인과 함께 할 수있는 뭔가가 수 곧 답변을 게시 할 예정입니다. 감사! 녹화 전에

+0

이 동작에 어떤 패턴이 있는가 - 맹목적으로 나 같은 입력 새내기 그래서

? 즉, 발사 당 처음 기록 할 때만 성공적으로 기록됩니까? 앱을 삭제 한 후 처음으로 앱을 처음 설치할 때만 성공적으로 기록됩니까? 게임을 다시 시작할 때까지 출시 당 매회 성공적으로 기록됩니까? –

+0

내가 볼 수있는 패턴이없는 것 같습니다. 그것은 시도의 약 50 %에서 발생하는 것 같습니다. 하지만 3 회 연속 시도하고 2 회 시도하지 않고 기적적으로 다시 작업합니다 (모두 앱을 다시 시작하지 않아도됩니다). – Dimitar08

답변

6

나는 그것을 알아 낸 것 같아 :

AVCaptureMovieFileOutput 클래스는 movieFragmentInterval 변수를 가지고 10에있는 기본값 10 초마다 "샘플 테이블"이 퀵타임 파일에 기록됩니다. 샘플 표가 없으면 파일을 읽을 수 없습니다.

내 녹음 내용이 모두 짧았 기 때문에 샘플 표가 파일에 쓰여지지 않을 때마다 버그가 발생한 것 같습니다. 필자가 [movieOutput stopRecording]을 호출하여 샘플 테이블을 작성할 것이라고 가정했기 때문에 이상한 점이 있지만 그 이유는 알 수 없습니다. fragmentInterval을 5 초로 낮추면 :

CMTime fragmentInterval = CMTimeMake(5,1); 

[movieOutput setMovieFragmentInterval:fragmentInterval]; 
[movieOutput startRecordingToOutputFileURL:pathUrl recordingDelegate:self]; 

버그가 사라졌습니다.여전히 마이크가 입력 장치로 추가 될 때마다 오류가 발생한 이유는 확실하지 않습니다.

+0

동영상 작성은 단편 간격을 설정하지 않고 잘 작동해야합니다. 귀하의 실제 문제는 다른 곳에 있다고 생각합니다. –

+0

동의합니다. 그것은 fragmentInterval이 그것을 고칠 것이라는 것을 이해하지 않습니다. 그것은 아마도 다른 무엇보다 반창고 솔루션입니다 ... – Dimitar08

+1

은 오늘 똑같은 것을 보았습니다. 매우 짧은 녹음의 경우에는 위임자 메소드 didStartRecordingToOutputFileAtURL이 호출되기 전에 [self.movieFileOutput stopRecording]이 호출됩니다. 그래서 해결책은 stopRecordingToOutputFileURL 다음에 멈추기 전에 didStartRecordingToOutputFileAtURL 호출을 기다리는 것이다. – Valentyn

1

콜이,

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:nil]; 

이 재생되기 전에,

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil]; 

나는 당신이 오디오를 녹음하려고하지 않는 문제가 발생하지 않습니다 고려 도움이 될 것입니다 생각합니다.

당신이 때마다 동일한 URL을 사용하고 있기 때문에, 당신은 삭제해야 그것은 첫째

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
NSString *pathString = [documentsDirectory stringByAppendingPathComponent:@"movie.mov"]; 
NSURL *pathUrl = [NSURL fileURLWithPath:pathString]; 
[[NSFileManager defaultManager] removeItemAtURL:pathUrl error:nil]; 
[movieOutput startRecordingToOutputFileURL:pathUrl recordingDelegate:self]; 
+0

3 회 연속 작업했지만 불행히도 다시 실패했습니다. – Dimitar08

+0

그리고 예, 녹음하기 전에 movie.mov 파일이 이미있는 경우 삭제합니다. – Dimitar08

+0

AVCaptureMovieFileOutput fragmentInterval 변수에 문제가있는 것처럼 보입니다. 조각을 기본 10 초에서 5 초로 낮추면 오류가 수정되었습니다. stackoverflow 내가 내 자신의 질문에 대답 할 수있을 때 나는 6 시간에 더 자세한 설명을 게시 할 것입니다. 도와 주셔서 감사합니다! – Dimitar08

1

AVCaptureMovieFileOutputfragmentInterval 속성을 더 높은 제한값으로 설정해야합니다. 기본적으로 10 초입니다.

나는 또한 비디오 녹화의 동일한 문제를 AVCaptureSession을 사용하여 10 초 이상으로 기록하지 못했습니다. 조각 간격을 최대 초인 300 초로 설정하면 비디오를 찍을 수있게되고 오디오로 녹음됩니다.

AVCaptureMovieFileOutput *aMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init]; 
CMTime fragmentInterval = CMTimeMake(300,1); 

[aMovieFileOutput setMovieFragmentInterval:fragmentInterval]; 
0

그것은 반복 대답은하지만, 누군가가 나 같은 IOS에서 시작하는 데 도움이 추가, 나는 KCMTimeInvalid을 시도했지만 그냥 나를 위해 작동하지 않았다. frazzled 한 시간 후, startRecordingToOutputFileURL을 호출 한 후 movieFragmentInterval을 설정한다는 것을 알게되었습니다. 마음에 논리적 매우 분명 순서를 유지

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