How to properly connect to Google Cast device and cast an url with an custom receiver?

跟風遠走 提交于 2019-12-24 14:23:02

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!