2013-03-29 73 views
2

我需要在我的OpenGL應用程序中無限期地重現視頻(當視頻結束時重新開始視頻)。 要做到這一點,我試圖利用AV基礎。 我創建了AVAssetReader和AVAssetReaderTrackOutput,並利用copyNextSampleBuffer方法獲取CMSampleBufferRef併爲每個幀創建OpenGL紋理。AVFoundation重現視頻循環

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是在閱讀狀態但是當它讀完,我試圖重啓AVAssetReading用新的調用[_assetReader startReading],應用程序崩潰而不輸出。 我做錯了什麼?完成閱讀後重新啓動AVAssetReading是正確的嗎?

+0

更新,這裏是一個真正的工作解決方案在iOS中使用新的VideoToolbox硬件訪問API:http://stackoverflow.com/a/33335884/763355 – MoDJ

回答

4

AVAssetReader不支持尋找或重新啓動,它本質上是一個順序解碼器。您必須創建一個新的AVAssetReader對象才能再次讀取相同的樣本。

1

感謝Costique!你的建議讓我回到了這個問題上。我最終通過創建一個新的AVAssetReader重新開始閱讀。然而,爲了這樣做,我注意到必須創建一個新的AVAssetReaderTrackOutput,並將其添加到新的AVAssetReader ,例如

[newAssetReader addOutput:newTrackOutput];