wake-up-neo.com

Wie kann man einen AVPlayerViewController programmgesteuert auf Vollbild bringen?

Ich versuche, einen AVPlayerViewController programmgesteuert in den Vollbildmodus zu schalten, der aus dem "Embedded" -Modus stammt, dies scheint jedoch mit der veröffentlichten API nicht möglich zu sein. 

Gibt es eine Problemumgehung, die ich vermisse? Ich bin daran interessiert, dieselbe Animation wie die Animation zu erhalten, die Sie erhalten, wenn der Benutzer die Schaltfläche Vollbild rechts unten in den Steuerelementen drückt.

Die Verwendung von MPMoviePlayerController ist keine praktikable Alternative, da möglicherweise mehr als ein Video gleichzeitig abgespielt wird.

Vielen Dank.

19
ikaver

AVPlayerViewController ist eine Unterklasse von UIViewController und kann daher wie jede andere View Controller-Unterklasse dargestellt werden. Können Sie presentViewController:animated:completion verwenden? 

self.avPlayerController.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self presentViewController:self.avPlayerController animated:YES completion:nil];

Dies zeigt dann die Schaltfläche "Fertig" in der oberen linken Ecke.

14
Daniel J

Aktualisiert für iOS 11

Es gibt keine unterstützte Methode, um programmgesteuert mit AVPlayerViewController programmgesteuert zu arbeiten (meiner Meinung nach etwas übersehen). 

AVPlayerViewController enthält jedoch eine private Methode die genau das tut. Sie müssen selbst entscheiden, ob Sie es verwenden möchten oder nicht, wenn Sie keine privaten Methoden aufrufen.

AVPlayerViewController + Fullscreen.h

#import <AVKit/AVKit.h>

@interface AVPlayerViewController (Fullscreen)

-(void)goFullscreen;

@end

AVPlayerViewController + Fullscreen.m

#import "AVPlayerViewController+Fullscreen.h"

@implementation AVPlayerViewController (Fullscreen)

-(void)goFullscreen {
    NSString *selectorForFullscreen = @"transitionToFullScreenViewControllerAnimated:completionHandler:";
    if (@available(iOS 11.3, *)) {
        selectorForFullscreen = @"transitionToFullScreenAnimated:interactive:completionHandler:";
    } else if (@available(iOS 11.0, *)) {
        selectorForFullscreen = @"transitionToFullScreenAnimated:completionHandler:";
    }
    SEL fsSelector = NSSelectorFromString([@"_" stringByAppendingString:selectorForFullscreen]);
    if ([self respondsToSelector:fsSelector]) {
        NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:fsSelector]];
        [inv setSelector:fsSelector];
        [inv setTarget:self];

        NSInteger index = 2; //arguments 0 and 1 are self and _cmd respectively, automatically set
        BOOL animated = YES;
        [inv setArgument:&(animated) atIndex:index];
        index++;

        if (@available(iOS 11.3, *)) {
            BOOL interactive = YES;
            [inv setArgument:&(interactive) atIndex:index]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation
            index++;
        }

        id completionBlock = nil;
        [inv setArgument:&(completionBlock) atIndex:index];
        [inv invoke];
    }
}

@end
12
ToddH

In iOS11 gibt es zwei neue Eigenschaften für AVPlayerViewController: entersFullScreenWhenPlaybackBegins und exitsFullScreenWhenPlaybackEnds. Sie können den Vollbildmodus direkt nach Beginn der Wiedergabe aktivieren und nach Beendigung der Wiedergabe mit diesen Eigenschaften deaktivieren. Wenn Sie nach einer gewissen Verzögerung den Vollbildmodus aktivieren müssen, können Sie private API-Methoden wie ToddH in seine Antwort verwenden. In iOS11 ist die _transitionToFullScreenViewControllerAnimated:completionHandler:-Methode jedoch nicht mehr verfügbar. Es gibt dieselbe Methode mit dem Namen _transitionToFullScreenAnimated:completionHandler:. Die zweite Methode akzeptiert die gleichen Argumente wie die erste. 

Ich kann ein Beispiel zeigen, wie man es benutzt. Zunächst müssen Sie eine AVPlayerViewController-Instanz in Ihrer UIViewController erstellen:

private let playerController : AVPlayerViewController = {

    if let urlForPlayer = URL(string: "your_video_url") {

        $0.player = AVPlayer(url: urlForPlayer)
    }
    return $0
} (AVPlayerViewController())

