2015-03-30 19 views
1

我正在合併多個視頻並在AVPlayer中播放它。視頻開頭很好,但有時視頻會凍結,只有音頻播放。我有一個UISlider,它有助於在視頻中前進或後退,使用seekToTime:AVPlayer的怪異行爲

所以奇怪的部分是,視頻凍結後,如果我使用滑塊前進或後退,視頻開始播放完全正常。我在多個設備上嘗試過我的應用程序。

所以基本上我必須使用seekToTime:方法來給視頻一個微調每次它凍結。

我對合並的視頻和播放代碼如下:

AVAsset *asset0 = [self currentAsset:0]; 
AVAsset *asset1 = [self currentAsset:1]; 
AVAsset *asset2 = [self currentAsset:2]; 
AVAsset *asset3 = [self currentAsset:3]; 
AVAsset *asset4 = [self currentAsset:4]; 

NSArray *assets = @[asset0, asset1, asset2, asset3, asset4]; 

AVMutableComposition *mutableComposition = [AVMutableComposition composition]; 
AVMutableCompositionTrack *videoCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo 
                        preferredTrackID:kCMPersistentTrackID_Invalid]; 
AVMutableCompositionTrack *audioCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio 
                        preferredTrackID:kCMPersistentTrackID_Invalid]; 

NSMutableArray *instructions = [NSMutableArray new]; 
CGSize size = CGSizeZero; 

CMTime time = kCMTimeZero; 
for (AVAsset *asset in assets) 
{ 
    AVAssetTrack *assetTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject; 
    AVAssetTrack *audioAssetTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject; 

    NSError *error; 
    [videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetTrack.timeRange.duration) 
            ofTrack:assetTrack 
            atTime:time 
            error:&error]; 
    if (error) { 
     NSLog(@"Error - %@", error.debugDescription); 
    } 

    [audioCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetTrack.timeRange.duration) 
            ofTrack:audioAssetTrack 
            atTime:time 
            error:&error]; 
    if (error) { 
     NSLog(@"Error - %@", error.debugDescription); 
    } 

    AVMutableVideoCompositionInstruction *videoCompositionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
    videoCompositionInstruction.timeRange = CMTimeRangeMake(time, assetTrack.timeRange.duration); 
    videoCompositionInstruction.layerInstructions = @[[AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack]]; 
    [instructions addObject:videoCompositionInstruction]; 

    time = CMTimeAdd(time, assetTrack.timeRange.duration); 

    if (CGSizeEqualToSize(size, CGSizeZero)) { 
     size = assetTrack.naturalSize;; 
    } 
} 

AVMutableVideoComposition *mutableVideoComposition = [AVMutableVideoComposition videoComposition]; 
mutableVideoComposition.instructions = instructions; 

mutableVideoComposition.frameDuration = CMTimeMake(1, 30); 
mutableVideoComposition.renderSize = size; 

pi = [AVPlayerItem playerItemWithAsset:mutableComposition]; 
pi.videoComposition = mutableVideoComposition; 

player = [AVPlayer playerWithPlayerItem:[[CameraEngine engine] pi]]; 

player.volume = 0.75; 
playerLayer = [AVPlayerLayer playerLayerWithPlayer: player]; 

playerLayer.frame = self.bounds; 
[self.layer addSublayer: playerLayer]; 
[playerLayer setNeedsDisplay]; 
[player play]; 

UPDATE:發現了這個link它描述了類似的問題。但他的解決方案並不完全瞭解。

+0

「但他的解決方案並不完全瞭解。」你是什​​麼意思?這似乎很清楚。你的意思是_你不明白嗎? – matt 2015-04-03 18:48:05

+0

另外,你能解釋你在做什麼AVMutableVideoCompositionInstruction? – matt 2015-04-03 18:50:28

+0

您可以在您的代碼中評論videoCompositionInstruction並嘗試相同的操作。可能是有問題的 – 2015-04-03 19:00:02

回答

0

爲什麼你打電話[AVPlayer playerWithPlayerItem:[[CameraEngine engine] pi]]而不是[AVPlayer playerWithPlayerItem:pi]?你構建你的構圖,並將其分配給pi,而不在任何地方使用。嘗試使用[AVPlayer playerWithPlayerItem:pi]來代替。

如果這不會幫助您嘗試更改您的videoComposition一代。嘗試執行以下操作:

AVMutableVideoCompositionInstruction *videoCompositionInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction]; 
videoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, mutableComposition.timeRange.duration); 
videoCompositionInstruction.layerInstructions = @[[AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:[mutableComposition tracksWithMediaType:AVMediaTypeVideo].firstObject]]; 

AVMutableVideoComposition *mutableVideoComposition = [AVMutableVideoComposition videoComposition]; 
mutableVideoComposition.instructions = @[videoCompositionInstruction]; 

mutableVideoComposition.frameDuration = CMTimeMake(1, 30); 
mutableVideoComposition.renderSize = size; 

在您的for循環後。希望這可以幫助!