gpt4 book ai didi

ios - 使用 AVMutableVideoComposition 时 AVMutableComposition 卡住的奇怪行为

转载 作者:可可西里 更新时间:2023-11-01 03:59:04 25 4
gpt4 key购买 nike

我正在尝试使用 AVMutableComposition 合并多个视频。我面临的问题是,每当我尝试添加任何 AVMutableVideoComposition 以应用任何指令时,我的播放会在 AVPlayer 中卡住,持续时间正好为 6 秒。

另一个有趣的事情是,如果我在使用相同的 videoComposition 导出后在 iPad 的照片应用程序中播放它,它会很好地播放。那么为什么它会在 6 秒时在 AVPlayer 中卡住?

代码:

AVMutableComposition *mutableComposition = [AVMutableComposition composition];

AVMutableCompositionTrack *videoCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];

AVMutableCompositionTrack *audioCompositionTrack = [mutableComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];

for (AVURLAsset *asset in assets)
{
AVAssetTrack *assetTrack;
assetTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
AVAssetTrack *audioAssetTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;


NSError *error;
[videoCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, assetTrack.timeRange.duration )
ofTrack:assetTrack
atTime:time
error:&error];

if (error) {
NSLog(@"asset url :: %@",assetTrack.asset);
NSLog(@"Error1 - %@", error.debugDescription);
}

[audioCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAssetTrack.timeRange.duration)
ofTrack:audioAssetTrack
atTime:time
error:&error];

if (error) {
NSLog(@"Error2 - %@", error.debugDescription);
}

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

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

AVMutableVideoCompositionInstruction *mainInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
AVMutableVideoCompositionLayerInstruction *videoTrackLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoCompositionTrack];

mainInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, time);
mainInstruction.layerInstructions = [NSArray arrayWithObjects:videoTrackLayerInstruction, nil];
AVMutableVideoComposition *mainCompositionInst = [AVMutableVideoComposition videoComposition];
mainCompositionInst.instructions = [NSArray arrayWithObject:mainInstruction];
mainCompositionInst.frameDuration = CMTimeMake(1, 30);
mainCompositionInst.renderSize = size;

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

另外,我知道问题主要出在 videoComposition 上,因为如果我删除 videoComposition,那么它在 AVPlayer 上可以正常播放。

更新 1:我刚刚发现当它在 6 秒后卡住时,如果我向后或向前拖动 slider (即使用 seekToTime),它会开始正常播放再次没有任何进一步的卡住。

即使视频卡住,音频也能继续正常播放。

更新 2:如果我继续使用具有相同 AVMutableCompositionAVAssetExportSession 导出它,并从导出的视频加载 Assets ,它工作正常。所以当我直接播放 AVMutableComposition 时,问题就出现了。

最佳答案

最后,我得到了解决这个问题的解决方案。

您应该在 playerItem 的状态更改为 .ReadyToPlay 后播放。

请看下面

func startVideoPlayer() {
let playerItem = AVPlayerItem(asset: self.composition!)
playerItem.videoComposition = self.videoComposition!

let player = AVPlayer(playerItem: playerItem)
player.actionAtItemEnd = .None

videoPlayerLayer = AVPlayerLayer(player: player)
videoPlayerLayer!.frame = self.bounds

/* add playerItem's observer */
player.addObserver(self, forKeyPath: "player.currentItem.status", options: .New, context: nil)

NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerItemDidReachEnd:", name: AVPlayerItemDidPlayToEndTimeNotification, object: playerItem);

self.layer.addSublayer(videoPlayerLayer!)
}

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath != nil && keyPath! == "player.currentItem.status" {
if let newValue = change?[NSKeyValueChangeNewKey] {
if AVPlayerStatus(rawValue: newValue as! Int) == .ReadyToPlay {
playVideo() /* play after status is changed to .ReadyToPlay */
}
}
} else {
super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}
}

func playerItemDidReachEnd(notification: NSNotification) {
let playerItem = notification.object as! AVPlayerItem
playerItem.seekToTime(kCMTimeZero)

playVideo()
}

func playVideo() {
videoPlayerLayer?.player!.play()
}

关于ios - 使用 AVMutableVideoComposition 时 AVMutableComposition 卡住的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31402674/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com