ATV-Bilibili-demo
ATV-Bilibili-demo copied to clipboard
Issue about subclassing AVPlayerViewController
The current VC inheritance chain is VideoPlayerViewController -> CommonPlayerViewController -> AVPlayerViewController.
But Apple's AVKit documentation states that "The framework doesn’t support subclassing AVPlayerViewController."
But AVKit is written by ObjectiveC,
AVPlayerViewController
can't marked asfinal class
to stop us from inheriting it.
Some issue I met before(setting AVPlaybackSpeed
and not working) may also be related to our usage of inheritance for AVPlayerViewController.
But anyway using subclass of AVPlayerViewController
has some risk that it may not work in future OS update. I'd like to suggest we make CommonPlayerViewController
a simple class or a subclass of NSObject and add a property var player: AVPlayerViewController
to refactor our codebase.
Try with simply putting AVPlayerViewController as a child controller of CommonPlayerViewController (fix/avplayerVC-child 541d204). But the directional key of the remote is not working or not forwarded to AVPlayerViewController. May need more research with the tvOS event chain.
another propose is make CommonPlayerViewController become a simple util to present avplayerVC only. move all danmuView, maskView and related logic to the overlayContentView of the AVPlayerVC.
If we just make CommonPlayerViewController a simple class or a subclass of NSObject and add a property var player: AVPlayerViewController. How to prevent the CommonPlayerViewController deinit immediately after present the AVPlayerViewController. There is not a view hierarchy to keep it. Or just do some hacky work like the overlayContentView holding the CommonPlayerViewController?
If we just make CommonPlayerViewController a simple class or a subclass of NSObject and add a property var player: AVPlayerViewController. How to prevent the CommonPlayerViewController deinit immediately after present the AVPlayerViewController. There is not a view hierarchy to keep it. Or just do some hacky work like the overlayContentView holding the CommonPlayerViewController?
Take VideoDetailViewController/VideoPlayerViewController as an example:
In VideoDetailViewController
, we try to present if from a vc. And when direatlyEnterVideo
is true and the present is complete, we'll continue to make VideoDetailViewController
to present our VideoPlayerViewController
The original code:
func present(from vc: UIViewController, direatlyEnterVideo: Bool = Settings.direatlyEnterVideo) {
if !direatlyEnterVideo {
vc.present(self, animated: true)
} else {
vc.present(self, animated: false) { [weak self] in
guard let self else { return }
let player = VideoPlayerViewController(playInfo: PlayInfo(aid: self.aid, cid: self.cid, epid: self.epid, isBangumi: self.isBangumi))
self.present(player, animated: true)
}
}
}
The new code can be written as follow
- In the init method of
VideoPlayerViewController/CommonPlayerViewController
, we create aAVPlayerViewController
and store it as an unowned(not weak) reference.
unowned var player: AVPlayerViewController
Also we somehow make AVPlayerViewController
strongly hold our VideoPlayerViewController/CommonPlayerViewController
instance.
- Then in the caller side, we just present
VideoPlayerViewController.player
func present(from vc: UIViewController, direatlyEnterVideo: Bool = Settings.direatlyEnterVideo) {
if !direatlyEnterVideo {
vc.present(self, animated: true)
} else {
vc.present(self, animated: false) { [weak self] in
guard let self else { return }
let controller = VideoPlayerViewController(playInfo: PlayInfo(aid: self.aid, cid: self.cid, epid: self.epid, isBangumi: self.isBangumi))
self.present(controller.player, animated: true)
}
}
}
yep, I am thinking is there is a simply elegant way to make AVPlayerViewController
strongly hold our VideoPlayerViewController/CommonPlayerViewController
instance without subclassing. Like use the AVPlayerViewController.overlayContentView
to hold the controller, but it's a little strange.
After override the preferredFocusEnvironments
of the CommonPlayerViewController
, the directional key of the remote works. Maybe we can still put the AVPlayerViewController
as the child of the CommonPlayerViewController
.
After override the
preferredFocusEnvironments
of theCommonPlayerViewController
, the directional key of the remote works. Maybe we can still put theAVPlayerViewController
as the subclass of theCommonPlayerViewController
.
Typo here? I guess you mean putting AVPlayerViewController as a child controller of CommonPlayerViewController
After override the
preferredFocusEnvironments
of theCommonPlayerViewController
, the directional key of the remote works. Maybe we can still put theAVPlayerViewController
as the subclass of theCommonPlayerViewController
.Typo here? I guess you mean putting AVPlayerViewController as a child controller of CommonPlayerViewController
you are right, now putting AVPlayerViewController as a child controller of CommonPlayerViewController works fine