2

次のコードを使用して、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」ファイルに次のように記録します。

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];

そして、再生が押されると、私は映画ファイルを次のように再生します:

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];

私はしばらくこれにいて、それを理解することができません、それは本当に非常にランダムです。どんな助けでも大歓迎です!

編集:movie.movファイルがすでに存在する場合は、新しい記録を開始する前に削除します。

EDIT2:この行と関係がある可能性があります: [movieOutput startRecordingToOutputFileURL:pathUrl recordingDelegate:self]; Xcodeは、この行に「互換性のないタイプ'id'のパラメーターにViewController*const_strong'を送信しています」という警告を表示します

EDIT3:問題は解決しました。まもなく回答を投稿します。ありがとう!

4

4 に答える 4

6

私はそれを理解したと思います:

AVCaptureMovieFileOutput クラスには、movieFragmentInterval 変数があり、デフォルトは 10 です。したがって、10 秒ごとに「サンプル テーブル」が QuickTime ファイルに書き込まれます。サンプル テーブルがないと、ファイルを読み取ることができません。

これをテストしたところ、すべての記録がかなり短かったため、サンプル テーブルがファイルに書き出されなかったときにバグが発生したようです。[movieOutput stopRecording] を呼び出したときにサンプル テーブルが書き出されると思っていたので、これは奇妙です。fragmentInterval を 5 秒に下げると、次のようになります。

CMTime fragmentInterval = CMTimeMake(5,1);

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

バグは消えたようです。ただし、マイクが入力デバイスとして追加されたときにのみエラーが発生した理由はまだわかりません.

于 2012-05-11T07:48:23.537 に答える
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];
于 2012-05-10T23:13:30.587 に答える
0

繰り返しの回答ですが、これを追加して、私のようなiosを使い始める人を助けるために、KCMTimeInvalidを試しましたが、うまくいきませんでした。1 時間後、私は startRecordingToOutputFileURL を呼び出した後に movieFragmentInterval を設定していることに気付きました。

したがって、私のようにやみくもにタイプする初心者の場合、論理的で非常に明白な順序を念頭に置いてください。

videoFileOutput.movieFragmentInterval = kCMTimeInvalid
videoFileOutput.startRecordingToOutputFileURL(filePath, recordingDelegate: recordingDelegate)
于 2016-06-26T09:11:05.983 に答える