How can I detect when the user press the expand icon of the AVPlayerViewController? I want to know when the movie playing is entering the fullscreen mode.
Asked
Active
Viewed 9,207 times
10
-
do you have Swift code for this? – Piraba Apr 04 '16 at 10:33
-
https://stackoverflow.com/a/58809976/7113238 would work. – Lawliet Nov 11 '19 at 23:28
5 Answers
5
It is also possible to observe bounds
of playerViewController.contentOverlayView
and compare that to [UIScreen mainScreen].bounds
, e.g.:
self.playerViewController = [AVPlayerViewController new];
// do this after adding player VC as a child VC or in completion block of -presentViewController:animated:completion:
[self.playerViewController.contentOverlayView addObserver:self forKeyPath:@"bounds" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
...
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context {
if (object == self.playerViewController.contentOverlayView) {
if ([keyPath isEqualToString:@"bounds"]) {
CGRect oldBounds = [change[NSKeyValueChangeOldKey] CGRectValue], newBounds = [change[NSKeyValueChangeNewKey] CGRectValue];
BOOL wasFullscreen = CGRectEqualToRect(oldBounds, [UIScreen mainScreen].bounds), isFullscreen = CGRectEqualToRect(newBounds, [UIScreen mainScreen].bounds);
if (isFullscreen && !wasFullscreen) {
if (CGRectEqualToRect(oldBounds, CGRectMake(0, 0, newBounds.size.height, newBounds.size.width))) {
NSLog(@"rotated fullscreen");
}
else {
NSLog(@"entered fullscreen");
}
}
else if (!isFullscreen && wasFullscreen) {
NSLog(@"exited fullscreen");
}
}
}
}

kambala
- 2,341
- 19
- 20
-
@PavanMore works fine for me on iOS 10, but I tested it only with iOS 9 SDK – kambala Sep 21 '17 at 20:21
4
You can use KVO to observe the videoBounds
property of your AVPlayerViewController
instance.
Edit The most basic example being
[_myPlayerViewController addObserver:self forKeyPath:@"videoBounds" options:0 context:nil];

ChrisH
- 4,468
- 2
- 33
- 42
-
ChrisH while I can find the code to register KVO to get player status, I can't seem to find the keyPath which will notify on the videoBounds change. [self.playerViewController.player addObserver:self forKeyPath:@"status" options:0 context:nil]; - What instead of @"status" do you use? – John Stewart Sep 24 '15 at 21:31
-
@JohnStewart You're talking about observing the `status` property of the `playerViewController.player` - you need to observe the `videoBounds` property of the `playerViewController` – ChrisH Sep 24 '15 at 21:34
-
1ChrisH - I've been experimenting with this solution, and while it does work perfectly for video files, I just found that when playing audio files using AVPlayerViewController, the videoBounds property doesn't change (reasonably so, since there is not actually any video). So I'm trying to find a way to detect a change to fullscreen in this case. Attempting to KVO on "frame" for playerViewController.player so far is not working. Might you have any suggestions in this case to detect when it goes fullscreen? – John Stewart Sep 26 '15 at 19:14
-
My app is just in the portrait mode. I have to enable all orientation modes after the player goes full screen in order to enable video in the landscape mode. But exiting fullscreen shows some issues. The application is in the landscape mode and is reseted after the player dismisses from the full screen. – Vladimír Slavík Nov 30 '15 at 20:49
4
In swift, both for audio and video:
Add this observer in a initialization function such as viewDidLoad, or didMoveToSuperview:
//Observe if player changed bounds and maybe went to fullscreen
playerController.contentOverlayView!.addObserver(self, forKeyPath: "bounds", options: NSKeyValueObservingOptions.New, context: nil)
and this function on the class:
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == "bounds" {
let rect = change!["new"] as! NSValue
if let playerRect: CGRect = rect.CGRectValue() as CGRect {
if playerRect.size == UIScreen.mainScreen().bounds.size {
print("Player in full screen")
isVideoInFullScreen = true
} else {
print("Player not in full screen")
}
}
}
}

Lombas
- 1,000
- 1
- 8
- 24
2
Swift 2.2 Create and use subclass of AVPlayerViewController.
class YouVideoPlayer: AVPlayerViewController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if view.bounds == contentOverlayView?.bounds {
//code
}
}

Serge Bilyk
- 875
- 9
- 10
-
3From documentation: "Important Do not subclass AVPlayerViewController. Overriding this class’s methods is unsupported and results in undefined behavior." – Ilya Oct 28 '16 at 07:01
-
1
-1
self.frameChecker = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkContetnOverlay) userInfo:nil repeats:YES];
-(void)checkContetnOverlay{
BOOL currentPlayerIsFullscreen = (self.avVideoPlayer.contentOverlayView.frame.size.width>1000 || self.avVideoPlayer.contentOverlayView.frame.size.height>1000);
//works with these values only for iPad
if (((PlayerViewController*)self.parentViewController).playerIsInfullScreen != currentPlayerIsFullscreen) {
if (currentPlayerIsFullscreen) {
NSLog(@"CUSTOM PLAYER (av) : changed to fullscreen");
self.avVideoPlayer.showsPlaybackControls = YES;
}else{
NSLog(@"CUSTOM PLAYER (av) : changed to minimised");
self.avVideoPlayer.showsPlaybackControls = YES;
}
}
}

Durdu
- 4,649
- 2
- 27
- 47