ios - 如何从UISlider 的自定义位置播放音频?

标签 ios position avaudioplayer playback uislider

我正在开发一个语音备忘录应用程序,它可以记录用户的声音并回放。

录音部分效果不错。录制的文件已成功存储,当用户点击保存的文件时,它才开始播放文件。

我正在使用 UISlider 来指示播放进度。现在,我将 UISlideruserInteractionEnabled 属性禁用为 NO。所以,我不允许用户与 UISlider 栏进行交互。

我需要的是,我想使这个属性为YES,这样就可以选择想要播放音频的地方。为此,我在 slider 代码中添加了以下行。

[mySlider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];

通过添加以上行,我可以在 sliderChanged: 方法中找到 slider 位置。但是,我不知道如何从所选位置启动播放器。每个文件的大小不同,因此播放时间也不同。

是否有可用的示例代码?需要您的帮助。

谢谢

最佳答案

在 Swift 中分享一个解决方案。

根据 zeeran 发布的 objective-c 实现,我能够让我的项目与 slider 一起工作,它甚至可以连续更新当前时间,而我以前没有这样做过。我很高兴。

所以我想分享快速实现,以防它能帮助到那里的任何人。

import UIKit
import AVFoundation
import Foundation

class ActivityViewController: UIViewController, AVAudioPlayerDelegate {  
    /// The player & sound file object
    var audioPlayer = AVAudioPlayer()
    var activitySound = NSURL()

    var updater : CADisplayLink! = nil // tracks the time into the track
    var updater_running : Bool = false // did the updater start?
    var playing : Bool = false //indicates if track was started playing

    @IBOutlet var playButton: UIButton!
    @IBOutlet var timeLabel: UILabel!  // shows time and duration
    @IBOutlet var audioSlider: UISlider! // slider object

    @IBAction func pressedPlayButton(sender: AnyObject) {
        if (playing == false) {
            updater = CADisplayLink(target: self, selector: Selector("updateProgress"))
            updater.frameInterval = 1
            updater.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode)
            updater_running = true
            audioPlayer.play()
            playButton.selected = true // pause image is assigned to "selected"
            playing = true
            updateProgress()
        } else {
            updateProgress()  // update track time
            audioPlayer.pause()  // then pause
            playButton.selected = false  // show play image (unselected button)
            playing = false // note track has stopped playing
        }
    }

    // action for when the slider is moved: set as 'valuechanged' for UISlider object
    @IBAction func sliderMoved(sender: UISlider) {
        // if the track was playing store true, so we can restart playing after changing the track position
        var wasPlaying : Bool = false
        if playing == true {
            audioPlayer.pause()
            wasPlaying = true
        }
        audioPlayer.currentTime = NSTimeInterval(round(audioSlider.value))
        updateProgress()
        // starts playing track again it it had been playing
        if (wasPlaying == true) {
            audioPlayer.play()
            wasPlaying == false
        }
    }

    // Timer delegate method that updates current time display in minutes
    func updateProgress() {
        let total = Float(audioPlayer.duration/60)
        let current_time = Float(audioPlayer.currentTime/60)
        audioSlider.minimumValue = 0.0
        audioSlider.maximumValue = Float(audioPlayer.duration)
        audioSlider.setValue(Float(audioPlayer.currentTime), animated: true)
        timeLabel.text = NSString(format: "%.2f/%.2f", current_time, total) as String
    }

    //- AVAudioPlayer delegate method - resets things when track finishe playing
    func PlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {
        if flag {
            playButton.selected = false
            playing = false
            audioPlayer.currentTime = 0.0
            updateProgress()
            updater.invalidate()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // configure AVAudioPlayer as audioPlayer object
        let file = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("file1", ofType: "mp3")!)!
        audioPlayer = audioPlayer(contentsOfURL: file, error: nil)
        audioPlayer.delegate = self

        audioSlider.continuous = false
    }

    // method makes sure updater gets stopped when leaving view controller, because otherwise it will run indefinitely in background
    override func viewWillDisappear(animated: Bool) {
        if playing == true {
            audioPlayer.stop()
        }
        updater.invalidate()
        updater_running = false
        super.viewWillDisappear(animated)
    }
}

关于ios - 如何从UISlider 的自定义位置播放音频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17684218/

相关文章:

ios - 使用项目模板时防止 Xcode 6.3 链接默认库和 header

ios - 在 Swift 中通过 TouchID 生成哈希或字符串

android - RecyclerView - 如何平滑滚动到某个位置的项目顶部?

ios - 如何使用 AVAudioPlayer 播放 'http:/......./mp3'

swift - AudioPlayer 和锁屏/控制中心控制 Swift

iphone - 按下按钮时的 Swift AVAudioplayer

ios - 调整屏幕截图图像大小导致文本模糊 ios

Java JComboBox控件滚动条位置?

html - 为父 div 设置 overflow-x 的位置 Sticky

ios - CollectionUIView重新加载数据在获取数据后不更新显示