Google Cast(Chromecast)浏览器 SDK 学习笔记(一)

前几天由于京东打折,买了个索尼的 SRS-X77 音箱,看说明书说支持 Google Cast,试了试感受还挺好用,因而研究了一下 Google Cast 的 SDK。javascript

Chromecast、Google Cast 傻傻分不清楚?

Google 在 2013 年推出了一个叫 Chromecast 的硬件,它运行一个精简版的 Chrome OS,用户可使用手机或者电脑(Chrome 浏览器)来控制它播放网络或者本地的视频、照片等。Google 随之发布了适用于 iOS、Android 和 Chrome 浏览器的 SDK。2015 年,Google 又发布了 Chromecast Audio,它没有 HDMI 接口,只能播放音频。Google 给Chromecast 使用的这套技术命名为 Google Cast。java

也就是说, Chromecast 是 Google 推出的硬件产品的名称,Google Cast 指的是是这套经过网络播放媒体技术,好比对应苹果的 AirPlay。除了 Chromecast 系列硬件自己,Android TV 也支持做为 Google Cast 的接收端,此外,索尼、LG 等厂商也制造了一些支持 Google Cast 的音响系统,固然也就包含了我买的索尼 SRS-X 系列。web

Google Cast 大体工做原理

发送端 app(sender app)使用 SDK,将须要播放的媒体的信息发送到 Google 的服务器,服务器再通知接收端播放(因此发送端和接收端必须均可以访问 Google 的服务器才行)。接收端运行的是一个浏览器,它会根据发送端的app ID和媒体信息,去载入对应的一个网页这个网页(receiver app)也是由发送端 app 的开发者提供的,的将会负责播放相应的媒体内容。即便接收端时 Chromecast Audio 之类只能播放音频的硬件,这个网页也是会载入并渲染的。chrome

Google Cast 和 DLNA 或者苹果的 AirPlay 不一样之处,一是依赖 Google 的服务器,也就是说必须链接到 Internet 才能够用,若是只有一个局域网是不行的。二是前两个的接收端播放器接收端自己提供的,开发者只须要提供要播放的内容就能够,可是 Google Cast 则是须要提供本身的receiver app,这样的好处是开发者能够高度定制(好比能够定制UI,或者加入弹幕、歌词滚动、音乐可视化之类复杂功能),虽然接收端每每运行的并非Android这样的开放操做系统,可是由于receiver app的本质是网页,因此开发难度并不高。api

不过,若是你不须要定制化的receiver app,Google也提供了一套默认的receiver app,拥有最基本的音视频播放的功能。浏览器

固然,以上只是根据我对 Google 的文档的理解总结的,若是有什么错误请指出。服务器

Google Cast 一些概念的介绍

  • 发送端(sender)
    能够是Chrome 浏览器(电脑版或者 Android 版)、Android 设备、iOS 设备。网络

  • 发送端 app(sender app)
    使用了 Google Cast SDK 的 app,能够是 web app(网页)也能够是 Android 或 iOS app。session

  • 接收端(receiver)
    支持做为接收端的硬件,如Chromecast、机顶盒、音箱、电视之类。app

  • 接收端 app(receiver app)
    接收端上运行的 app,由 sender 指定的 app ID 决定,其本质是网页,接收端上的浏览器将其载入并执行。

  • session
    Sender 首先要跟特定的 receiver 创建 session 才能相互通讯。创建 session 对于用户来讲就是“设备配对”的过程。

  • media
    Session 创建后,Sender 可使用 session 的 loadMedia 方法来告诉 receiver 播放媒体。若是 loadMedia 成功,Sender 会得到一个 media 对象。该对象反映了receiver app正在播放的媒体,其中包含了播放状态,播放队列等信息。

使用 SDK 制做一个简单的 sender app

下面咱们跟着官方教程,用 Chrome 浏览器的 SDK(Javascript)制做一个简单的 sender app。由于注册 app ID 要交五美圆因此我就直接使用默认的 receiver app 了。

引入 SDK

固然第一步就是在页面中引入 SDK:

<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script>

SDK使用了chrome.cast这个namespace。

初始化:

function onError(error) {
  console.log(error);
}

function onInitSuccess() {
  console.log('API successfully initialized');
}

