10

I am using Apple Airplay and AVPlayer to show a video on an external display, while showing some controls on the device using Apple TV and AirPlay.

I am using this class to display the AVPlayer on the external screen:

#import "AirPlayViewController.h"

@interface AirPlayViewController ()

@end

@implementation AirPlayViewController

- (id)initWithFrame:(CGRect)iFrame{
    self.view.frame = iFrame;

    self.backGroundImageView = [[UIImageView alloc]initWithFrame:iFrame];
    [self.view addSubview: self.backGroundImageView];

    return self;
}

- (void)viewDidLoad{
    [super viewDidLoad];

}

-(void)viewWillDisappear:(BOOL)animated{
    [audioVideoPlayer pause];
}

-(void)playMediaWithURL:(NSURL*)aURL{
    audioVideoPlayer = [AVPlayer playerWithURL:aURL];
    audioVideoPlayer.usesExternalPlaybackWhileExternalScreenIsActive=YES;
    audioVideoPlayer.allowsExternalPlayback= YES;

    //manually resizing and adding the layer, so that the app does not get confused with airplayfunctionality
    AVPlayerLayer* playerLayer = [AVPlayerLayer playerLayerWithPlayer: audioVideoPlayer];
    playerLayer.frame = self.view.bounds;
    [self.view.layer addSublayer:playerLayer];

    if (audioVideoPlayer) {
        [audioVideoPlayer play];
    }
}

-(void)stopMediaPlayback{
    [audioVideoPlayer pause];
    [[AVPlayerLayer playerLayerWithPlayer: audioVideoPlayer] removeFromSuperlayer];
    audioVideoPlayer = nil;
}

@end

The problem I have is right there in playMediaWithURL:. The AVPlayer layer is not automatically added to the external screen but I have to add it by hand, which feels kind of dirty and leads to all kind of clean-up work when I want to remove the AVPlayer from the view again.

Has anyone else had trouble with this and found some neat way to implement it?

The airPlayViewController is called from another UIViewController that contains the second window along with all the AirPlay delegate stuff to display it, using this function:

- (void)setupMirroringForScreen:(UIScreen *)anExternalScreen{
    //find the correct resolution for the external screen
    UIScreen *tScreen= anExternalScreen;
    CGSize max = {0, 0};
    UIScreenMode *maxScreenMode = nil;

    for (UIScreenMode *current in tScreen.availableModes) {
        if (maxScreenMode == nil || current.size.height > max.height || current.size.width > max.width) {
            max = current.size;
            maxScreenMode = current;
        }
    }
    tScreen.currentMode = maxScreenMode;

    // Setup window in external screen
    self.externalWindow = [[UIWindow alloc] initWithFrame:tScreen.bounds];
    self.externalWindow.hidden = NO;
    self.externalWindow.layer.contentsGravity = kCAGravityResizeAspect;
    self.externalWindow.screen = tScreen;

    self.airPlayVC = [[AirPlayViewController alloc]initWithFrame:tScreen.bounds];
    [self.airPlayVC.backGroundImageView setImage:[UIImage imageNamed:mainMenuExternalBackgroundImage]];

    //try to play a video on the external Screen/ Audio file as fallback
    NSURL *tURL= [[NSBundle mainBundle]URLForResource:mainMenuVideo withExtension:nil];
    if (!tURL) {
        tURL = [[NSBundle mainBundle] URLForResource:mainMenuAmbienceMusic withExtension:nil];
    }
    [self.airPlayVC playMediaWithURL:tURL];
    [self.externalWindow addSubview:self.airPlayVC.view];

}
Jamie Taylor
  • 4,709
  • 5
  • 44
  • 66
Amandir
  • 679
  • 1
  • 7
  • 20
  • To Clarify: The Audio Playback is fine anyway, and if I add the Playerlayer the way I do in my code the video is also displayed and the autosizing and everything works fine. It just doesn't feel right to ad the layer by hand, so I am looking for a better way to implement this – Amandir Mar 17 '14 at 14:27
  • Hey Kim, in the end I sticked with the above solution. – Amandir Oct 13 '14 at 08:18

0 Answers0