问题
For creating this I used Google Cast reference at Github https://github.com/googlecast/CastHelloText-ios & https://github.com/googlecast/CastVideos-ios
Then if you downloaded it have a look at my block of code that has to do with Google Cast. If you see something that makes this error happen, please let me know. Because I honestly don't know if this a Xcode or a Google Cast bug.. or is the most common error.. Humans
Start the emulator, it wil look for active Chrome Cast devices in the network. If found the cast button wil appear. When you press the cast button it wil go to chooseDevice()
function and wil present a UIAlertController with the device(s) in your network and then you can select an device you want to cast to.
If you clicked on an device it wil go to connectToDevice()
function and make an connection.
When it's connected it should go to the next function called "deviceManagerDidConnect". So I get an message "Connected".. after 5 seconds I get an error message "Error Domain=com.google.GCKError Code=2. Network connection timeout". When I rebuild the project I get an different outcome.. after the "deviceManagerDidConnect" It is now going to "didConnectToCastApplication" function and that didn't happen the first time. Is this a bug or am I doing something wrong?
What I expect is that it is going to "deviceManagerDidConnect" and after that it is going to "didConnectToCastApplication" function. After that all works I want to cast a WKWebView.. I know that not (yet) supported. So I want to cast an URL I gave in an Textfield.
What version of the product are you using? On what operating system?
GoogleCastSDK-2.5.1-Release, OS X Yosemite 10.10.1
Xcode Version 6.1.1 (6A2008a)
Thanks in advance and have a great day,
feri
Below you can find my code..
// ==================== Google Cast ====================
// ==================== chooseDevice() ====================
func chooseDevice() {
if selectedDevice == nil {
let alertController = UIAlertController(title: "Choose device..", message: "", preferredStyle: .ActionSheet)
for device in deviceScanner.devices {
alertController.addAction(UIAlertAction(title: device.friendlyName, style: .Default, handler: { alertAction in
self.selectedDevice = device as GCKDevice
self.connectToDevice()
}))
}
let addCancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: { alertAction in
alertController.dismissViewControllerAnimated(true, completion: nil)
})
// Add action to the controller
alertController.addAction(addCancelAction)
// Finaly present the action controller
presentViewController(alertController, animated: true, completion: nil)
}
else {
updateButtonStates()
let mediaTitle = self.mediaInformation?.metadata.stringForKey(kGCKMetadataKeyTitle)
// mediaTitle.metadata.stringForKey(kGCKMetadataKeyTitle) //Silver Essence Castaway
// var mediaTitle = mediaInformation.metadata.stringForKey(kGCKMetadataKeyTitle)
NSLog("De waarde van kGCKMetadataKeyTitle is: \(kGCKMetadataKeyTitle)")
let alertController = UIAlertController(title: "Casting to: \(selectedDevice.friendlyName)", message: nil, preferredStyle: .ActionSheet)
let addDisconnectingAction = UIAlertAction(title: "Disconnect device", style: .Destructive, handler: { alertAction in
println("De waarde van mediaInformation is: \(mediaTitle)")
if mediaTitle != nil {
(mediaTitle != nil ? 1 : 0)
alertController.dismissViewControllerAnimated(true, completion: nil)
println("the else UIAlertController")
}
})
let addCancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: { alertAction in
println("De waarde van mediaInformation is: \(mediaTitle)")
if mediaTitle != nil {
(mediaTitle != nil ? 2 : 1)
alertController.dismissViewControllerAnimated(true, completion: nil)
println("else uiactionsheet")
}
})
// Add action to the controller
alertController.addAction(addDisconnectingAction)
alertController.addAction(addCancelAction)
// Finaly present the action controller
self.presentViewController(alertController, animated: true, completion: nil)
}
}
// ==================== updateStatsFromDevice() ====================
func updateStatsFromDevice() {
if mediaControlChannel != nil {
mediaInformation = mediaControlChannel.mediaStatus.mediaInformation
}
}
// ==================== isConnected() ====================
func isConnected() -> Bool {
return deviceManager.isConnected
}
// ==================== connectToDevice() ====================
func connectToDevice() {
if selectedDevice != nil {
// var info = NSBundle.mainBundle().infoDictionary!["CFBundleIdentifier"] as? NSString
// deviceManager = GCKDeviceManager(device: selectedDevice, clientPackageName: info)
deviceManager = GCKDeviceManager(device: selectedDevice, clientPackageName: "CFBundleIdentifier")
// NSLog("de waarde van info is \(info)")
NSLog("de waarde van selectedDevice is \(selectedDevice)")
deviceManager.delegate = self
deviceManager.connect()
}
}
// ==================== deviceDisconnected() ====================
func deviceDisconnected() {
NSLog("Device disconneted: \(selectedDevice.friendlyName)")
deviceManager = nil
selectedDevice = nil
mediaControlChannel = nil
textChannel = nil
}
// ==================== updateButtonStates() ====================
func updateButtonStates() {
if (deviceScanner.devices.count == 0) {
// Hide the cast button
chromecastButton.setImage(btnImage, forState: .Normal)
chromecastButton.hidden = true
}
if (deviceScanner.devices.count > 0) {
chromecastButton.setImage(btnImage, forState: .Normal)
chromecastButton.hidden = false
// Show cast button
if (deviceManager != nil) {
chromecastButton.setImage(btnImageSelected, forState: .Normal)
chromecastButton.hidden = false
}
}
}
// ==================== sendText ====================
@IBAction func sendText(sender: AnyObject) {
NSLog("Cast video")
if deviceManager == nil {
var alert = UIAlertController(title: "Not connected", message: "Please connect to Cast device", preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
presentViewController(alert, animated: true, completion: nil)
return
}
// Define media metadata
var metaData = GCKMediaMetadata(metadataType: GCKMediaMetadataType.User)
metaData.objectForKey("CFBundleVersion")
metaData.setString("Bug Bunny!", forKey: kGCKMetadataKeyTitle)
metaData.setString("dit is allemaal maar was subtitles", forKey: kGCKMetadataKeySubtitle)
var url = NSURL(string: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg")
metaData.addImage(GCKImage(URL: url, width: 480, height: 360))
// var mediaInformation = GCKMediaInformation(contentID: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4", streamType: .None, contentType: "video/mp4", metadata: metaData as GCKMediaMetadata, streamDuration: 0, customData: nil)
mediaInformation = GCKMediaInformation(contentID: "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4", streamType: GCKMediaStreamType.None, contentType: "video/mp4", metadata: metaData, streamDuration: 0, customData: nil)
NSLog("waarde van mediainformation is : \(mediaInformation)")
self.mediaControlChannel?.loadMedia(mediaInformation, autoplay: true, playPosition: 0)
// textChannel.sendTextMessage(textFieldUrl.text)
}
// MARK: GCKDeviceScannerListener
// ==================== deviceDidComeOnline() ====================
func deviceDidComeOnline(device: GCKDevice!) {
NSLog("device found! \(device.friendlyName)")
updateButtonStates()
}
// ==================== deviceDidGoOffline() ====================
func deviceDidGoOffline(device: GCKDevice!) {
NSLog("device did go offline \(device.friendlyName)")
updateButtonStates()
}
// MARK: UIActionSheetDelegate
// ==================== actionSheet() ====================
func actionSheet(actionSheet: UIActionSheet, clickedButtonAtIndex buttonIndex: Int) {
if selectedDevice == nil {
if buttonIndex < deviceScanner.devices.count {
selectedDevice = deviceScanner.devices[buttonIndex] as GCKDevice
NSLog("Selecting device: \(selectedDevice.friendlyName)")
connectToDevice()
}
}
else {
if buttonIndex == 1 {
NSLog("Disconnecting device: \(selectedDevice.friendlyName)")
deviceManager.leaveApplication()
deviceManager.disconnect()
deviceDisconnected()
updateButtonStates()
}
else if buttonIndex == 0 {
// Join the existing session
}
}
}
// MARK: GCKDeviceManagerDelegate
// ==================== deviceManagerDidConnect() ====================
func deviceManagerDidConnect(deviceManager: GCKDeviceManager!) {
NSLog("Connected!")
updateButtonStates()
self.deviceManager.launchApplication(kReceiverAppID)
}
// ==================== didConnectToCastApplication() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didConnectToCastApplication applicationMetadata: GCKApplicationMetadata!, sessionID: String!, launchedApplication: Bool) {
NSLog("application has launched")
// textChannel = HTCGTextChannel(namespace: "urn:x-cast:com.silver.essence.Silver")
// self.deviceManager.addChannel(textChannel)
mediaControlChannel = GCKMediaControlChannel()
mediaControlChannel.delegate = self
self.deviceManager.addChannel(mediaControlChannel)
mediaControlChannel.requestStatus()
}
// ==================== didFailToConnectToApplicationWithError() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didFailToConnectToApplicationWithError error: NSError!) {
showError(error)
deviceDisconnected()
updateButtonStates()
}
// ==================== didFailToConnectWithError() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didFailToConnectWithError error: NSError!) {
showError(error)
deviceDisconnected()
updateButtonStates()
}
// ==================== didDisconnectWithError() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didDisconnectWithError error: NSError!) {
NSLog("Received notification that device disconnected")
if error != nil {
showError(error)
}
deviceDisconnected()
updateButtonStates()
}
// ==================== didReceiveApplicationMetadata() ====================
func deviceManager(deviceManager: GCKDeviceManager!, didReceiveApplicationMetadata metadata: GCKApplicationMetadata!) {
applicationMetadata = metadata
}
// ==================== showError() ====================
func showError(error: NSError) {
var alert = UIAlertController(title: "Something went wrong", message: error.description, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
presentViewController(alert, animated: true, completion: nil)
}
// ==================== viewDidLoad() ====================
override func viewDidLoad() {
super.viewDidLoad()
self.loadNSUserDefaults()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "saveNSUserDefaults", name: "kSaveSwitchesStatesNotification", object: nil);
navigationItem.title = "Settings"
// ==================== Adding the Chromecast button ====================
// kReceiverAppID = kGCKMediaDefaultReceiverApplicationID
NSLog("de waarde van kReceiverAppID in viewDidLoad() is : \(kReceiverAppID)")
btnImage = UIImage(named: "icon-cast-identified")
btnImageSelected = UIImage(named: "icon-cast-connected")
chromecastButton = UIButton()
chromecastButton.setImage(UIImage(named: "icon-cast-identified"), forState: .Normal)
chromecastButton.frame = CGRectMake(0, 0, 45, 45)
chromecastButton.addTarget(self, action: "chooseDevice", forControlEvents: .TouchUpInside)
chromecastButton.hidden = true
var rightItem:UIBarButtonItem = UIBarButtonItem()
rightItem.customView = chromecastButton
self.navigationItem.leftBarButtonItem = rightItem
// ==================== Scan for Chromecast devices ====================
deviceScanner = GCKDeviceScanner()
filterCriteria = GCKFilterCriteria(forAvailableApplicationWithID: kReceiverAppID)
deviceScanner.filterCriteria = filterCriteria
deviceScanner.addListener(self)
deviceScanner.startScan()
}
回答1:
finally I found the problem! It was in the receiver. The HTML file that the receiver is loading when you connect to a cast device in your network. Make sure that your HTML file has the proper functions to connect back to the application. Hope this will help someone who is encounter the same problem and not to think about the solution for weeks..
If you don't know which functions are needed look at the examples that Google have provided us. https://github.com/googlecast/
来源:https://stackoverflow.com/questions/27841273/how-to-properly-connect-to-google-cast-device-and-cast-an-url-with-an-custom-rec