2014年8月4日 星期一

Chromecast 開發經驗

Google 的 Chromecast 於 2014 年 6 月在日本開賣了,由於我們的產品在日本是開放下載與付費的,所以比國內的其他公司較早接觸到這項新產品,此文章簡單的介紹 Google Cast 的使用、功能實作流程與開發上的常見錯誤。

開發文件:Google Cast
官方網站:Chromecast
設定軟體:Android AppiOS App

在使用 Chromecast ( 亦稱 Google Cast ) 之前,有兩個名詞必須先知道,一個是 Sender App 另一個是 Receiver App,所謂的 Sender App 指的是 Phone、Tablet、Chrome 上面用來瀏覽影音資訊的應用程式,而 Receiver 指的是透過 HDMI 介面接上 Chromecast 的大螢幕,可能是電視或一般的螢幕,在 Sender App 實作完 Google Cast 的相關功能後,用戶會多了一項播放目標可以選擇,除了原先 App 內的播放介面之外,用戶還可以選擇由 Receiver 端來播放,目前 Google Cast 有提供三個平台的 Sender SDK ,分別是 Android,iOS,Chrome,初次接觸的用戶可以透過這三個平台下的 YouTube 學習 Chromecast 的使用者經驗。

在安裝 Chromecast 方面,可以透過 Mac、Android、iOS 上下載 Chromecast App 找到新的 Chromecast 裝置,並且連接上後為它設定 Wifi 環境及裝置名稱,設定好之後即可讓你的 Sender App 在同樣的無線網路環境下搜尋到這個新裝置。

在前一段有提到 Sender App 與 Receiver App 兩個名詞,但 Receiver App 並不是執行在 Android 框架上的應用程式,而是執行在 Chrome 上的 Web Application,必須使用 HTML + JavaScript 開發,在開發 Receiver App 時難免需要測試網頁的執行狀況,在測試方面 Google 提供了一個介面連接 Chromecast 裝置並查看狀態,只要在同一個無線網路環境下瀏覽 http://{chromecast-device-ip}:9222 即可連接到該裝置的 Debug Mode,這裡可能會發生第一個常見的錯誤,如果你的 Browser 提示找不到這個網頁,請檢查 Chromecast App 的設定頁中,是否沒有勾選 "檢查更新時將這個 Chromecast 的序號傳送給 Google" 這個項目,請勾選它並且重新啟動,找不到網頁的狀況即可排除。

和 Receiver 相比較,Sender App 的撰寫相對容易且單純,只要裝 SDK 中的 RemoteMediaPlayer 當作一個介面比較不一樣的播放器,再根據用戶是否有連接 Chromecast 裝置,去選擇在原本 App 內的播放器播放還是由 RemoteMediaPlayet 播放即可,注意一些連線與斷線的細節即可,而在開發撰寫 Receiver App 之前,面臨到的第一個問題是評估該選擇哪一種 Receiver App 的類型,文件上列出 3 種。

1. Default Media Receiver
2. Styled Media Receiver
3. Custom Receiver

第一種與第二種在行為上是一模一樣的,只是 Styled Media Receiver 比 Default 多了客制 Background、Logo、Splash、Watermark 等選項,這些內容必須使用一個 css 檔案來管理,並且申請一個 Receiver Application Id 後,將這個 css 檔案的連結提供給 Google 與這個 Application Id 相對應,Chromecast 即可在 Sender 連上並傳送 Application Id 後,知道該開啟哪一種 App 與載入哪一個 css 檔案,第三種 Custom Receiver 指的是自己製作 Web App 所以客製程度是沒有限制的,比較需要注意的是第二種、第三種所要提供的 css 與 web URL 必須是 https 的連結,這對一般的個人玩家來說算一個門檻。

Receiver App 雖然不用上架,但卻有一個註冊的流程,剛才說過,Sender 連接上 Receiver 時必須傳送一個 Application Id 告知 Chromecast 開啟哪一個應用程式,第二、三種 Receiver App 必須由開發者自己申請及註冊 Application Id,申請時每個開發者帳號需付美金 5 元,一個帳號底下可以建立數個應用程式,當然一個 Receiver App 對應多個 Sender App 也是可以辦得到的。第一種 Default Media Receiver 因為不需要開啟任何客制的項目,所以不必申請 Application Id,但 Sender 仍需送一個 Application Id 給 Chromecast,這是一個固定的值,常數名稱為 DEFAULT_MEDIA_RECEIVER_APPLICATION_ID

開發 Receiver App 於測試階段,應該會發現裝置的解晰度會無預期的改變導致 Web 畫面僅顯示部份之類的狀況發生,這是因為 Chromecast 目前在某些階段僅能顯示最高 720p ( 1280*720 ) 的解晰度,即便它的介面是 1080p 的 HDMI 也如此,所以在製作 Splash、Background 等圖片時,最好是以 720p 的解晰度去設計,而開發 Web 時,應該用 Width="40%" 這種百分比的寫法,而非使用 Width="768" 這種寫法,以確保 Web 在 720p 與 1080p 的解晰度下皆能顯示正常。

在 Sender 與 Receiver 溝通方面,必須先參考各自的 Google Cast Library,以 Sender 來說需要 Google Play Service 與 Support Library 兩個,如果是使用 Android Studio 與 Gradle 的開發者,在這種情況下相較於使用 ADT 的開發者來得方便,僅需在 build.gradle 的 dependencies 增加以下兩行即可,可大幅減少專案所佔用的容量

dependencies {
    compile 'com.android.support:mediarouter-v7:19.1.+'
    compile 'com.google.android.gms:play-services:4.4.52'
}

在訊息溝通及播放影音方面,有兩個最重要的 Method 必須了解,第一個是用來通知 Receiver 載入一個 MediaInfo,Sender 與 Receiver 所對應的 API 與 Event 如下

// Sender App
RemoteMediaPlayer.load

// Receiver App
window.mediaElement = document.getElementById(‘player');
window.mediaManager = new cast.receiver.MediaManager(window.mediaElement);
window.mediaManager.onLoad

另一個用來從 Sender 傳送一個字串訊息,Receiver 可接受也可回傳訊息至 Sender

// Sender App
Cast.CastApi.sendMessage

// Receiver App
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
window.messageBus = window.castReceiverManager.getCastMessageBus('urn:x-cast:com.ascii.castpractice');
window.messageBus.onMessage

如果想要簡單的測試 Styled 及 Custom Receiver,我撰寫了一個可以看出解晰度變化的範例於此:AsciiHuang/CastPractice.git

也可以到此:Samples for Google Cast SDKs 下載 Google 的官方範例。

如果使用任一個範例改成自己申請的 Application Id 後,發現 MediaRouterButton 持續顯示 Disabled 的狀態,大部份原因是你的 Application Id 還沒有 published 完成,不妨試試使用上面提過的 DEFAULT_MEDIA_RECEIVER_APPLICATION_ID 這個 Id 來測試,如果這個 Default Receiver Id 是可以用的,即代表你的 App Id 還無法使用,必須為 Published 並等待一段時間。


1 則留言:

  1. 請問,我將手機當WebServer,寄送本機影片URL給chromecast播放,但是有時會發生chromecast那邊讀取條跑不完得狀態,發生後就再也無法丟資料了,您是否有類似狀況!?

    回覆刪除