Ios 使用AVMutableVideoComposition时AVMutableComposition冻结的奇怪行为
我正在尝试使用Ios 使用AVMutableVideoComposition时AVMutableComposition冻结的奇怪行为,ios,objective-c,video,avfoundation,avmutablecomposition,Ios,Objective C,Video,Avfoundation,Avmutablecomposition,我正在尝试使用AVMutableComposition合并多个视频。我面临的问题是,每当我尝试添加任何AVMutableVideoComposition以应用任何指令时,我的播放都会在AVPlayer中以精确的6秒时间冻结 另一件有趣的事情是,如果我使用相同的videoComposition导出后在iPad的Photos应用程序中播放它,它会播放得很好。那么为什么它会在AVPlayer中冻结6秒 代码: 另外,我知道问题主要是videoComposition,因为如果我删除videoCompos
AVMutableComposition
合并多个视频。我面临的问题是,每当我尝试添加任何AVMutableVideoComposition
以应用任何指令时,我的播放都会在AVPlayer
中以精确的6秒时间冻结
另一件有趣的事情是,如果我使用相同的videoComposition
导出后在iPad的Photos应用程序中播放它,它会播放得很好。那么为什么它会在AVPlayer
中冻结6秒
代码:
另外,我知道问题主要是videoComposition
,因为如果我删除videoComposition
,那么它在AVPlayer
上播放得很好
更新1:我刚刚发现,当它在6秒后冻结时,如果我将滑块向后或向前拖动(即使用seekToTime
),它将再次正常播放,而不再冻结
此外,即使视频冻结,音频仍能正常播放
更新2:如果我继续使用
AVAssetExportSession
以相同的AVMutableComposition
导出它,并从导出的视频中加载资源,它工作正常。所以,当我直接播放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()
}
func startVideoPlayer(){
让playerItem=AVPlayerItem(资产:self.composition!)
playerItem.videoComposition=self.videoComposition!
let player=AVPlayer(playerItem:playerItem)
player.actionAtItemEnd=.None
videoPlayerLayer=AVPlayerLayer(播放器:播放器)
videoPlayerLayer!.frame=self.bounds
/*添加playerItem的观察者*/
player.addObserver(self,forKeyPath:“player.currentItem.status”,选项:。新建,上下文:nil)
NSNotificationCenter.defaultCenter().addObserver(self,选择器:“PlayerItemDidReachen:”,名称:AVPlayerItemDidPlayToEndTimeNotification,对象:playerItem);
self.layer.addSublayer(videoPlayerLayer!)
}
重写func observeValueForKeyPath(键路径:String?,对象对象的类型:AnyObject?,更改:[String:AnyObject]?,上下文:UnsafeMutablePointer){
如果keyPath!=nil&&keyPath!==“player.currentItem.status”{
如果让newValue=更改?[NSKeyValueChangeNewKey]{
如果AVPlayerStatus(rawValue:newValue as!Int)=.ReadyToPlay{
playVideo()/*状态更改为.ReadyToPlay后播放*/
}
}
}否则{
super.observeValueForKeyPath(键路径,of对象:object,change:change,context:context)
}
}
func PlayerItemDidReachen(通知:NSNotification){
让playerItem=notification.object为!AVPlayerItem
playerItem.seekToTime(kCMTimeZero)
播放视频()
}
func播放视频(){
videoPlayerLayer?.player!.play()
}
我也有同样的问题,运气好吗?又一次;这种情况仍然存在。有人能在这里做出反应吗?@朱利安目前还不能解决这个问题。最终解决了出口问题,这需要等待。在提供赏金后也不注意这个问题。继续投票,希望最终有人注意到。@Julian请检查我的答案。我刚刚解决了这个问题,就像30分钟前一样,谢谢你。实际上我有一个不同的问题。我为资产轨道而不是合成轨道创建了说明。。。愚蠢的一个,但我还是花了3个星期才找到正确的组合
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()
}