使用tableView单元中的播放滑块播放音频

时间:2019-01-14 02:40:49

标签: ios swift

如何在tableView单元格内使用带有播放和暂停功能的播放滑块播放音频? 有点困难。谁能帮助我解决这个问题?

like this one

所以我在@JacobCavin的帮助下提出了一个解决方案 并提出了此代码,但仍收到零错误报告。不知道为什么。

var playerItem:AVPlayerItem?
var player:AVPlayer?
var slider: UISlider?

override func viewDidLoad() {
    super.viewDidLoad()

   startPlayer()
}

func startPlayer() {

    let url = URL(string: "https://s3.amazonaws.com/kargopolov/kukushka.mp3")
    let playerItem:AVPlayerItem = AVPlayerItem(url: url!)
    player = AVPlayer(playerItem: playerItem)

    slider!.minimumValue = 0


    let duration : CMTime = playerItem.asset.duration
    let seconds : Float64 = CMTimeGetSeconds(duration)

    slider!.maximumValue = Float(seconds)
    slider!.isContinuous = false

    slider?.addTarget(self, action: #selector(cChatViewController.sliderChanged(sender:)), for: .valueChanged)

    player!.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, 1), queue: DispatchQueue.main) { (CMTime) -> Void in
        if self.player!.currentItem?.status == .readyToPlay {
            let time : Float64 = CMTimeGetSeconds(self.player!.currentTime());
            self.slider!.value = Float ( time );
        }

    }

}

//MARK: Private Functions

// Create function for your button
@objc func playPauseTapped(sender: UIButton) {

    if player?.rate == 0
    {
        player!.play()
        //playButton!.setImage(UIImage(named: "player_control_pause_50px.png"), forState: UIControlState.Normal)
        //            playButton!.setTitle("Pause", for: UIControlState.normal)
    } else {
        player!.pause()
        //playButton!.setImage(UIImage(named: "player_control_play_50px.png"), forState: UIControlState.Normal)
        //            playButton!.setTitle("Play", for: UIControlState.normal)
    }
}


func sliderChanged(sender: UISlider) {

    let seconds : Int64 = Int64(sender.value)
    let targetTime:CMTime = CMTimeMake(seconds, 1)

    player!.seek(to: targetTime)

    if player!.rate == 0
    {
        player?.play()
    }
}

} 扩展程序PopOverViewController:UITableViewDataSource {     func tableView(_ tableView:UITableView,numberOfRowsInSection部分:Int)-> Int {         返回1     }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! MessagesTableViewCell

    cell.outgoingPlayPauseButton.addTarget(self, action: #selector(playPauseTapped(sender:)), for: .touchUpInside)
    cell.outgoingAudioSlider.addTarget(self, action: #selector(sliderChanged(sender:)), for: .valueChanged)

    return cell
}

}

扩展名PopOverViewController:UITableViewDelegate {

}

2 个答案:

答案 0 :(得分:0)

您将需要一个UIViewController和一个UITableView。您还需要创建自定义UITableViewCell并设置UIButtonUISlider。您可以找到有关所有内容的教程here。完成此操作后,在自定义UIButton ...中为那些UISliderUITableViewCell项目创建变量...

class PlayerTableViewCell: UITableViewCell {

      @IBOutlet weak var playPauseButton: UIButton!
      @IBOutlet weak var slider: UISlider!

}

现在,在您的UIViewController中,您需要遵循正确的协议,并在UITableViewCell函数中返回自定义cellForRowAtIndexPath ...

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PlayerTableViewCell

    return cell
}

现在,我们将设置音频播放器。请查看下面的代码,这些代码将放入您的UIViewController ...

    import UIKit
    // You need to import AVFoundation
    import AVFoundation

    class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

        // Create a variable for your audio player
        var audioPlayer: AVAudioPlayer?

        override func viewDidLoad() {
            super.viewDidLoad()

            do {
                // Create the path of the audio file you have in your project. For example: songname.mp3
                if let fileURL = Bundle.main.path(forResource: "songname", ofType: "mp3") {
                    audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: fileURL))
                    // Now to play the song
                    audioPlayer?.play()
                } else {
                    print("No file with that name exists")
                }
            } catch let error {
                print("Plaing the file failed with an error \(error.localizedDescription)")
            }


        }

        // Create function for your button
        @objc func playPauseTapped(sender: UIButton) {
            if (audioPlayer?.isPlaying)! {
                // Since the audioPlayer is playing, we want to pause the music
                audioPlayer?.pause()
                // We will change the button's (sender's) image to reflect the change
                sender.setImage(UIImage(named: "play"), for: .normal)
            } else {
                // Since the audioPlayer is NOT playing, we want to play the music
                audioPlayer?.play()
                // We will change the button's (sender's) image to reflect the change
                sender.setImage(UIImage(named: "pause"), for: .normal)
            }
        }