Dann müssen Sie die Ansicht für AVPlayerViewController einrichten und zu Ihrer aktuellen Controller-Ansicht hinzufügen. Die Funktion setupAVplayerController kann das für Sie tun:

private func setupAVplayerController() {

    self.addChildViewController(self.playerController)
    self.playerController.view.frame = CGRect(x: 0.0, y: 0.0, width: 200.0, height: 200.0)
    self.view.addSubview(self.playerController.view)
    self.playerController.didMove(toParentViewController: self)
}

Die Funktion enterFullscreen erzwingt den Vollbildmodus für AVPlayerViewController:

private func enterFullscreen(playerViewController:AVPlayerViewController) {

    let selectorName : String = {

        if #available(iOS 11, *) {

            return "_transitionToFullScreenAnimated:completionHandler:"
        } else {

            return "_transitionToFullScreenViewControllerAnimated:completionHandler:"
        }
    }()
    let selectorToForceFullScreenMode = NSSelectorFromString(selectorName)
    if playerViewController.responds(to: selectorToForceFullScreenMode) {

            playerViewController.perform(selectorToForceFullScreenMode, with: true, with: nil)
    }
}

Und jetzt müssen Sie alle diese Funktionen dort aufrufen, wo Sie sie benötigen, zum Beispiel in viewDidAppear:

override func viewDidAppear(_ animated: Bool) {

    super.viewDidAppear(animated)

    //Your code

    self.setupAVplayerController()
    self.playerController.player?.play()
    DispatchQueue.main.asyncAfter(deadline: .now() + 10) {

        self.enterFullscreen(playerViewController:self.playerController)
    }
}

Vergessen Sie nicht, dass diese Lösung auf privaten API-Aufrufen basiert, deren Verwendung nicht empfohlen wird.

6
Roman Podymov

UPDATE: Swift 4-Version von ToddHs Antwort:

private func enterFullscreen(playerViewController: AVPlayerViewController) {

    let selectorName: String = {
        if #available(iOS 11.3, *) {
            return "_transitionToFullScreenAnimated:interactive:completionHandler:"
        } else if #available(iOS 11, *) {
            return "_transitionToFullScreenAnimated:completionHandler:"
        } else {
            return "_transitionToFullScreenViewControllerAnimated:completionHandler:"
        }
    }()
    let selectorToForceFullScreenMode = NSSelectorFromString(selectorName)

    if playerViewController.responds(to: selectorToForceFullScreenMode) {
        playerViewController.perform(selectorToForceFullScreenMode, with: true, with: nil)
    }
}
2
Ivan Georgiev

Swift 3 Version für die Antwort von ToddH:

extension AVPlayerViewController {

    func goFullScreen() {
        let selector = NSSelectorFromString("_transitionToFullScreenViewControllerAnimated:completionHandler:")
        if self.responds(to: selector) {
            // first argument is animated (true for me), second is completion handler (nil in my case)
            self.perform(selector, with: true, with: nil)
        }
    }
}
2
Milan Nosáľ

Sie können einfach die Eigenschaft videoGravity von AVPlayerViewController festlegen.

if(fullscreen)
{
    [self.avPlayerController 
     setVideoGravity:AVLayerVideoGravityResizeAspectFill];
}
else
{
    [self.avPlayerController 
    setVideoGravity:AVLayerVideoGravityResizeAspect];
}
1
The iCoder

Ich musste keinen eingeschränkten Code verwenden.

Dazu gehe ich davon aus, dass Sie den AVPlayerViewController als Child-View-Controller hinzugefügt haben.

Dazu müssen Sie zuerst den untergeordneten Ansichts-Controller entfernen und ihn dann erneut als Vollbild-Controller anzeigen und die AVPlayer -Ansicht ordnungsgemäß an die übergeordnete Ansicht anhängen.

Hier ist, wie ich es gemacht habe. Bitte beachten Sie, dass ich eine Bibliothek mit dem Namen Easy Peasy Verwende, um die playerVC.view - Einschränkungen wiederherzustellen - dies kann auch mit geeigneten Einschränkungen geschehen.

    @objc func fullscreenButtonClicked() {

        playerVC.willMove(toParentViewController: nil)
        playerVC.view.removeFromSuperview()
        playerVC.removeFromParentViewController()


        self.present(self.playerVC, animated: false, completion: {
            self.playerVC.view.easy.layout(Top(), Right(), Left(), Bottom())
        })
    }

0
rahulg