     var fullAudioDataLength: Int = 0;
     
     var mediaLoader: MediaLoader?;
-    var activityIndicator: UIActivityIndicatorView?
     var hasPushedViewController: Bool = false;
     var ignoreNextDelegateCall: Bool = false;
     

        let player = AVPlayer(url: urlToLoad);
        self.player = player;
        self.player?.currentItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: [.old, .new], context: nil)
        
        player.addObserver(self, forKeyPath: "timeControlStatus", options: [.old, .new], context: nil)
        player.automaticallyWaitsToMinimizeStalling = false;

        let playerViewController = AVPlayerViewController();
        self.playerViewController = playerViewController;
        playerViewController.player = self.player;
        playerViewController.view.autoresizingMask = [.flexibleHeight, .flexibleWidth];
        playerViewController.addObserver(self, forKeyPath: "videoBounds", options: [.old, .new], context: nil);

        self.activityIndicator = UIActivityIndicatorView();
        self.activityIndicator?.style = .large;

        self.rootViewController.pushViewController(playerViewController, animated: false);
        playerViewController.navigationItem.backButtonTitle = "Back";
        self.navigationControllerObserver.observePopTransition(of: playerViewController, delegate: self);
        self.hasPushedViewController = true;
        player.play();
    }
    
    override public func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == "timeControlStatus", let change = change, let newValue = change[NSKeyValueChangeKey.newKey] as? Int, let oldValue = change[NSKeyValueChangeKey.oldKey] as? Int {
            let oldStatus = AVPlayer.TimeControlStatus(rawValue: oldValue)
            let newStatus = AVPlayer.TimeControlStatus(rawValue: newValue)
            DispatchQueue.main.async {[weak self] in
                guard let activityIndicator = self?.activityIndicator else { return }
                if (newStatus == .waitingToPlayAtSpecifiedRate && activityIndicator.isAnimating) {
                    activityIndicator.startAnimating();
                }
                if newStatus != oldStatus {
                    if newStatus == .playing || newStatus == .paused {
                        activityIndicator.stopAnimating()
                    } else {
                        activityIndicator.startAnimating()
                    }
                }
            }
        } else if let center = self.playerViewController?.view.center, keyPath == "videoBounds", !center.equalTo(CGPoint(x: 0, y: 0)) {
            guard let activityIndicator = self.activityIndicator else { return }

            activityIndicator.center = center;
            if (activityIndicator.superview == nil) {
                self.playerViewController?.view.addSubview(activityIndicator);
            }
            self.playerViewController?.view.bringSubviewToFront(activityIndicator);
            activityIndicator.startAnimating();
        } else if keyPath == #keyPath(AVPlayerItem.status) {
            let status: AVPlayerItem.Status
            if let statusNumber = change?[.newKey] as? NSNumber {
                status = AVPlayerItem.Status(rawValue: statusNumber.intValue)!

            // Switch over status value
            switch status {
            case .readyToPlay:
                // Player item is ready to play.
                player?.play()
            case .failed:
                // Player item failed. See error.
                if let error = (object as? AVPlayerItem)?.error?.localizedDescription {
                    MDCSnackbarManager.default.show(MDCSnackbarMessage(text: "Failed to play video with error: \(error)"))
                } else {
