GithubHelp home page GithubHelp logo

mhmiles / opencastswift Goto Github PK

View Code? Open in Web Editor NEW
112.0 6.0 26.0 1.11 MB

An open source implementation of the Google Cast SDK written in Swift

License: MIT License

Ruby 0.48% Swift 99.23% Objective-C 0.29%
swift macos casting chromecast google-cast

opencastswift's Introduction

OpenCastSwift: An open source implementation of the Google Cast SDK written in Swift

Carthage Compatible GitHub release Swift 4.1 platforms

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

OS support

I've tested this to work on macOS 10.12 and iOS 11. It may work on earlier versions, I just haven't tested it. Sample apps with some basic functionality are included for both macOS and iOS. The iOS app is more built-out with a working example of casting an audio stream.

This framework fails build for watchOS because watchOS does not support SSL over CFStream sockets. I've left the target in this project in hopes that support is added in a future version of watchOS ๐Ÿคž๐Ÿคž.

Basic usage

Finding Google Cast devices on the network

import OpenCastSwift

var scanner = CastDeviceScanner()

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

scanner.startScanning()

It's also possible to receive device list changes by setting the scanner's delegate.

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.

import OpenCastSwift

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

Getting information about status changes

Implement the CastClientDelegate protocol to get information about the connection and the device's status:

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:

// appId is the unique identifier of the caster app to launch. The CastAppIdentifier struct contains the identifiers of the default generic media player, YouTube, and Google Assistant.

client.launch(appId: CastAppIdentifier.defaultMediaPlayer) { [weak self] result in
		switch result {
		case .success(let app):
	    // here you would probably call client.load() to load some media

		case .failure(let error):
			print(error)
		}

}

Joining an app

To connect to an existing app session, you use the join method on CastClient:

// appId is the unique identifier of the caster app to join. A value of nil will cause the client to attempt to connect to the currently running app.

client.join() { [weak self] result in
		switch result {
		case .success(let app):
	    // here you would probably call client.load() to load some media

		case .failure(let error):
			print(error)
		}

}

Loading media

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

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) { result in
          switch result {
          case .success(let status):
            print(status)

          case .failure(let error):
            print(error)
          }
    }

    // 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.

func updateStatus() {
	// app is a CastApp instance you got after launching the app

	client.requestMediaStatus(for: app) { result in
      switch result {
      case .success(let status):
        print(status)

      case .failure(let error):
        print(error)
      }
	}
}

Implemented features

  • Discover cast devices on the local network
  • Launch, join, leave, and quit cast applications
  • Playback and volume controls for both devices and groups
  • Custom channels via subclassing CastChannel
  • Send and receive binary payloads

There is even some stubbed out functionality for undocumented features like device setup, certificate validation, and renaming. Contributions are always appreciated. ๐Ÿ˜„

Apps that use OpenCastSwift

  • CastSync - A macOS menu bar app for syncing playback from your Google Cast device to iTunes or VLC on your computer

Thanks

opencastswift's People

Contributors

mhmiles avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

opencastswift's Issues

Error when testing the sample app on MacOS

I'm Getting a nw_resolver_start_query_timer_block_invoke [C1] Query fired: did not receive both families in time for 8c3a638c-89a9-b15b-a9e1-6826acf9ee64.local.:8009 Error in Xcode when trying to connect to a chromecast using the sample app provided. Currently testing on a mac running MacOS 10.15.4 and xcode version 11.4.1 (11E503a). Anyone have a solution for this?

How to cast a website to smart TV ?

Hello,

I want to cast website to smart TV. for example I want to load "www.google.com" in my iPhone and cast it to TV. How can I do that ?

What I will have to change in below code ?

 client.launch(appId: CastAppIdentifier.defaultMediaPlayer) { (result) in
           switch result {
           case .success(let app):
               let media = CastMedia(title: "TEST CAST", url: URL(string: "http://traffic.libsyn.com/billburr/MMPC_8-1-16.mp3")!, contentType: "audio/mp3")

               self.client.load(media: media, with: app) { result in
                   switch result {
                   case .success(let status):
                       print(status)

                   case .failure(let error):
                       print(error)
                   }
               }

           case .failure(let error):
               print(error)
           }
       }

Doesn't seem to work with YouTube anymore

The default media player works fine with MP4 URLs, but if I directly try to launch the YouTube app with client.launch(appId: "YouTube"), the result object is always a failure, stating:

launch("Unable to get launched app instance")

Did YouTube break it completely, or am I doing something silly?

ios 14

any idea why and app on ios 14 doesn't work ?
Using the demo app, I get "Started scanning", but nothing else... scanner.isScanning returns false
There is no prompt for the LocalNetwork permissions....

Custom Channels

I have an app that I need to launch in Chromecast,
after client.launch(appID: <some string>) it says "No channel attached for namespace : ".
Can you help me out with this?

Status of the repository

I've been planning to remove the GoogleCast dependency for a long time and this repo seems to be exactly what I'm looking for but the last commit is from three years ago. Is anyone using it for production apps and has had any problems with changes to the Cast protocol being incompatible with the current state of this framework?

Also, maybe it's possible to drop all dependencies but swift-protobuf and add support for spm.

In case someone is interested I could take a look at spm support.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.