swift:音频滑块控件

Posted

技术标签:

【中文标题】swift:音频滑块控件【英文标题】:swift: audio slider control 【发布时间】:2016-01-24 01:47:38 【问题描述】:

问题:

当我转到包含按钮和滑块的视图控制器时,它会使应用程序崩溃并在 slider.maximumValue = Float(audioPlayer.duration) 的行上给我 Thread 1:EXC_BAD_ACCESS (code=1, address=0x38)。在视图控制器中,我有一个播放/暂停按钮、一个停止按钮和一个控制音频播放位置的滑块。

代码:

import UIKit
import AVFoundation

class AgnesAudioViewController: UIViewController 

var audioPlayer = AVAudioPlayer()
var toggleState = 1
@IBOutlet var slider: UISlider!

@IBAction func done(sender: AnyObject) 
    dismissViewControllerAnimated(true, completion: nil)


@IBAction func play(sender: AnyObject) 
    audioPlayer.play()


@IBAction func pause(sender: AnyObject) 
    audioPlayer.pause()


@IBAction func stop(sender: AnyObject) 
    audioPlayer.stop()


@IBAction func scrubAudio(sender: AnyObject) 
    audioPlayer.stop()
    audioPlayer.currentTime = NSTimeInterval(slider.value)
    audioPlayer.prepareToPlay()
    audioPlayer.play()


@IBAction func playPauseButton(sender: AnyObject) 
    var playBtn = sender as! UIButton
    if toggleState == 1 
        audioPlayer.play()
        toggleState = 2
        playBtn.setImage(UIImage(named:"pause.png"),forState:UIControlState.Normal)
     else 
        audioPlayer.pause()
        toggleState = 1
        playBtn.setImage(UIImage(named:"play.png"),forState:UIControlState.Normal)
    


override func viewDidLoad() 
    super.viewDidLoad()

    var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateSlider"), userInfo: nil, repeats: true)

    slider.maximumValue = Float(audioPlayer.duration)

    let pathString = NSBundle.mainBundle().pathForResource("agnes", ofType: "mp2")

    if let pathString = pathString 

        let pathURL = NSURL(fileURLWithPath: pathString)

        do 

            try audioPlayer = AVAudioPlayer(contentsOfURL: pathURL)

         catch 

            print("error")
        


    



func updateSlider() 
    slider.value = Float(audioPlayer.currentTime)


【问题讨论】:

【参考方案1】:

这解决了问题:

import UIKit
import AVFoundation

class AgnesAudioViewController: UIViewController 

var audioPlayer = AVAudioPlayer()
var toggleState = 1
@IBOutlet var slider: UISlider!
@IBOutlet var playedTime: UILabel!

@IBAction func done(sender: AnyObject) 
    dismissViewControllerAnimated(true, completion: nil)
    audioPlayer.stop()


@IBAction func play(sender: AnyObject) 
    audioPlayer.play()
    updateTime()


@IBAction func pause(sender: AnyObject) 
    audioPlayer.pause()
    updateTime()


@IBAction func stop(sender: AnyObject) 
    audioPlayer.stop()
    updateTime()


@IBAction func scrubAudio(sender: AnyObject) 
    audioPlayer.stop()
    audioPlayer.currentTime = NSTimeInterval(slider.value)
    audioPlayer.prepareToPlay()
    audioPlayer.play()


func updateTime() 
    var currentTime = Int(audioPlayer.currentTime)
    var duration = Int(audioPlayer.duration)
    var total = currentTime - duration
    var totalString = String(total)

    var minutes = currentTime/60
    var seconds = currentTime - minutes / 60

    playedTime.text = NSString(format: "%02d:%02d", minutes,seconds) as String


@IBAction func playPauseButton(sender: AnyObject) 
    //1 = play
    //2 = pausw
    var playBtn = sender as! UIButton
    if toggleState == 1 
        audioPlayer.play()
        toggleState = 2
        playBtn.setImage(UIImage(named:"pause2.png"),forState:UIControlState.Normal)
     else 
        audioPlayer.pause()
        toggleState = 1
        playBtn.setImage(UIImage(named:"play2.png"),forState:UIControlState.Normal)
    


override func viewDidLoad() 
    super.viewDidLoad()

    var updateTimer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateTime"), userInfo: nil, repeats: true)
    var timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("updateSlider"), userInfo: nil, repeats: true)

    let pathString = NSBundle.mainBundle().pathForResource("agnes", ofType: "mp3")

    if let pathString = pathString 

        let pathURL = NSURL(fileURLWithPath: pathString)

        do 

            try audioPlayer = AVAudioPlayer(contentsOfURL: pathURL)

         catch 

            print("error")
        


    

    slider.maximumValue = Float(audioPlayer.duration)


func updateSlider() 
    slider.value = Float(audioPlayer.currentTime)
    

【讨论】:

那么总数是多少? var seconds = currentTime - minutes / 60 是错误的。应该是 var currentTime - 分钟 * 60【参考方案2】:

对于Hunter回答,没关系,但我会在updateTime 函数中添加一些行。因为这样它不会在标签中显示像 1:61 这样的时间。

    func updateTime() 
    var currentTime = Int(audioPlayer.currentTime)
    var duration = Int(audioPlayer.duration)
    var total = currentTime - duration
    var totalString = String(total)

    var minutes = currentTime/60
    var seconds = currentTime - minutes / 60
    if minutes > 0 
       seconds = seconds - 60 * minutes
    

    playedTime.text = NSString(format: "%02d:%02d", minutes,seconds) as String

【讨论】:

那么总数是多少? @iosMentalist 如果我现在看它可能什么都没有。这段代码可能会更简洁,并且还有一些不必要的计算,对此感到抱歉。写这篇文章后我学到了很多:)

以上是关于swift:音频滑块控件的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中使用控件播放音频

带有 Swift 的步进滑块 [重复]

将 JS 音量控件附加到多个 Audiojs 音频播放器

Dropbox 应用,例如视频和音频预览

光滑的滑块视频复制

CPP / JUCE 音频编程框架 - 滑块阵列不工作 - 单滑块工作