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 doesn't support seeking or restarting, it is essentially a sequential decoder. You have to create a new AVAssetReader object to read the same samples again.

于 2013-06-11T11:12:08.827 回答
1

Thanks Costique! Your suggestion brings me back on the problem. I finally restarted the reading by creating a new AVAssetReader. However in order to do that I noted that a new AVAssetReaderTrackOutput must be created and added to the new AVAssetReader e.g.

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