Created
May 17, 2022 14:33
-
-
Save dotkebi/aeeef0b6d7d72e86b53b9f4fc6c74fa1 to your computer and use it in GitHub Desktop.
brightcove
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// CastPlayerViewController.swift | |
// BasicCastPlayer | |
// | |
// Copyright © 2020 Brightcove, Inc. All rights reserved. | |
// | |
import UIKit | |
import GoogleCast | |
import SnapKit | |
import BrightcovePlayerSDK | |
import BrightcoveGoogleCast | |
@objc class CastPlayerViewController: UIViewController { | |
var officialLive: OfficialLiveResponse? | |
var videoContainer = UIView() | |
private let googleCastManager: BCOVGoogleCastManager = BCOVGoogleCastManager() | |
lazy var playerView: BCOVPUIPlayerView? = { | |
let options = BCOVPUIPlayerViewOptions() | |
options.presentingViewController = self | |
// Create PlayerUI views with normal VOD controls. | |
let controlView = BCOVPUIBasicControlView.withVODLayout() | |
guard let _playerView = BCOVPUIPlayerView(playbackController: nil, options: options, controlsView: controlView) else { | |
return nil | |
} | |
// Add to parent view | |
self.videoContainer.addSubview(_playerView) | |
_playerView.translatesAutoresizingMaskIntoConstraints = false | |
_playerView.snp.makeConstraints { make in | |
make.top.bottom.leading.trailing.equalToSuperview() | |
} | |
return _playerView | |
}() | |
lazy var playbackController: BCOVPlaybackController? = { | |
guard let _playbackController = BCOVPlayerSDKManager.shared()?.createPlaybackController() else { | |
return nil | |
} | |
_playbackController.isAutoAdvance = true | |
_playbackController.isAutoPlay = true | |
_playbackController.delegate = self | |
_playbackController.add(googleCastManager) | |
return _playbackController | |
}() | |
override var preferredStatusBarStyle: UIStatusBarStyle { | |
.lightContent | |
} | |
override var shouldAutorotate: Bool { | |
true | |
} | |
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { | |
super.viewWillTransition(to: size, with: coordinator) | |
if UIDevice.current.orientation.isLandscape { | |
hide() | |
view.backgroundColor = UIColor.black | |
} else { | |
self.show() | |
view.backgroundColor = UIColor.white | |
} | |
} | |
// MARK: - View Lifecycle | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
guard let live = officialLive else { | |
return | |
} | |
navigationItem.title = live.title | |
view.backgroundColor = UIColor.white | |
view.addSubview(videoContainer) | |
let height = UIScreen.main.bounds.width * 9.0 / 16.0 | |
videoContainer.snp.makeConstraints { make in | |
make.top.equalTo(view.safeAreaLayoutGuide.snp.top) | |
make.leading.trailing.equalToSuperview() | |
make.height.equalTo(height) | |
} | |
videoContainer.isHidden = true | |
googleCastManager.delegate = self | |
let castButton = GCKUICastButton(frame: CGRect(x: 0, y: 0, width: 24, height: 24)) | |
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: castButton) | |
NotificationCenter.default.addObserver(self, selector: #selector(castStateDidChange), | |
name: NSNotification.Name.gckCastStateDidChange, | |
object: GCKCastContext.sharedInstance()) | |
playerView?.playbackController = playbackController | |
requestPlaylist(item: live) | |
} | |
// MARK: - Misc | |
private func requestPlaylist(item: OfficialLiveResponse) { | |
let playbackService = BCOVPlaybackService(accountId: item.account, policyKey: item.policyKey) | |
playbackService?.findVideo(withVideoID: item.videoId, parameters: nil, completion: { [weak self] (video: BCOVVideo?, json: [AnyHashable: Any]?, error: Error?) in | |
guard let _video = video else { | |
print("PlayerViewController Debug - Error retrieving video playlist") | |
return | |
} | |
self?.videoContainer.isHidden = GCKCastContext.sharedInstance().castState == .connected | |
self?.playbackController?.setVideos([_video] as NSArray) | |
}) | |
} | |
// MARK: - Notification Handlers | |
@objc private func castStateDidChange(_ notification: Notification) { | |
let state = GCKCastContext.sharedInstance().castState | |
switch state { | |
case .noDevicesAvailable: | |
print("No cast devices available") | |
break | |
case .connected: | |
print("Cast device connected") | |
break | |
case .connecting: | |
print("Cast device connecting") | |
break | |
case .notConnected: | |
print("Cast device not connected") | |
break | |
default: | |
break | |
} | |
} | |
} | |
// MARK: - BCOVPlaybackControllerDelegate | |
extension CastPlayerViewController: BCOVPlaybackControllerDelegate { | |
func playbackController(_ controller: BCOVPlaybackController!, playbackSession session: BCOVPlaybackSession!, didReceive lifecycleEvent: BCOVPlaybackSessionLifecycleEvent!) { | |
if lifecycleEvent.eventType == kBCOVPlaybackSessionLifecycleEventEnd { | |
videoContainer.isHidden = true | |
} | |
} | |
} | |
// MARK: - BCOVGoogleCastManagerDelegate | |
extension CastPlayerViewController: BCOVGoogleCastManagerDelegate { | |
func switched(toLocalPlayback lastKnownStreamPosition: TimeInterval, withError error: Error?) { | |
if lastKnownStreamPosition > 0 { | |
playbackController?.play() | |
} | |
videoContainer.isHidden = false | |
if let _error = error { | |
print("Switched to local playback with error: \(_error.localizedDescription)") | |
} | |
} | |
func switchedToRemotePlayback() { | |
videoContainer.isHidden = true | |
} | |
func currentCastedVideoDidComplete() { | |
videoContainer.isHidden = true | |
} | |
func castedVideoFailedToPlay() { | |
print("Failed to play casted video") | |
} | |
func suitableSourceNotFound() { | |
print("Suitable source for video not found!") | |
//dismiss(animated: true, completion: nil) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment