Skip to content

Instantly share code, notes, and snippets.

@nickv2002
Last active October 21, 2021 06:19
Show Gist options
  • Save nickv2002/b7bb28cdccc000bdb910 to your computer and use it in GitHub Desktop.
Save nickv2002/b7bb28cdccc000bdb910 to your computer and use it in GitHub Desktop.
Swift code to play YouTube videos on AppleTV tvOS via a TVJS call using XCDYouTubeKit
//
// Created by Nick Vance on 12/4/15.
// Copyright © 2015 ToWatchList. All rights reserved.
//
import AVKit
import XCDYouTubeKit
import TVMLKit
class YTPlayerViewController: AVPlayerViewController, AVPlayerViewControllerDelegate {
//call this method once after setting up your appController.
func createPlayYT( appController:TVApplicationController ){
//allows us to access the javascript context
appController.evaluateInJavaScriptContext({(evaluation: JSContext) -> Void in
//this is the block that will be called when javascript calls playYTblock(videoIdentifier)
let playYTblock : @convention(block) (String) -> Void = {
(videoIdentifier : String) -> Void in
print("Playing YouTube Video with ID:", videoIdentifier)
let playerViewController = AVPlayerViewController()
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
// topController should now be your topmost view controller
topController.presentViewController(playerViewController, animated: true, completion: nil)
XCDYouTubeClient.defaultClient().getVideoWithIdentifier(videoIdentifier) { [weak playerViewController] (video: XCDYouTubeVideo?, error: NSError?) in
if let streamURL = (video?.streamURLs[XCDYouTubeVideoQualityHTTPLiveStreaming] ??
video?.streamURLs[XCDYouTubeVideoQuality.HD720.rawValue] ??
video?.streamURLs[XCDYouTubeVideoQuality.Medium360.rawValue] ??
video?.streamURLs[XCDYouTubeVideoQuality.Small240.rawValue]) {
playerViewController?.player = AVPlayer(URL: streamURL)
playerViewController?.player?.play()
playerViewController?.player?.actionAtItemEnd = AVPlayerActionAtItemEnd.None
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "playerItemDidReachEnd:",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: playerViewController?.player?.currentItem)
} else {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
}
}
//this creates a function in the javascript context called "playYTblock".
//calling playYTblock(videoIdentifier) in javascript will call the block we created above.
evaluation.setObject(unsafeBitCast(playYTblock, AnyObject.self), forKeyedSubscript: "playYTblock")
}, completion: {(Bool) -> Void in
//evaluation block finished running
})
}
func playerItemDidReachEnd(notification: NSNotification) {
print("Video reached end! Dismiss player")
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
// topController should now be your topmost view controller
topController.dismissViewControllerAnimated(true, completion: nil)
}
}
}
@ryanreece
Copy link

Here's a gist updated for TVOS 10 based on 0xced's Stack Overflow comment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment