gutenbergn
gutenbergn

Reputation: 494

Remove buffering activity indicator from AVPlayerViewController

I'm implementing an iOS video player using AVPlayerViewController with custom playback controls (i.e., the showsPlaybackControls property is defined as NO). This seems to work properly in most cases, the only issue I'm seeing is that I would like to use a custom activity indicator with the player as well, but it seems that AVPlayerViewController shows a default activity indicator while buffering the video at some points.

Is there a way to remove this default activity indicator view from AVPlayerViewController?

The image shows what I'm describing, the controls at the bottom are custom and overlaid on top of the player, but the activity indicator is not.

player with custom controls and default activity indicator

Upvotes: 9

Views: 2796

Answers (2)

Gasper
Gasper

Reputation: 5689

I made an extension of AVPlayerViewController that exposes the internal activity indicator. Here you go, with all the Swift 3 sexiness:

import AVKit

extension AVPlayerViewController {
    /// Activity indicator contained nested inside the controller's view.
    var activityIndicator: UIActivityIndicatorView? {
        // Indicator is extracted by traversing the subviews of the controller's `view` property.
        // `AVPlayerViewController`'s view contains a private `AVLoadingIndicatorView` that
        // holds an instance of `UIActivityIndicatorView` as a subview.
        let nestedSubviews: [UIView] = view.subviews
            .flatMap { [$0] + $0.subviews }
            .flatMap { [$0] + $0.subviews }
            .flatMap { [$0] + $0.subviews }
        return nestedSubviews.filter { $0 is UIActivityIndicatorView }.first as? UIActivityIndicatorView
    }

    /// Indicating whether the built-in activity indicator is hidden or not.
    var isActivityIndicatorHidden: Bool {
        set {
            activityIndicator?.alpha = newValue ? 0 : 1
        }
        get {
            return activityIndicator?.alpha == 0
        }
    }
}

With this, you can either easily style the UIActivityIndicatorView or just hide it all together, e.g.:

playerViewController.isActivityIndicatorHidden = true

Upvotes: 4

Vladica Pešić
Vladica Pešić

Reputation: 41

I also searched for this solution and the way I managed to make it is hide video player view controllers view once I started playing video and when video is ready to play I show it again.

private func playVideo() {

    videoPlayer?.play()

    self.addLoader()

    videoPlayerController.view.hidden = true

    videoPlayer?.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.New, context: nil)
}

public override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {

    if (object?.isEqual(videoPlayer) == true && keyPath == "status") {

        self.removeLoader()
        videoPlayerController.view.hidden = false
    }
}

Upvotes: 1

Related Questions