An open API service indexing awesome lists of open source software.

https://github.com/insidegui/ChromeCastCore

An open source implementation of the Google Cast SDK for macOS
https://github.com/insidegui/ChromeCastCore

chromecast ios macos osx

Last synced: 3 months ago
JSON representation

An open source implementation of the Google Cast SDK for macOS

Awesome Lists containing this project

README

          

## ChromeCastCore: An open source implementation of the Google Cast SDK for macOS

This framework implements the Google Cast APIs so they can be used in macOS apps. Google provides an official SDK but it is only for iOS and closed source.

### 🐉 Here be dragons

This repository exists as a dependency for my [Apple Events](https://github.com/insidegui/AppleEvents) and [WWDC](/insidegui/WWDC) apps.

**Any external contribution that's outside the scope of the project and/or requires changes to the the apps mentioned above will not be accepted. If you're looking for a more generic library with support to more features and platforms, check out [OpenCastSwift](https://github.com/mhmiles/opencastswift).**

### OS Support

I have only tested on 10.12, but it should work on 10.11 and even on iOS (with some minor changes).

### Basic usage

### Finding ChromeCast devices on the network

```swift
import ChromeCastCore

var scanner = CastDeviceScanner()

NotificationCenter.default.addObserver(forName: DeviceScanner.DeviceListDidChange, object: scanner, queue: nil) { [unowned self] _ in
// self.scanner.devices contains the list of devices available
}

scanner.startScanning()
```

### Connecting to a device

`CastClient` is the class used to establish a connection and sending requests to a specific device, you instantiate it with a `CastDevice` instance received from `CastDeviceScanner`.

```swift
import ChromeCastCore

var client = CastClient(device: scanner.devices.first!)
client.connect()
```

### Getting information about status changes

`CastClient` currently implements two block-based callbacks for you to get notifications about status changes:

* `statusDidChange` is called when the device's overall status has changed (running apps, volume, etc)
* `mediaStatusDidChange` is called when the device's playback status has changed (current media item, current time, etc). NOTE: this is not called automatically during playback, you must send a request asking for the media info

You can also implement the `CastClientDelegate` protocol to get information about the connection and the device's status:

```swift
protocol CastClientDelegate {
optional func castClient(_ client: CastClient, willConnectTo device: CastDevice)
optional func castClient(_ client: CastClient, didConnectTo device: CastDevice)
optional func castClient(_ client: CastClient, didDisconnectFrom device: CastDevice)
optional func castClient(_ client: CastClient, connectionTo device: CastDevice, didFailWith error: NSError)

optional func castClient(_ client: CastClient, deviceStatusDidChange status: CastStatus)
optional func castClient(_ client: CastClient, mediaStatusDidChange status: CastMediaStatus)
}
```

### Launching an app

To launch an app on the device, you use the `launch` method on `CastClient`:

```swift
// .defaultMediaPlayer is the 'generic' player that can stream any video URL of a supported type
client.launch(appId: .defaultMediaPlayer) { [weak self] error, app in
guard let app = app else {
if let error = error {
NSLog("Error launching app: \(error)")
} else {
NSLog("Unknown error launching app")
}

return
}

// here you would probably call client.load(...) to load some media with the app,
// or hold onto the app instance to send commands to it later
}
```

Notice the `.defaultMediaPlayer` enum above, it represents the 'generic' player that can stream any supported video URL you send it. The framework only supports this and `.youTube` for now.

### Loading media

After you have an instance of `CastApp`, you can tell the client to load some media with it using the `load` method:

```swift
let videoURL = URL(string: "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8")!
let posterURL = URL(string: "https://i.imgur.com/GPgh0AN.jpg")!

// create a CastMedia object to hold media information
let media = CastMedia(title: "Test Bars",
url: videoURL,
poster: posterURL,
contentType: "application/vnd.apple.mpegurl",
streamType: CastMediaStreamType.buffered,
autoplay: true,
currentTime: 0)

// app is the instance of the app you got from the client after calling launch, or from the status callbacks
client.load(media: media, with: app) { error, status in
guard let status = status else {
if let error = error {
NSLog("Error loading media: \(error)")
} else {
NSLog("Unknown error loading media")
}

return
}

// this media has been successfully loaded, status contains the initial status for this media
// you can now call requestMediaStatus periodically to get updated media status
}
```

### Getting media status periodically

After you start streaming some media, you will probably want to get updated status every second, to update the UI. You should call the method `requestMediaStatus` on `CastClient`, this sends a request to the device to get the most recent media status, to get the response you must have registered a `mediaStatusDidChange` callback or implemented the `castClient(_ client: CastClient, mediaStatusDidChange status: CastMediaStatus)` delegate method.

```swift

func updateStatus() {
// app is a CastApp instance you got after launching the app
// mediaSessionId is the current media session id you got from the latest CastStatus
client.requestMediaStatus(for: app, mediaSessionId: status.mediaSessionId)
}

func castClient(_ client: CastClient, mediaStatusDidChange status: CastMediaStatus) {
NSLog("media status did change: \(status)")
}
```