2015-03-30 54 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循环后。希望这可以帮助!