Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Issue about subclassing AVPlayerViewController #89

Closed
Kyle-Ye opened this issue Nov 19, 2023 · 8 comments
Closed

Issue about subclassing AVPlayerViewController #89

Kyle-Ye opened this issue Nov 19, 2023 · 8 comments
Assignees

Comments

@Kyle-Ye
Copy link
Contributor

Kyle-Ye commented Nov 19, 2023

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 as final 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.

@yichengchen yichengchen self-assigned this Nov 19, 2023
@yichengchen
Copy link
Owner

yichengchen commented Nov 19, 2023

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.

@yichengchen
Copy link
Owner

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.

@yichengchen
Copy link
Owner

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?

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Nov 19, 2023

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

  1. In the init method of VideoPlayerViewController/CommonPlayerViewController, we create a AVPlayerViewController and store it as an unowned(not weak) reference.
unowned var player: AVPlayerViewController

Also we somehow make AVPlayerViewController strongly hold our VideoPlayerViewController/CommonPlayerViewController instance.

  1. 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)
        }
    }
}

@yichengchen
Copy link
Owner

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.

@yichengchen
Copy link
Owner

yichengchen commented Nov 20, 2023

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 .

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Nov 20, 2023

After override the preferredFocusEnvironments of the CommonPlayerViewController, the directional key of the remote works. Maybe we can still put the AVPlayerViewController as the subclass of the CommonPlayerViewController .

Typo here? I guess you mean putting AVPlayerViewController as a child controller of CommonPlayerViewController

@yichengchen
Copy link
Owner

After override the preferredFocusEnvironments of the CommonPlayerViewController, the directional key of the remote works. Maybe we can still put the AVPlayerViewController as the subclass of the CommonPlayerViewController .

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

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants