3

を使用してビデオを録画してAVCaptureMovieFileOutputいます。ただし、キャプチャしたビデオを録画時間全体にわたって保持するのではなく、最後の2分間のビデオのみを保持したいと思います。本質的に、私はビデオの末尾のバッファを作成したいと思います。

movieFragmentInterval15秒に設定してこれを実装しようとしました。これらの15秒がバッファリングされると、MOVファイルの最初の15秒は次のコードを使用してトリミングされます。

//This would be called 7 seconds after the video stream started buffering.
-(void)startTrimTimer
{
    trimTimer = [NSTimer scheduledTimerWithTimeInterval:15 target:self selector:@selector(trimFlashbackBuffer) userInfo:nil repeats:YES];
}

    -(void)trimFlashbackBuffer
    {
        //make sure that there is enough video before trimming off 15 seconds
        if(trimReadyCount<3){
            trimReadyCount++;
            return;
        }

        AVURLAsset *videoAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/flashbackBuffer.MOV",tripDirectory]] options:nil]; 

        AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:videoAsset presetName:AVAssetExportPresetHighestQuality];
        exportSession.outputURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/flashbackBuffer.MOV",tripDirectory]];
        exportSession.outputFileType = AVFileTypeQuickTimeMovie;
        CMTimeRange timeRange = CMTimeRangeMake(CMTimeMake(15000, 1000), CMTimeMake(120000, 1000));
        exportSession.timeRange = timeRange;

        [exportSession exportAsynchronouslyWithCompletionHandler:^{
            switch (exportSession.status) {
                case AVAssetExportSessionStatusCompleted:
                    // Custom method to import the Exported Video
                    [self loadAssetFromFile:exportSession.outputURL];
                    break;
                case AVAssetExportSessionStatusFailed:
                    //
                    NSLog(@"Failed:%@",exportSession.error);
                    break;
                case AVAssetExportSessionStatusCancelled:
                    //
                    NSLog(@"Canceled:%@",exportSession.error);
                    break;
                default:
                    break;
            }
        }];

    }

trimFlashbackBufferただし、が呼び出されるたびに次のエラーが発生します。

Failed:Error Domain=AVFoundationErrorDomain Code=-11823 "Cannot Save" UserInfo=0x12e710 {NSLocalizedRecoverySuggestion=Try saving again., NSLocalizedDescription=Cannot Save}

これは、ファイルがすでにによって書き込まれているためAVCaptureMovieFileOutputですか?

この方法が機能しない場合、シームレスなトレーリングビデオバッファの効果をどのように達成できますか?

ありがとう!

4

2 に答える 2

3

ここで達成しようとしていることがうまくいくかどうかはわかりません。これは、あなたが言ったように、ファイルをトリミングしようとしているときにファイルを書き込んでいるためです。なぜビデオを録画して後でトリミングできないのですか?いつでも2分間のビデオを保持したい場合は、AVCaptureVideoDataOutputを使用してみてください。これを使用すると、ビデオフレームが取得され、AVAssetWriterを使用して、フレームを圧縮してファイルに書き込むことができます。このSOを確認してください。それを行う方法について話している質問AVAssetWriterとAVAssetWriterInputsを介してビデオ+オーディオを書き込むこのコードは機能していません。なんで?

于 2011-08-23T19:07:59.047 に答える
2

エクスポートURLと同じファイルを上書きしようとしているため、エラーが発生していると思われます。ドキュメントには、「既存のファイルを上書きしようとしたり、アプリケーションのサンドボックスの外にファイルを書き込もうとすると、エクスポートが失敗します。既存のファイルを上書きする必要がある場合は、最初にファイルを削除する必要があります」と記載されています。

ビデオの最後の2分間を取得するには、別の非同期呼び出しであるloadValuesAsynchronouslyForKeysを使用して、最初にビデオの長さを取得することをお勧めします。この期間を使用して、時間範囲を作成し、別のURLにエクスポートしてビデオをトリミングできます。

CMTime start = CMTimeMakeWithSeconds(durationObtained - 120, 600); 
CMTime duration = CMTimeMakeWithSeconds(120, 600);
CMTimeRange range = CMTimeRangeMake(start, duration);  
exportSession.timeRange = range;
于 2011-09-27T07:22:15.713 に答える