A, implementation,
Picture-in-picture is easy, step one, step two, step three.
1. Prepare to picture in picture
#import <AVKit/AVKit.h>
@property (nonatomic, strong) AVPictureInPictureController *pipVC;
@property (nonatomic, strong) AVPlayerLayer *playerLayer;
@property (nonatomic, strong) AVPlayer *player;
Copy the code
2, configuration,
- (void)startPip { self.player = [AVPlayer playerWithURL:[NSURL URLWithString:self.liveVideo.hdlurl]]; self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player]; self.playerLayer.frame = CGRectMake(100, 80, 100, 200); [self.player play]; [self.view.layer addSublayer:self.playerLayer]; / / 1. Determine whether support picture in picture function if ([AVPictureInPictureController isPictureInPictureSupported]) {/ / 2. @try {NSError *error = nil; [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback mode:AVAudioSessionModeMoviePlayback options:AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:&error]; // Why comment this out? You will find that sometimes AVAudioSession fails to open it. By the above methods [[AVAudioSession sharedInstance] setCategory: AVAudioSessionOrientationBack error: & error]; [[AVAudioSession sharedInstance] setActive:YES error:&error]; } @catch (NSException *exception) {NSLog(@"AVAudioSession error "); } self.pipVC = [[AVPictureInPictureController alloc] initWithPlayerLayer:self.playerLayer]; self.pipVC.delegate = self; }}Copy the code
3. Start/close
- (void)openOrClose { if (self.pipVC.isPictureInPictureActive) { [self.pipVC stopPictureInPicture]; } else { [self.pipVC startPictureInPicture]; }} / / agent / / is about to open the picture in picture - (void) pictureInPictureControllerWillStartPictureInPicture: (AVPictureInPictureController *)pictureInPictureController { NSLog(@""); } / / have open picture in picture - (void) pictureInPictureControllerDidStartPictureInPicture: (AVPictureInPictureController *)pictureInPictureController { NSLog(@""); } / / open the picture in picture failure - (void) pictureInPictureController: (pictureInPictureController AVPictureInPictureController *) failedToStartPictureInPictureWithError:(NSError *)error { NSLog(@"%@", error); } / / a close picture in picture - (void) pictureInPictureControllerWillStopPictureInPicture: (AVPictureInPictureController *)pictureInPictureController { NSLog(@""); } / / has been closed picture in picture - (void) pictureInPictureControllerDidStopPictureInPicture: (AVPictureInPictureController *)pictureInPictureController { NSLog(@""); } / / close picture in picture and resume playback interface - (void) pictureInPictureController: (pictureInPictureController AVPictureInPictureController *) restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler { NSLog(@""); }Copy the code
Two, pay attention to points and pits
-
After setting AVPlayerLayer Frame, you can adjust the size of the picture in the picture
-
The bottom layer of the picture in the picture is AVPlayer, some people say that can only play video, actually wrong, can play live broadcast of.m3U8 (currently some voice has this logic).
- So there is a problem. If the PLAYER in APP uses URL of other protocol, how to switch? Player provided for SDK in general APP.
- In the live broadcast, if the APP and picture-in-picture use non-protocol URL, in fact, there is little impact, because the picture is always real-time, there is no synchronization problem, only the UI excessive need to deal with.
-
Picture in picture is AVPictureInPictureController, if want to within the APP, according to the global need to let the singleton
-
Real machine debugging! Simulators don’t work
-
App kill, picture in picture also immediately disappear