2016-07-20 33 views
1

我有这样的代码:斯威夫特AVPlayer seekToTime问题

let punto = sender.locationInView(self.barraVideo).x 
     let larghezzaImg : Double = Double((self.barraVideoInvisTocco?.frame.width)!) 

     let percTocco : Double = (100/larghezzaImg) * Double(punto) 

     let lunghezzaVideo : Double = Double(CGFloat((avPlayer?.currentItem?.asset.duration.value)!)/CGFloat(1000.0)); 
     let frameRate : Int32 = (avPlayer?.currentItem?.currentTime().timescale)! 

     let secondo : Float64 = Float64((lunghezzaVideo/100)*percTocco) 
     print("Val : \(secondo)"); 

     avPlayer?.currentItem?.seekToTime(CMTimeMakeWithSeconds(secondo, frameRate)) 

     avPlayer?.play() 
     videoInPlay = true; 
     playPauseBtn!.image = UIImage(named: "iconaPausa.png")!; 

这recive上搜索条自来水的X cordinate,寻求视频。该代码适用于日志视频,但对于短视频非常不利。 当我在短片挖掘AVPlayer只追求接近开始时或接近视频的结尾,而不是中间

打印:

Val : 3.36008475976495 
Val : 7.14189817632069 
Val : 13.3303201306846 
Val : 3.70388597945183 
Val : 3.93308679257642 
Val : 3.24548435320265 
Val : 3.70388597945183 
Val : 18.8311396456748 
Val : 27.0823689181601 
Val : 40.1468152662618 
Val : 51.3776551093667 
Val : 17.2267339538027 
Val : 9.54850671412889 
Val : 23.4151559081666 
Val : 37.6256063218913 

瓦尔rappresents秒正确的价值在哪里不会寻求。 对不起,英语不好,我是意大利人

回答

4

对于AVPlayer,有不同的方法让玩家寻找时间;

player.seekToTime(<#time: CMTime#CMTime#>) 

这种方法,玩家将寻求seekingTime很快,但不求确切位置seekingTime是,这意味着会有一些抵消seekingTime的

苹果的文档

使用此方法以寻求当前播放项目指定的时间。

找到的时间可能与效率的指定时间不同。

如需查询样本,请查看seekToTime:toleranceBefore:toleranceAfter :.

player.seekToTime(<#T##time: CMTime##CMTime#>, completionHandler: <#T##(Bool) -> Void#>) 

这种方法,玩家将寻求快速,也seekingTime,与胶印,你可以做一些事情completionHandler

苹果的文档

使用此方法寻求当前播放器项目的指定时间,并在搜索操作完成时被通知。

为仍在处理任何先前寻求请求完成处理程序将立即与成品参数

设置为否被调用。如果新请求完成而没有被另一个查找请求或任何其他操作中断,则指定完成处理程序将完成处理程序调用,并将完成的参数设置为YES。

如果你想寻求更准确,使用下面的方法,而不是

player.seekToTime(<#T##time: CMTime##CMTime#>, toleranceBefore: <#T##CMTime#>, toleranceAfter: <#T##CMTime#>) 

player.seekToTime(<#T##time: CMTime##CMTime#>, toleranceBefore: <#T##CMTime#>, toleranceAfter: <#T##CMTime#>, completionHandler: <#T##(Bool) -> Void#>) 

此方法将让玩家寻求指定的时间,你问,但会慢一些(以及..根据大部分目前媒体上)

苹果的文档

使用此方法以寻求当前播放项目指定的时间。

的时间seeked到将[时间toleranceBefore,时间+ toleranceAfter]的范围内,并且可以从对效率的指定的时间不同。

通行证kCMTimeZero两者toleranceBefore和toleranceAfter请求样品准确求其可能产生额外的解码延迟。

使用beforeTolerance消息传递此方法:kCMTimePositiveInfinity和afterTolerance:kCMTimePositiveInfinity与消息传递seekToTime:直接相同。

我注意到你正在使用

avPlayer?.currentItem?.seekToTime(CMTimeMakeWithSeconds(secondo, frameRate)) 

你可以尝试使用这种方法来寻找指定的时间 (当然要慢)

avPlayer?.currentItem?.seekToTime(CMTimeMakeWithSeconds(secondo, frameRate), toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero) 

愿望可以帮助你出来,目前的

1

我怀疑任何的答案供给实际工作。试试这个:

Technical Q & A QA1820 如何通过AVPlayer seekToTime实现流畅的视频清理:?

问:我的应用程序允许用户使用与AVPlayer seekToTime组合的滑块控制擦洗视频文件:但是在视频帧的显示的相当大的滞后。我怎样才能达到更平滑的擦洗?

答:不要打电话给AVPlayer seekToTime:快速连续。这将取消正在进行的搜索,导致大量搜索并且不会显示大量目标帧。相反,请使用AVPlayer seekToTime的完成处理程序变体,并等待正在进行的查找,然后再发出另一个。清单1和清单2给出了这种技术的例子(注意:这些例子假设已经创建了一个有效的玩家对象,玩家的当前物品状态是通过键值观察来维护的)更多信息,请参阅AV Foundation编程指南:

使用AVPlayer seekToTime的完成处理程序变种:流畅的擦洗(SWIFT)。

import AVFoundation 

class MyClass { 

    var isSeekInProgress = false 
    let player = <#A valid player object #> 
    var chaseTime = kCMTimeZero 
    // your player.currentItem.status 
    var playerCurrentItemStatus:AVPlayerItemStatus = .Unknown 

    ... 

    func stopPlayingAndSeekSmoothlyToTime(newChaseTime:CMTime) 
    { 
     player.pause() 

     if CMTimeCompare(newChaseTime, chaseTime) != 0 
     { 
      chaseTime = newChaseTime; 

      if !isSeekInProgress 
      { 
       trySeekToChaseTime() 
      } 
     } 
    } 

    func trySeekToChaseTime() 
    { 
     if playerCurrentItemStatus == .Unknown 
     { 
      // wait until item becomes ready (KVO player.currentItem.status) 
     } 
     else if playerCurrentItemStatus == .ReadyToPlay 
     { 
      actuallySeekToTime() 
     } 
    } 

    func actuallySeekToTime() 
    { 
     isSeekInProgress = true 
     let seekTimeInProgress = chaseTime 
     player.seekToTime(seekTimeInProgress, toleranceBefore: kCMTimeZero, 
       toleranceAfter: kCMTimeZero, completionHandler: 
     { (isFinished:Bool) -> Void in 

      if CMTimeCompare(seekTimeInProgress, chaseTime) == 0 
      { 
       isSeekInProgress = false 
      } 
      else 
      { 
       trySeekToChaseTime() 
      } 
     }) 
    } 

}