iOS Airplay - "Playing on your TV"
Asked Answered
N

2

6

I have displayed the airplay button using this code

var airplayButton: UIBarButtonItem!
let airView: MPVolumeView = MPVolumeView()
airView.showsRouteButton = true
airView.showsVolumeSlider = false
airView.sizeToFit()
airView.tintColor = UIColor.blackColor()

airplayButton = UIBarButtonItem(customView: airView)
airplayButton.tintColor = UIColor.whiteColor()

Now, I want to display a screen. Is there any default method in iOS Airplay framework to display it. Or I have to design screen myself. Also, there are no delegates to verify when the device is connected and movie start streaming on AppleTV through iOS Device. I only have a variable to check i.e externalPlaybackActive

The issue is If I use the variable it wouldn't be efficient solution as I have airplay can be connected from Control during playback. I don't want to run a timer to check after each second if the movie is streaming on AppleTV. Any better ideas ?

This video is playing on "Apple TV"

Like this image

Niggardly answered 30/6, 2016 at 9:10 Comment(0)
N
3

This is how I implemented it. It works like a charm !

//Airplay constants

private var observerContextAirplay = 1

private var propertyToObserveAirplay = "externalPlaybackActive"

 // MARK: AirPlay Key-value Observing

    func startObservingForAirPlayStatusChanges()
    {
        self.player.moviePlayer.addObserver(self, forKeyPath: propertyToObserveAirplay, options: .New, context: &observerContextAirplay)
    }

    func stopObservingForAirPlayStatusChanges()
    {
        self.player.moviePlayer.removeObserver(self, forKeyPath: propertyToObserveAirplay)
    }

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if context == &observerContextAirplay {
            if self.player.moviePlayer.externalPlaybackActive == true
            {                    
                self.setUpAirPlayView()
            }
            else if self.player.moviePlayer.externalPlaybackActive == false
            {
                self.resetPlayerView()
            }

        }
        else {
            super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
        }
    }

//Setup AirplayView

func setUpAirPlayView()
{
    //Airplay Button

    if self.airPlay_PlayBtn == nil
    {
        let playImage = UIImage(named: "player_play.png")!
        if let _ = self.airPlay_PlayBtnFrame
        {
            self.airPlay_PlayBtn = UIButton(frame: self.airPlay_PlayBtnFrame)
            self.airPlay_PlayBtn.setBackgroundImage(playImage, forState: UIControlState.Normal)
            self.airPlay_PlayBtn.addTarget(self, action: #selector(ICFPlayerViewController.airPlayButtonAction), forControlEvents: UIControlEvents.TouchUpInside)

            self.airPlay_PlayBtn.setBackgroundImage(UIImage(named: "player_play.png"), forState: .Normal)
            self.airPlay_PlayBtn.setBackgroundImage(UIImage(named: "player_pause.png"), forState: .Selected)
            self.airPlay_PlayBtn.center = self.view.center

            self.view.addSubview(self.airPlay_PlayBtn)
            if let _ = self.player
            {
                self.player.playPauseButton.hidden = true
            }
        }
    }
    else
    {
        self.airPlay_PlayBtn.hidden = false
        if let _ = self.player
        {
            self.player.playPauseButton.hidden = true
        }
    }

    // Airplay Label
    if self.airPlayLabel == nil
    {
        self.airPlayLabel = UILabel()
        self.airPlayLabel.frame = CGRectMake(0, 0, 280, 20)

        self.airPlayLabel.text = "Your video is now playing on Apple TV"
        self.airPlayLabel.textAlignment = NSTextAlignment.Center
        self.airPlayLabel.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.6)

        self.airPlayLabel.textColor = UIColor.whiteColor()

        self.airPlayLabel.sizeToFit()

        self.airPlayLabel.center = self.view.center

        self.airPlayLabel.center.y = self.view.center.y - self.activityIndicator.frame.size.height*1.5
        self.view.addSubview(self.airPlayLabel)
    }
    else
    {
        self.airPlayLabel.hidden = false
    }

    // Thumbnail
    self.setupContentThumbnailImageView() //Fetch Thumbnail image
    if let _ = self.thumbnailImage
    {
        self.view.addSubview(self.thumbnailImage)
    }

    self.view.bringSubviewToFront(bottomToolbar)
    self.view.bringSubviewToFront(topToolbar)

    if let _ = self.airPlayLabel
    {
        self.view.bringSubviewToFront(self.airPlayLabel)
    }
    if let _ = self.airPlay_PlayBtn
    {
        self.view.bringSubviewToFront(self.airPlay_PlayBtn)
    }

}
Niggardly answered 10/7, 2016 at 7:47 Comment(3)
You don't even show what self.setUpAirPlayView() does. Did you take my suggestion and use the contentOverlayView?Malevolent
Yeah I did and It didnt work. There is no member named 'contentOverlayView'. I am using AVPlayer. self.setUpAirPlayView() is just a function to display a view on top of my player's view. Will post that function too.Niggardly
Right, that's why I said it would work if you were using an AVPlayerViewController, you didn't specify that you were using an AVPlayer.Malevolent
M
0

It looks like you're using an AVPlayerViewController, which has a contentOverlayView UIView property which sits between the video player and the controls.

You can start by putting a property observer on externalPlaybackActive to know when AirPlay playback starts. Once the value of that is true, initialize your UIView, add it as a subview of your player's contentOverlayView, and poisition it.

let subview = UIView() // your view you want to show when AirPlay is active
subview.frame = CGRect(...)
playerVC.contentOverlayView?.addSubview(subview)
playerVC.contentOverlayView?.bringSubviewToFront(subview)
Malevolent answered 5/7, 2016 at 14:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.