私は AVPlayerViewController を「埋め込み」モードからプログラムでフルスクリーンモードにしようとしていますが、これは公開されたAPIでは不可能なようです。
私が見逃している回避策はありますか?ユーザーがコントロールの右下にある全画面ボタンを押したときに表示されるアニメーションと同じアニメーションを取得することに興味があります。
MPMoviePlayerControllerの使用は、一度に複数のビデオを再生する可能性があるため、実行可能な代替手段ではありません。
ありがとう。
AVPlayerViewControllerはUIViewControllerのサブクラスであるため、他のView Controllerサブクラスと同様に表示可能です。 presentViewController:animated:completion
を使用できますか?
self.avPlayerController.modalPresentationStyle = UIModalPresentationOverFullScreen;
[self presentViewController:self.avPlayerController animated:YES completion:nil];
これにより、左上隅に「完了」ボタンが表示されます。
iOS 11用に更新されました
プログラムでAVPlayerViewControllerを使用してフルスクリーンに移行する方法はサポートされていません(私の意見では少し見落としがあります)。
ただし、 AVPlayerViewControllerにはプライベートメソッドが含まれています それはまさにそれを行います。プライベートメソッドを呼び出すことになっていない場合は、使用するかどうかを自分で決定する必要があります。
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
IOS11には、AVPlayerViewController
の2つの新しいプロパティがあります:entersFullScreenWhenPlaybackBegins
とexitsFullScreenWhenPlaybackEnds
。これらのプロパティを使用して、再生開始直後に全画面モードを有効にし、再生が終了したときに無効にすることができます。しばらくしてフルスクリーンモードを有効にする必要がある場合は、 ToddHhis answer で言及されているように、プライベートAPIメソッドを使用できます。ただし、iOS11では_transitionToFullScreenViewControllerAnimated:completionHandler:
メソッドは使用できなくなりました。_transitionToFullScreenAnimated:completionHandler:
という同じメソッドがあります。 2番目のメソッドは、最初のメソッドと同じ引数を受け入れます。
使い方の例を示すことができます。まず、AVPlayerViewController
にUIViewController
インスタンスを作成する必要があります。
private let playerController : AVPlayerViewController = {
if let urlForPlayer = URL(string: "your_video_url") {
$0.player = AVPlayer(url: urlForPlayer)
}
return $0
} (AVPlayerViewController())
次に、AVPlayerViewControllerのビューをセットアップし、現在のコントローラービューに追加する必要があります。関数setupAVplayerController
はあなたのためにそれをすることができます:
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)
}
関数enterFullscreen
は、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)
}
}
そして今、あなたは必要な場所でこれらすべての関数を呼び出す必要があります。例えば、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)
}
}
このソリューションは、使用が推奨されていないプライベートAPI呼び出しに基づいていることを忘れないでください。
更新:Swift ToddHの答えの4つのバージョン:
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)
}
}
ToddHの回答用のSwift 3バージョン:
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)
}
}
}
AVPlayerViewControllerのvideoGravityプロパティを設定するだけです。
if(fullscreen)
{
[self.avPlayerController
setVideoGravity:AVLayerVideoGravityResizeAspectFill];
}
else
{
[self.avPlayerController
setVideoGravity:AVLayerVideoGravityResizeAspect];
}
制限されたコードを使用する必要はありませんでした。
このため、AVPlayerViewController
を子View Controllerとして追加したと想定しています。
そのためには、まず子View Controllerを削除してから、それを再びフルスクリーンコントローラとして提示し、AVPlayer
ビューをその親ビューに適切にアタッチする必要があります。
これが私がやった方法です。 Easy Peasy
制約を復元するためにplayerVC.view
というライブラリを使用していることに注意してください-適切な制約でも同様に行うことができます。
@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())
})
}