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

Con*_*sed 2 position playback avaudioplayer uislider ios

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

录音部分效果很好。记录的文件已成功存储,并且当用户点击保存的文件时,它才开始播放文件。

UISlider用来指示播放进度。现在,我将UISlideruserInteractionEnabled属性禁用为NO。因此,我不允许用户与UISliderbar 进行交互。

我需要的是,我想将此属性启用为YES,以便可以选择所需的位置播放音频。为此,我在滑块代码中添加了以下行。

[mySlider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢

Nat*_*lia 5

在Swift中共享解决方案。

我能够基于发布的Objective-C实现zeeran使我的项目与滑块一起使用,并且它甚至可以连续不断地更新当前时间,而我以前没有这样做。我很高兴

因此,我想分享一下快速实施,以防它对任何人都有帮助。

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)
    }
}
Run Code Online (Sandbox Code Playgroud)