Swift AVPlayer搜索时间问题

Swift AVPlayer搜索时间问题,swift,avplayer,Swift,Avplayer,我有以下代码: let punto = sender.locationInView(self.barraVideo).x let larghezzaImg : Double = Double((self.barraVideoInvisTocco?.frame.width)!) let percTocco : Double = (100 / larghezzaImg) * Double(punto) let lunghezzaVideo : Do

我有以下代码:

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")!;
在seekBar上点击x坐标并搜索视频。 该代码适用于日志视频,但在短视频中效果很差。 当我点击短视频时,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
val Rap表示我不想寻找的秒的正确值。
抱歉英语不好,我是意大利人

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

player.seekToTime(<#time: CMTime#CMTime#>)
您可以尝试使用此方法来查找指定的时间 (当然慢一点)


希望能帮助你

我怀疑所提供的任何答案是否有效。试试这个:

QA1820技术问答 如何使用AVPlayer seekToTime:实现平滑的视频擦洗

问:我的应用程序允许用户使用滑动控制结合AVPlayer seekToTime来清理视频文件:但是视频帧的显示有相当大的滞后。如何实现更平滑的擦洗

答:避免打电话给AVPlayer seektime:快速连续。这将取消正在进行的搜索,导致大量搜索而不是大量显示目标帧。相反,请使用AVPlayer seekToTime:的完成处理程序变量,并等待正在进行的搜索首先完成,然后再发出另一个搜索。清单1和清单2给出了该技术的示例(注意:这些示例假设已经创建了一个有效的播放器对象,并且玩家的当前项目状态通过关键值观察被保持。参见AV基础编程指南以获得更多信息):

使用AVPlayer的完成处理程序变体seekToTime:进行更平滑的擦洗(Swift)

import-AVFoundation
类MyClass{
var isSeekInProgress=false
让玩家=
var chaseTime=kCMTimeZero
//您的player.currentItem.status
var playerCurrentItemStatus:AVPlayerItemStatus=.Unknown
...
func停止播放并搜索Moothlytime(新追逐时间:CMTime)
{
player.pause()
如果CMTimeCompare(newChaseTime,chaseTime)!=0
{
chaseTime=新chaseTime;
如果!是不是有进展
{
trySeekToChaseTime()
}
}
}
func trySeekToChaseTime()
{
如果playerCurrentItemStatus==.Unknown
{
//等待项目准备就绪(KVO player.currentItem.status)
}
否则,如果playerCurrentItemStatus==.ReadyToPlay
{
实际Ektotime()
}
}
func实际sektotime()
{
isSeekInProgress=true
让seekTimeInProgress=chaseTime
player.seekToTime(seekTimeInProgress,之前的公差:kCMTimeZero,
公差:kCMTimeZero,completionHandler:
{(isFinished:Bool)->中的Void
如果CMTimeCompare(参见时间进程,chaseTime)=0
{
isSeekInProgress=false
}
其他的
{
trySeekToChaseTime()
}
})
}
}

这对我很有效。关键点是将kCMTimeZero放在两个公差字段中

player.seek(to: CMTimeMakeWithSeconds(value, duration), toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)

在Swift 4.2和Xcode 10.1中

player?.seek(to: CMTimeMakeWithSeconds(100, preferredTimescale: 1), toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero)
avPlayer?.currentItem?.seekToTime(CMTimeMakeWithSeconds(secondo, frameRate))
avPlayer?.currentItem?.seekToTime(CMTimeMakeWithSeconds(secondo, frameRate), toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
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()
            }
        })
    }

}
player.seek(to: CMTimeMakeWithSeconds(value, duration), toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)
player?.seek(to: CMTimeMakeWithSeconds(100, preferredTimescale: 1), toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero)