2

OpenGL アプリケーションでビデオを無期限に再生する必要があります (終了時にビデオを再開する)。そのためにAVファンデーションを活用しようと思っています。AVAssetReader と AVAssetReaderTrackOutput を作成し、copyNextSampleBuffer メソッドを使用して CMSampleBufferRef を取得し、各フレームの OpenGL テクスチャを作成します。

    NSString *path = [[NSBundle mainBundle] pathForResource:videoFileName ofType:type];
    _url = [NSURL fileURLWithPath:path];

    //Create the AVAsset 
    _asset = [AVURLAsset assetWithURL:_url];

    //Get the asset AVAssetTrack
    NSArray *arrayAssetTrack = [_asset tracksWithMediaType:AVMediaTypeVideo];
    _assetTrackVideo = [arrayAssetTrack objectAtIndex:0];

    //create the AVAssetReaderTrackOutput
    NSDictionary *dictCompressionProperty = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:kCVPixelFormatType_32BGRA] forKey:(id) kCVPixelBufferPixelFormatTypeKey];
    _trackOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:_assetTrackVideo outputSettings:dictCompressionProperty];

    //Create the AVAssetReader
    NSError *error;
    _assetReader = [[AVAssetReader alloc] initWithAsset:_asset error:&error];
    if(error){
        NSLog(@"error in AssetReader %@", error);
    }
    [_assetReader addOutput:_trackOutput];
    //_assetReader.timeRange = CMTimeRangeMake(kCMTimeZero, _asset.duration);

    //Asset reading start reading
    [_assetReader startReading];

そして、GLKViewController の -update メソッドで、次のように呼び出します。

if (_assetReader.status == AVAssetReaderStatusReading){
    if (_trackOutput) {
        CMSampleBufferRef sampleBuffer = [_trackOutput copyNextSampleBuffer];
        [self createNewTextureVideoFromOutputSampleBuffer:sampleBuffer]; //create the new texture
    }
}else if (_assetReader.status == AVAssetReaderStatusCompleted) {
    NSLog(@"restart");
    [_assetReader startReading];
}

AVAssetReader が読み取り状態になるまではすべて正常に動作しますが、読み取りが終了し、新しい呼び出し [_assetReader startReading] で AVAssetReading を再起動しようとすると、出力なしでアプリケーションがクラッシュします。私が間違っていることは何ですか?読み取りが完了したら AVAssetReading を再開するのは正しいですか?

4

2 に答える 2

4

AVAssetReaderシークまたは再起動をサポートしていません。これは本質的にシーケンシャル デコーダーです。AVAssetReader同じサンプルを再度読み取るには、新しいオブジェクトを作成する必要があります。

于 2013-06-11T11:12:08.827 に答える
1

ありがとうコスティーク!あなたの提案は私を問題に戻します。最後に、新しい AVAssetReader を作成して読み取りを再開しました。ただし、これを行うには、新しい AVAssetReaderTrackOutput を作成して新しい AVAssetReader に追加する必要があることに注意しました。

[newAssetReader addOutput:newTrackOutput]; 
于 2013-06-13T16:19:49.687 に答える