Skip to content

Instantly share code, notes, and snippets.

@dotkebi
Created May 17, 2022 14:33
Show Gist options
  • Save dotkebi/aeeef0b6d7d72e86b53b9f4fc6c74fa1 to your computer and use it in GitHub Desktop.
Save dotkebi/aeeef0b6d7d72e86b53b9f4fc6c74fa1 to your computer and use it in GitHub Desktop.
brightcove
//
// 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