function initializeCastApi() {
  const appID = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
  const sessionRequest = new chrome.cast.SessionRequest(applicationID);
  const apiConfig = new chrome.cast.ApiConfig(sessionRequest,
    sessionListener,
    receiverListener);
  chrome.cast.initialize(apiConfig, onInitSuccess, onError);
};

window['__onGCastApiAvailable'] = function(loaded, errorInfo) {
  if (loaded) {
    console.log('API available');
    initializeCastApi();
  } else {
    console.log(errorInfo);
  }
}

咱们须要监听__onGCastApiAvailable这个自定义事件,来执行 initializeCastApiinitializeCastApi 须要知道咱们的 app ID(若是使用默认的 receiver app 则使用 chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID 这个常量。sessionListenerreceiverListener 是什么呢?下面说。

receiverListener 就是当receiver的状态发生改变的时候触发的回调函数。Google Cast 使用 mDNS 协议来实现设备发现,当有receiver被发现或者消失的时候,这个函数想会被触发。好比咱们定义一个这样的 receiverListener

let receiverIsAvailable = false;
function receiverListener(receiverAvailability) {
  console.log(`Receiver is ${receiverAvailability}`);
  receiverIsAvailable = (receiverAvailability === chrome.cast.ReceiverAvailability.AVAILABLE);
}

一开始个人音箱处于关机状态,刷新页面,控制台显示:

Receiver is unavailable

而后我把音箱打开,并链接到网络,此时控制台显示:

Receiver is available

可见 receiverListener 的调用是实时的,可是这个函数并不知道有几个 receivers,更不知道 receivers 的具体信息——其惟一参数是一个字符串 unavailable 或者 available,将其与 chrome.cast.ReceiverAvailability.AVAILABLE 常量比较来肯定是否available。

sessionListener 是当存在 session 的时候调用的函数。当咱们第一次初始化页面的时候,尚未创建 session,因此这个函数并无被调用,可是若是咱们已经创建了 session,那么再次刷新这个页面时,SDK 便会发现已经存在的 session 并调用这个函数。在这个函数中咱们能够把 session 存储起来,供之后调用:

let currentSession = null;

function sessionListener(session) {
  currentSession = session;
  console.log('Current session updated');
}

创建 session(设备配对)

function onRequestSessionSuccess(session){
  console.log(session);
  currentSession = session;
  console.log('Current session updated');
}

function requestSession(){
  if(!currentSession){
    chrome.cast.requestSession(onRequestSessionSuccess, onError);
  }
}

设备配对须要客户端主动执行,好比咱们能够在页面上放一个按钮,用户按下的时候就执行 requestSession。执行后咱们能够看到 Chrome 弹出设备列表,这个列表是 Chrome 浏览器自己提供的:

设备选择界面1

能够看到个人音箱已经跟 Google Play Music 配对了,不过咱们须要它跟目前的页面配对,点击音箱名称,而后点击“投射”,音箱就会跟 Play Music 断开而后跟咱们这个页面创建 session。

设备选择界面2

若是创建 session 成功就会调用 onRequestSessionSuccess,这个函数跟前面说的 sessionListener 是差很少的。

把 session 打印出来,是这样的:

session

能够看到 session 是由 sender app 和 receiver 决定的,只有咱们创建了 session 才能获得具体的 receiver(以前咱们只知道 receiver 是否 avilable,不知道 receiver 有哪些),能够知道 receiver 能支持音频仍是视频等。当咱们再次载入页面的时候,由于 appId 相同,因此初始化阶段就能够触发 sessionListener 咱们能够这时就得到 session 而不须要再进行 requestSession 的操做了。注意个人音箱以前跟 Google Play Music 以前有一个 session 可是并无触发个人页面的 sessionListener,由于 appId 不一样。

播放媒体

如今有了 session,咱们终于能够命令 receiver 播放媒体了!

let currentMedia = null;

function onMediaDiscovered(how, media) {
  currentMedia = media;
}

function loadMedia(){
  const mediaInfo = new chrome.cast.media.MediaInfo('http://example.com/example.mp3');
  const request = new chrome.cast.media.LoadRequest(mediaInfo);
  session.loadMedia(request,
    onMediaDiscovered.bind(this, 'loadMedia'),
    onError);
}

执行完 loadMedia 不一会,应该就能够听到音箱发出声音了✌️。

返回的 media 对象能够用来控制播放:

currentMedia.pause();
currentMedia.play();
currentMedia.stop();
相关文章
相关标签/搜索