// Change the audioPlayer's current time when the slider is changed
    @objc func sliderChanged(sender: UISlider) {
        audioPlayer?.currentTime = TimeInterval(sender.value)
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! YourCustomCellClass

        // Set up your Play/Pause button's action
        cell.playPauseButton.addTarget(self, action: #selector(playPauseTapped(sender:)), for: .touchUpInside)

        // Set up the slider
        cell.slider.maximumValue = Float((audioPlayer?.duration)!)
        cell.slider.value = Float((audioPlayer?.currentTime)!)
        cell.slider.addTarget(self, action: #selector(sliderChanged(sender:)), for: .valueChanged)
        return cell
    }
}

然后您就去了!现在,您可以控制UITableViewCell中的音频了。如果您希望UISlider反映歌曲的当前时间,请将Timer设置为每秒播放一次并更新滑块的值...

slider.value = Float((audioPlayer?.currentTime)!)

希望对您有所帮助!

答案 1 :(得分:0)

所以我找到了问题的解决方案,这里就是:)非常感谢您的帮助。

这是我问题的完整代码

用于视图控制器。

导入UIKit 导入AVFoundation

PopOverViewController类:UIViewController {

var playerItem:AVPlayerItem?
var player:AVPlayer?
var slider: UISlider?

override func viewDidLoad() {
    super.viewDidLoad()

   startPlayer()
}

func startPlayer() {

    let url = URL(string: "https://s3.amazonaws.com/kargopolov/kukushka.mp3")
    let playerItem:AVPlayerItem = AVPlayerItem(url: url!)
    player = AVPlayer(playerItem: playerItem)



}

//MARK: Private Functions

// Create function for your button
@objc func playPauseTapped(sender: UIButton) {

    if player?.rate == 0
    {
        player!.play()
        //playButton!.setImage(UIImage(named: "player_control_pause_50px.png"), forState: UIControlState.Normal)
        //            playButton!.setTitle("Pause", for: UIControlState.normal)
    } else {
        player!.pause()
        //playButton!.setImage(UIImage(named: "player_control_play_50px.png"), forState: UIControlState.Normal)
        //            playButton!.setTitle("Play", for: UIControlState.normal)
    }
}


func sliderChanged(sender: UISlider) {

    let seconds : Int64 = Int64(sender.value)
    let targetTime:CMTime = CMTimeMake(seconds, 1)

    player!.seek(to: targetTime)

    player!.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, 1), queue: DispatchQueue.main) { (CMTime) -> Void in
        if self.player!.currentItem?.status == .readyToPlay {
            let time : Float64 = CMTimeGetSeconds(self.player!.currentTime());
            sender.value = Float ( time );
        }
    }
    if player?.rate == 0 {
        player?.play()
    }
}

} 扩展程序PopOverViewController:UITableViewDataSource {     func tableView(_ tableView:UITableView,numberOfRowsInSection部分:Int)-> Int {         返回1     }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! MessagesTableViewCell

    let url = URL(string: "https://s3.amazonaws.com/kargopolov/kukushka.mp3")
    let playerItem:AVPlayerItem = AVPlayerItem(url: url!)
    player = AVPlayer(playerItem: playerItem)

    cell.outgoingAudioSlider.minimumValue = 0
    cell.ingoingAudioSlider.minimumValue = 0

    let duration : CMTime = playerItem.asset.duration
    let seconds : Float64 = CMTimeGetSeconds(duration)


    cell.outgoingAudioSlider.maximumValue = Float(seconds)
    cell.outgoingAudioSlider.isContinuous = false


    cell.outgoingAudioSlider.addTarget(self, action: #selector(cChatViewController.sliderChanged(sender:)), for: .valueChanged)


    cell.outgoingPlayPauseButton.addTarget(self, action: #selector(playPauseTapped(sender:)), for: .touchUpInside)


    cell.outgoingPlayPauseButton.addTarget(self, action: #selector(playPauseTapped(sender:)), for: .touchUpInside)
    cell.outgoingAudioSlider.addTarget(self, action: #selector(sliderChanged(sender:)), for: .valueChanged)

    return cell
}

}

扩展名PopOverViewController:UITableViewDelegate {

}

以及“表格视图”单元格

导入UIKit

MessagesTableViewCell类:UITableViewCell {

@IBOutlet weak var outgoingAudioContainer: UIView!
@IBOutlet weak var outgoingPlayPauseButton: UIButton!
@IBOutlet weak var outgoingAudioSlider: UISlider!

}