如何使 UISlider 匹配音频进度

Posted

技术标签:

【中文标题】如何使 UISlider 匹配音频进度【英文标题】:How To Make UISlider match Audio progress 【发布时间】:2017-03-07 14:43:51 【问题描述】:

我正在创建一个简单的音乐应用程序,我想知道如何制作一个 UiSlider 来跟踪音频文件的进度。到目前为止,这是我的项目:

代码:

import UIKit
import AVFoundation

class SongDetailViewController: UITableViewController 

    var audioPlayer = AVAudioPlayer()

    override func viewDidLoad() 
        super.viewDidLoad()

        do 
            audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "Song Name", ofType: "mp3")!))
            audioPlayer.prepareToPlay()

            var audiosession = AVAudioSession.sharedInstance()

            do 
                try audioSession.setCategory(AVAudioSessionCategoryPlayback)
            
        

        catch 
            print(error)
        
    
//    Buttons

//    Dismiss
    @IBAction func dismiss(_ sender: Any) 
        dismiss(animated: true, completion: nil)
    

//    Play
    @IBAction func play(_ sender: Any) 
        audioPlayer.stop()
        audioPlayer.play()
    

//    Pause
    @IBAction func pause(_ sender: Any) 
        audioPlayer.pause()
    

//    Restart
    @IBAction func restart(_ sender: Any) 
        audioPlayer.currentTime = 0
    


我想创建类似于 Apple Music 应用程序的 uislider,它会跟踪音频文件的进度,并且每当用户滑动球的东西(大声笑)时,它就会转到歌曲的那个时间。如果你能给我一些代码来完成这个,那就太棒了!

请记住,我对编码还很陌生,并且仍在快速学习,所以请保持简单 :-) 再次感谢!

【问题讨论】:

【参考方案1】:

如果您改用AVPlayer,您可以将periodicTimeObserver 添加到您的AVPlayer。在下面的示例中,您将每 1/30 秒收到一次回调……

let player = AVPlayer(url: Bundle.main.url(forResource: "Song Name", withExtension: "mp3")!)

player.addPeriodicTimeObserver(forInterval: CMTimeMake(1, 30), queue: .main)  time in

    let fraction = CMTimeGetSeconds(time) / CMTimeGetSeconds(player.currentItem!.duration)

    self.slider.value = fraction

您在代码中创建audioPlayer 的地方,替换为上面的代码。

【讨论】:

好的,那么,你能把我上面的代码放到100%完成的地方吗?如果您需要为滑块放置一个 IB 插座,也将其放入其中。那样可以么?非常感谢!! 您认为您可以自己尝试一下,如果仍有问题,请更新您的问题? 更新了我的答案。期望 SO 上的人为您完成工作是一种不好的形式。您需要自己尝试一下,然后在遇到问题时询问。 "...你能把我上面的代码放到 100% 完成的地方吗?"你开玩笑的对吧? “你能为我做我所有的工作吗?” “我的车需要洗,你介意吗?”这不是其他人为您工作的网站。付出一些努力,我们会为您提供帮助,但不要要求将解决方案交给玩具“100% 完成”。【参考方案2】:

使用AVAudioPlayer,您可以创建一个周期性计时器,该计时器每秒触发数次(最多60 次/秒- 再多就浪费了),并根据您的音频播放器的currentTime 属性更新您的滑块。要将更新与屏幕刷新同步,您可以使用 CADisplayLink 计时器。


编辑:

我的这部分答案不起作用:

还应该可以在您的设备上设置一个 Key Value Observer AVAudioPlayers currentTime 属性使每次的值 改变你的观察者火力。 (我没有尝试过,但它应该 工作。)


【讨论】:

很确定 currentTime 不支持 KVO,除非事情发生了变化。他们的文档说 KVO 不适合持续的状态变化。 developer.apple.com/documentation/avfoundation/…

以上是关于如何使 UISlider 匹配音频进度的主要内容,如果未能解决你的问题,请参考以下文章

UISlider Swift 的 AVPlayer 进度

UISlider 进展不顺利

给 UISlider 进度条圆角 [Swift]

具有缓冲进度的 UISlider - AVPlayer

通过在 UISlider 中选择点来修剪音频文件

UISlider 不能与 AVPlayer 一起正常工作