使用Swift开发一个贝乐虎启蒙App - 音频播放

706 阅读2分钟

这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战

前言

上一篇我们封装了音频播放,现在我们就来使用它。在这之前我们要来处理一个问题,就是当我们返回首页的时候,音频还是可以继续播放的,而且在首页的导航栏右上角会有一个音频播放的按钮,所以音频播放页面我们做成单例

页面搭建这边就省略了

IMG_0239.PNG

逻辑处理

1、新建一个AudioPlayerViewController控制器

  • 创建一个单例
static let share = AudioPlayerViewController()
  • 新增一些属性
var playerItemModel = AudioItemModel() /// 正在播放的item
var didAudioItemModeChange: () -> Void = {} /// 播放的item改变
var dataSource = [AudioItemModel]()
var playerIndex: Int = 0
private var isSingle: Bool = false /// 单曲循环
  • 初始化AudioPlayer
private lazy var player: AudioPlayer = {
    let player = AudioPlayer()
    player.delegate = self
    player.playbackPausesWhenResigningActive = false
    player.playbackPausesWhenBackgrounded = false
    player.playbackResumesWhenBecameActive = false
    player.playbackResumesWhenEnteringForeground = false
    return player
}()

extension AudioPlayerViewController: AudioPlayerDelegate {

    func playerStateDidChange(_ player: AudioPlayer) {
        bottomView.playState = player.playState
    }

    func playerCurrentTimeDidChange(_ player: AudioPlayer) {
        if player.playState == .playing {
            bottomView.currentTime = player.currentTimeInterval
            bottomView.maxTime = player.maximumDuration
            bottomView.sliderValue = Float(player.currentTimeInterval / player.maximumDuration)
        }
    }

    func playerPlaybackDidEnd(_ player: AudioPlayer) {
        /// 如果不是单曲播放的话,playerIndex就+1
        if !isSingle {
            playerIndex += 1
        }
        playerURL()
    }

    func player(_ player: AudioPlayer, didFailWithError error: Error?) {

    }
}
  • 增加一个playerURL()方法来播放
func playerURL() {
    /// 对边界处理
    if playerIndex < 0 {
        playerIndex = dataSource.count - 1
    }

    if playerIndex > dataSource.count - 1 {
        playerIndex = 0
    }

    let model = dataSource[playerIndex]
    /// 选中的id和正在播放的id一致就不做处理
    if model.id == playerItemModel.id {
        return
    }

    iconImageView.kf_set(audioModel.album.thumbs.large_thumb)
    titleLabel.text = model.title
    playerItemModel = model
    didAudioItemModeChange()
    player.player(model.sd_url)
}
  • 初始化来控制播放
private lazy var bottomView: AudioPlayerBottomView = {
    let view = AudioPlayerBottomView()
    return view
}()

/// 播放/暂停
bottomView.didClickPlayer = { [weak self] in
    guard let `self` = self else { return }
    self.player.changePlay()
}

/// 滑动进度条快进/后退
bottomView.sliderValueDidChange = { [weak self] value in
    guard let `self` = self else { return }
    let sliderTime = value * self.player.maximumDuration
    self.player.seek(to: CMTime(seconds: sliderTime, preferredTimescale: CMTimeScale(1 * NSEC_PER_SEC)))
}

/// UISlider按下/松开状态,按下的时候暂停播放,松开播放
bottomView.sliderTouch = { [weak self] value in
    guard let `self` = self else { return }
    if value == .down {
        self.player.pause()
    } else {
        self.player.play()
    }
}

/// 下一曲
bottomView.didNext = { [weak self] in
    guard let `self` = self else { return }
    self.playerIndex += (self.isSingle ? 0 : 1)
    self.playerURL()
}

/// 上一曲
bottomView.didUp = { [weak self] in
    guard let `self` = self else { return }
    self.playerIndex -= (self.isSingle ? 0 : 1)
    self.playerURL()
}

/// 播放模式
bottomView.didPlayerType = { [weak self] isSingle in
    guard let `self` = self else { return }
    self.isSingle = isSingle
}
  • 处理导航栏显示/隐藏音频播放按钮
private func showAudioIcon() {
    if !AudioPlayerViewController.share.playerItemModel.id.isEmpty {
        navigation.item.rightBarButtonItem = UIBarButtonItem(image: "icon_nav_audio".image, closure: { [weak self] _ in
            guard let `self` = self else { return }
            self.push(AudioPlayerViewController.share)
        })
    } else {
        navigation.item.rightBarButtonItem = nil
    }
}
  • AudioPlayerViewController里面增加一个pause()方法,用来处理视频播放时,暂停音频播放,然后在视频播放页面调用就可以了
func pause() {
    if !playerItemModel.id.isEmpty {
        player.pause()
    }
}

效果

ypbf.gif