14

I am developing an iPhone application that has support for video play. I am using MPMoviePlayerController with custom controls for playing the video. For this purpose I have set control style of MPMoviePlayerController to MPMovieControlStyleNone.

I would like to support AirPlay feature for the video being played. As per the documentation, we have to set the 'allowsAirPlay' property of MPMoviePlayerController to YES to enable AirPlay feature. How can I display the AirPlay button on my player UI if I am using MPMoviePlayerController with custom controls?

I have tried the following:

  1. Instantiated MPVolumeView
  2. Set the showsRouteButton and showsVolumeSlider properties of MPVolumeView to NO to hide the volume slider and route button
  3. Added MPVolumeView on my custom player View

I have not given the reference of MPVolumeView and MPMoviePlayerController to each other. But, if 'allowsAirPlay' of MPMoviePlayerController is set to YES then AirPlay button gets displayed on MPVolumeView. How are MPVolumeView and MPMoviePlayerController related? What is the connection between these two classes which are created independently?

halfer
  • 19,824
  • 17
  • 99
  • 186
spd
  • 2,114
  • 1
  • 29
  • 54

4 Answers4

10

Since the MPMoviePlayerController only allows you to play one video at a time, the MediaPlayer framework always knows the video that's playing. That's how MPVolumeView knows about the MPMoviePlayerController. I have no official docs, but I imagine it's baked into the framework this way.

Since there are probably a lot of checks and balances going on (and they loves consistent UIs), Apple only allows you to use their AirPlay button/UI for tapping into this feature. You can, however, put that button wherever you want:

airplayButton = [[MPVolumeView alloc] init];
airplayButton.frame = CGRectMake(myX, myY, 40, 40);
[airplayButton setShowsVolumeSlider:NO];
[customPlayerControls.view addSubview:airplayButton];

I just guessed on the width,height being 40,40 and I'm sure it's not correct, but once I got the button in place it didn't matter.

devdavid
  • 1,571
  • 10
  • 14
  • But, this does not answer my question – spd Aug 09 '11 at 03:36
  • 2
    You ask two questions: > How can I display the AirPlay button on my player UI if I am using MPMoviePlayerController with custom controls? The code snippet answers this. Create an instance of MPVolumeView, hide it's volume slider, you're left with the Airplay button. Set its frame and add it to the view. This puts a fully functioning Airplay button in your controls. It only appears if there is an Airplay enabled device in range. [To change the appearance]: http://stackoverflow.com/questions/5730973/airplay-support-mpmovieplayercontroller-and-mpvolumeview-relation/6988562#6988562 – devdavid Aug 09 '11 at 21:45
  • > How are MPVolumeView and MPMoviePlayerController related? They are both part of the MediaPlayer framework, so, when an MPMoviePlayerController is playing a movie, the framework "knows" about it. Since MPVolumeView is in the framework, it "knows" about it. That's why you don't need to pass any reference of the MPMoviePlayerController to the Airplay button - it already knows. – devdavid Aug 09 '11 at 21:45
  • Thank you for the response. I also have one more query: Is there any way to show Air Play Button on our UI before MPMoviePlayer Controller is created [just creating MPVolumeView]. I think it is not possible; just wanted to conform... – spd Aug 10 '11 at 07:18
  • I haven't tested so I don't know for sure, but I'm almost certain the answer is no. But since the button would be dead anyway (that is, it wouldn't hook anything up to airplay since the app has no media playing), you could easily create a UIButton using the airplay button icon and put it wherever you want. Apple could potentially have a problem with that during review, though. – devdavid Aug 10 '11 at 23:23
2
for (UIButton *button in volumeView.subviews) {
if ([button isKindOfClass:[UIButton class]]) {
    [button setImage:[UIImage imageNamed:@"custom-route-button.png"] forState:UIControlStateNormal];
    [button sizeToFit];
}}

I think this will help you.

user755278
  • 1,634
  • 3
  • 16
  • 32
  • This solution has potential for app rejection by Apple. However, it currently is the only solution available. +1 – Till Jun 05 '11 at 03:10
  • @Till: Since this solution doesn't use any private APIs Apple won't reject it. In fact, we do similar things (customize the volume slider) and other apps do it as well. If Apple choses the change the layout so that the the button isn't a direct subview any more the code will simply not work any more, but it won't do anything harmful. – DarkDust Jul 09 '12 at 07:23
  • @DarkDust using non-private API methods does not prevent rejection. Modifying Apple's standard controls where obviously not intended by Apple also promotes that risk. Still this solution works and **currently** is not subject to rejection by Apple. – Till Jul 09 '12 at 08:25
2

The MPVolumeView has an attribute to hide the volume slider and to show the Route button. So there is no need to traverse the views hiding things.

MPVolumeView *volumeView = [[[MPVolumeView alloc] initWithFrame:myContainerView.bounds] autorelease];
volumeView.showsVolumeSlider = NO;
volumeView.showsRouteButton = YES;
[myContainerView addSubview:volumeView];

The placement of the AirPlay (Route) button may not be what you expect so you may have to play the frame of the container view a bit to get it where you want it.

Skabber
  • 369
  • 3
  • 10
0

The answer is: you can't. There is no official method as of iOS 4.3 to provide your own controls for Airplay - you need to use the standard controls if you need that functionality.

mrwalker
  • 1,883
  • 21
  • 23