/***************************************************************************** * AudioMiniPlayer.swift * VLC for iOS ***************************************************************************** * Copyright (c) 2019 VideoLAN. All rights reserved. * $Id$ * * Authors: Soomin Lee * * Refer to the COPYING file of the official project for license. *****************************************************************************/ @objc(VLCAudioMiniPlayer) class AudioMiniPlayer: UIView, MiniPlayer { var visible: Bool = false var contentHeight: Float { return 72.0 } @IBOutlet private weak var audioMiniPlayer: UIView! @IBOutlet private weak var artworkImageView: UIImageView! @IBOutlet private weak var titleLabel: UILabel! @IBOutlet private weak var artistLabel: UILabel! @IBOutlet private weak var progressBarView: UIProgressView! @IBOutlet private weak var playPauseButton: UIButton! @IBOutlet private weak var previousButton: UIButton! @IBOutlet private weak var nextButton: UIButton! private var mediaService: MediaLibraryService private lazy var playbackController = VLCPlaybackController.sharedInstance() @objc init(service: MediaLibraryService) { self.mediaService = service super.init(frame: .zero) initView() setupConstraint() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func updatePlayPauseButton() { let imageName = playbackController.isPlaying ? "MiniPause" : "MiniPlay" playPauseButton.imageView?.image = UIImage(named: imageName) } } // MARK: - Private initializers private extension AudioMiniPlayer { private func initView() { Bundle.main.loadNibNamed("AudioMiniPlayer", owner: self, options: nil) addSubview(audioMiniPlayer) audioMiniPlayer.clipsToBounds = true audioMiniPlayer.layer.cornerRadius = 4 progressBarView.clipsToBounds = true progressBarView.layer.cornerRadius = 1 artworkImageView.clipsToBounds = true artworkImageView.layer.cornerRadius = 2 playPauseButton.accessibilityLabel = NSLocalizedString("PLAY_PAUSE_BUTTON", comment: "") nextButton.accessibilityLabel = NSLocalizedString("NEXT_BUTTON", comment: "") previousButton.accessibilityLabel = NSLocalizedString("PREV_BUTTON", comment: "") } private func setupConstraint() { var guide: LayoutAnchorContainer = self if #available(iOS 11.0, *) { guide = safeAreaLayoutGuide } audioMiniPlayer.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([audioMiniPlayer.leadingAnchor.constraint(equalTo: guide.leadingAnchor, constant: 8), audioMiniPlayer.trailingAnchor.constraint(equalTo: guide.trailingAnchor, constant: -8), audioMiniPlayer.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8), ]) } } // MARK: - VLCPlaybackControllerDelegate extension AudioMiniPlayer { func prepare(forMediaPlayback controller: VLCPlaybackController) { updatePlayPauseButton() controller.delegate = self controller.recoverDisplayedMetadata() // For now, AudioMiniPlayer will be used for all media controller.videoOutputView = artworkImageView } func mediaPlayerStateChanged(_ currentState: VLCMediaPlayerState, isPlaying: Bool, currentMediaHasTrackToChooseFrom: Bool, currentMediaHasChapters: Bool, for controller: VLCPlaybackController) { updatePlayPauseButton() } func displayMetadata(for controller: VLCPlaybackController, metadata: VLCMetaData) { setMediaInfo(metadata) } func playbackPositionUpdated(_ controller: VLCPlaybackController) { progressBarView.progress = controller.playbackPosition } func savePlaybackState(_ controller: VLCPlaybackController) { mediaService.savePlaybackState(from: controller) } func media(forPlaying media: VLCMedia) -> VLCMLMedia? { return mediaService.fetchMedia(with: media.url) } } // MARK: - UI Receivers private extension AudioMiniPlayer { @IBAction private func handlePrevious(_ sender: UIButton) { playbackController.previous() } @IBAction private func handlePlayPause(_ sender: UIButton) { playbackController.playPause() } @IBAction private func handleNext(_ sender: UIButton) { playbackController.next() } @IBAction private func handleFullScreen(_ sender: Any) { UIApplication.shared.sendAction(#selector(VLCPlayerDisplayController.showFullscreenPlayback), to: nil, from: self, for: nil) } @IBAction private func handleSwipe(_ sender: UISwipeGestureRecognizer) { switch sender.direction { case .right: playbackController.previous() case .left: playbackController.next() default: break } } @IBAction private func handleLongPressPlayPause(_ sender: UILongPressGestureRecognizer) { switch sender.state { // case .began: // In the case of .began we could a an icon like the old miniplayer case .ended: playbackController.stopPlayback() case .cancelled, .failed: playbackController.playPause() updatePlayPauseButton() default: break } } } // MARK: - Setters private extension AudioMiniPlayer { private func setMediaInfo(_ metadata: VLCMetaData) { titleLabel.text = metadata.title artistLabel.text = metadata.artist if metadata.isAudioOnly { artworkImageView.image = metadata.artworkImage ?? UIImage(named: "no-artwork") } } }