iOSからchromecastへRemote Display #4
(前回記事)
remote display APIをプロジェクトに追加
前回は、google cast APIのプロジェクトへの取り込みは行なったが、remote display APIはまだでした。このAPIのプロジェクトへの追加から始める。
追加なんて簡単。google cast APIの時と同様に、以下の手順でframeworkを追加。
- プロジェクトルートにGoogleCastRemoteDisplay.framework ディレクトリをコピー
- finder上でGoogleCastRemoteDisplay.frameworkを選択し、xcodeにD&D
あらら。エラーが出る出る。
出てきたエラーをググると、ここにあたった。
書いてある通り、Other Linker Flagsに以下を追加
("Undefined symbols"エラーを、Other Linker Flagsで解決することが可能なのね・・・)
-lsqlite3 -lz
これで、エラーが30個くらいから4個まで減ったが、まだある。今後はこっち。
書いてある通り、CoreMedia.frameworkをプロジェクトに追加。ビルドエラーなくなった!
ん?こんな、マニュアルに書いてもいない適当な手順で進めていいのかって?
いいんです!悪いのはマニュアル(笑) 動けばOK^^
(appleさんが標準で持っているframeworkを使っているだけだしね)
これでエラーは無くなったが、 警告がまだある。
GCKRemoteDisplaySessionのヘッダ読み込み部分で、
Missing submodule 'AVFoundation.AVAudioTypes'
と言う警告が出る。気持ち悪いので対処。
umbrella headerだけあればいいとのこと(そりゃそうだよね。昔は存在してなかったと言うことか・・・?)なので、警告発生行を、
before:
#import <AVFoundation/AVAudioTypes.h>
after:
#import <AVFoundation/AVFoundation.h>
に変更。
そのとき、「frameworkの中のソース、変更しちゃっていいの?」と言う警告のポップアップが出るが、unlockを押す。
“GCKRemoteDisplaySession.h” is locked for editing and you may not be able to save your changes. Do you want to unlock it?
2箇所変更したら、警告0になりましたー。
remote display のimport時のエラー
remoteDisplayを実装するには、"GCKRemoteDisplayChannelDelegate"と言うプロトコルを使用するのだが、これを下記のように書くと、エラーになってしまう。
普通に、 "import GoogleCastRemoteDisplay" のimport文がないからそうなってると思うのだが、普通に"import GoogleCastRemoteDisplay" と書こうとしても、「GoogleCastRemoteDisplayなんてものはありません」と怒られる。。。
なんでGoogleCast はimportできてるのに、こっちはできないんだ・・・
サンプルソースを見ると、objective-cなのだが、
#import <GoogleCast/GoogleCast.h>
#import <GoogleCastRemoteDisplay/GoogleCastRemoteDisplay.h>
と書いてある。普通にimportできてるよねぇ。
よくわからないながら、いろいろやっていると、以下をやったらエラーがなくなった!
1. Test.h / Test.mのobjective-cのファイルを作成
2. 作成時に「Bridging Headerを作るか?」と聞かれるのでYES
3. 作成されたTest.hに、上記2つのimport文を記述
remote display のコード実装
ついに、全ての準備は整った。コードです。
remote displayでは、receiverに表示するframeを管理する、frameInputと言うobjectを使うのだが、公式サイトのマニュアルでは、それがmetalをベースとしたGCKMetalVideoFrameInputと言う実装クラスを使って実現している。
今回やろうとしているサイネージアプリでは、単純にUIViewの上に乗っているものをcastしてくれれば良いのだが、そんな仕組みではないのか!?
・・・ありました。
GCKMetalVideoFrameInputの親クラス:GCKVideoFrameInputには、3つの実装クラスがあって、前述のmetalベースのものの他に、以下がある。
GCKOpenGLESVideoFrameInput GCKViewVideoFrameInput
名前だけで判断すると、GCKViewVideoFrameInputを使用すれば、なんだかうまく行きそう^^;
と言うわけで、もろもろ調べてやってみましたー。
できた!
ちゃんと画面にviewが表示されました!
animateの処理は、ボタンを押すことで呼び出すようにしていて、単純にviewの色が徐々に変わるアニメーションをつけてます。chromecastでどのくらい滑らかに表示されるかを見るために。
現在テストしているchromecast環境は、Wi-Fiルータとテレビが離れていて、Wi-Fiの扇マークが3つ中2つって感じ。
携帯もほぼ同じ場所にいるので、あまりネットワーク環境としては良くないのだが、それでもそれなりに色の変化はそれっぽく表示されてくれた。
今回のソースは、(自分で)わかりやすくするために、エラー処理を敢えて抜いて描いてますが、きちんとしたアプリにはエラー処理は不可欠なので、そこはreferenceなりみながらやってみてください^^;
では、良いgooglecast lifeを!^^
iOSからchromecastへRemote Display #3
(前回記事)
swiftプロジェクトの準備
Develop iOS Sender App with Cast v2 | Cast | Google Developers
引き続き、このサイトに書いてある通りに進める。
真ん中くらいにある"iOS Development"から。
First, follow the guide, iOS Sender App Development to get started with building your app for remote display. Follow the procedures in that document up to, but not including, Launch application before following the procedures in this guide.
まずは、iOS Sender App Developmentのリンク先の手順をやりなさいと。Launch applicationの前の手順まで。
cocoapodsを使用するのが推奨、と書いてあるが、正しいPodfileの記述の例が見当たらなかったので、sampleに倣って進めてみる。
sampleタブから以下のリンクに行くことで、"CastRemoteDisplay-iOS"のソースを取得。
Develop iOS Sender App with Cast v2 | Cast | Google Developers
ダウンロードしたプロジェクトに対し、以下の設定を変更。
1. pod install
2. Build SettingsのSigningを正しく設定
3. Bundle Identifierを適当に変更
・・・その他、いろいろ足掻いてみるが、なかなかビルドエラーが取れない。
xcconfigの設定とか複雑で、知識不足のたなやんにはよくわからない・・・
というわけで、マニュアルに書いてある、手動設定の方の手順で行きます^^;
ただし、使用する外部モジュールは、cocoapodでdownloadしたものにする。
※バージョンは以下。
Installing google-cast-remote-display-sdk (2.10.4) Installing google-cast-sdk (2.10.4.1)
(必要なモジュールのインストールと各種初期設定)
- create a new xcode project から新規プロジェクト作成(single view app, swift)
- Build SettingsのSigningを正しく設定
- Bundle IDを、Google Cast SDK Developer Console で設定したApplication IDに対応するものに設定(google cast sdkは、Bundle IDを見ておらず、applicationIDのみで判断しているように見えるが念のため)
- Other Linker Flagsに追加
In your Xcode project, set the Other Linker Flags to
-ObjC
- 必要なframeworkの追加
とりあえず、GoogleCast.framework以外のものを一通り指定。
その後、以下の通りにGoogleCast.frameworkを追加。
5-1. このxcodeプロジェクトのルートディレクトリに、GoogleCast.frameworkをコピー(コンソールなどから)
5-2. GoogleCast.frameworkの中にある"GoogleCastResources.bundle"を、framework直下のディレクトリから、その親ディレクトリ(framework外)に移動。framework内にそのファイルがあると、以下のリンク先のエラーが発生する。
stackoverflow.com
5-3. このframeworkをD&Dでxcode上に設置。コピーはせずreferenceで。
5-4. 5-3までで、Target > GeneralのLinked Frameworks and Librariesの中にGoogleCast.frameworkが入っていると思うが、なければ追加(Embedded Binariesには入れない)
swiftコード記述(google cast sender API部分。remote display APIは次で^^;)
やっと、コードを書きます。本来のゴールはremote displayなのだが、ベースとしてgoogle cast sdk自体をわかっておかないと辛そうなので、まずはそこから。
事前準備として、scanするのをボタントリガーとするためボタンを追加。
そして、そのボタンを押すとscan() メソッドが呼ばれるように設定し、以下のコードを記述。
おお!できた!
googleさんが用意しているサンプル動画が、テレビに流れましたー。
複数のchromecast端末から対象を選択するところとかはとりあえず省いちゃったけど、これくらいの方が入り口としてはわかりやすいよね^^;
処理の流れとしては、以下のイメージ。
- deviceScanner.startScan() で、存在する端末を取得。
(ただし、存在することがわかっているのであれば、省略も可能。) - chromecastとonlineになった後に呼ばれるGCKDeviceScannerListener#deviceDidComeOnline() で、onlineになった(connectとはまた別なので用語に注意)端末とconnect
- 接続後に呼ばれるGCKDeviceManagerDelegate#deviceManagerDidConnect() で、アプリ起動
- アプリ起動後に呼ばれるGCKDeviceManagerDelegate#deviceManager(didConnectToCastApplication:) で、アプリからchromecastに渡すデータを処理して、渡す
では、次はついにremote displayの実装行きます!
iOSからchromecastへRemote Display #2
(前回記事)yo-tan.hatenablog.com
本家サイトの読み込み
さて、能書きはこれくらいにして、実際の作業に入って行きましょー。
今回やりたいのは「Remote Display」。
どうやら、自分で自由に、テレビに表示するものを作れるようだ。
Remote Display | Cast | Google Developers
いきなりこんなこと書かれると、やる気削がれるねぇ・・・既に更新が止まっていて、今後消えゆくAPIなのか・・・?
まぁ、理解できていない「CAF」は使わなくていいみたいだから、一旦気にしないことにしよう^^;
そして、まだベータ版なの・・・大丈夫かねこれ。。
んっ!でも(まだ)くじけないっ!くじけそうっ(笑)
Google Cast SDK Developer Console
順番的にはあとから気づいたんだけど、先に書いておきます。
remote display APIを使用するためには、"Google Cast SDK Developer Console"への登録が必要となる。登録料$5です。
前述のremote displayのサイトの一番下に書いてあるんですが、$5とはいえ金がかかることは一番最初に書いてくれ・・・
Google Cast SDK Developer Console
こんな画面です。
で、Applicationは、登録するとApplication IDが発行される(画面キャプチャ上は一応Application IDをマスクしてます)。
そのIDは、ソースコードに埋め込んで使用する。これはOK。
その下にある、Device。どうやらchromecastでテストするためには、その機器のserialを登録しておく必要があるらしい。
しかし、"ADD NEW DEVICES"ボタンがdisabledになっていて押せない・・・
画面上部には"NOTE: Developer devices cannot be added at this time."と書いてある。。
どうやら、3日前とかの投稿だから、最近になって発生している模様。。。
これは解決するまで待つしかないか・・・
(2018/7/11)直った!
Seems Google has resolved this. I am no longer seeing this message on Registration page
「なんだかgoogleが直したみたい。その(エラー)メッセージ、もう表示されてないね」
って、、、天下のGoogleさん、有料のサイトを2週間も使えなくしておいて、直りましたもごめんなさいも何もなし・・・?
「直したみたい」の一般人コメントで終わりとは・・・このサイト自体、googleが管理するサイトなのに・・・ほんとひどいなgoogle。
と言うわけで、以下サイトの下の"Devices"のところをみてSerialを取得、登録は、サイト見ればできましたー。
Registration | Cast | Google Developers
さて、次は実装。続くっ
iOSからchromecastへRemote Display #1
iPhoneアプリで、サイネージ系のアプリを作ってるのだが、そのアプリに、ディスプレイとの接続をcastで行う機能を追加したいという要望があった。
その対応で、色々困ったので後ろを歩く方のためにメモメモ。
castの種類と概要
さて、たなやんは、そもそもcastってなんだ?からスタート^^;
以下、いろんなサイト見てかじった情報。
・スマホからディスプレイに、無線接続で画面表示をする規格(or 機器)は、主に以下。
1. chromecast
2. amazon fire TV
3. Apple TV
4. miracast
・1.は、プログラムすることで、任意の画面をディスプレイに映すことができる模様
https://developers.google.com/cast/docs/remote
・2.は、AirPlay前提でのミラーのようなので、アプリとしてプログラムする話ではない模様(間違ってたらご指摘を〜)
・4.は、一般的な規格だがiOSは未対応。
そんなわけで、当該アプリは既に3.には対応しているので、追加で対応できるのはchromecastのみだと悟る^^;
chromecast 購入!
実は、chromecastはよく聞いてはいたけど、実物見たことなかったんです。
流行りに疎いたなやんも、たまには新し物(では全然ないよねもはや・・)にも触れようかなと言うことで、早速購入!
今は、第二世代ってやつらしいです。HDMI接続で、先に丸いのがついてるやつ。ultraじゃない方買いました。
これ、電源別途必要なんだ・・・ネット上の写真にないからよくわからんよ・・ヨドバシ吉祥寺店のおねいさんはきちんと教えてくれたけど。ありがとうヨドバシおねいさん!
さて、早速繋いでみた。
youtubeがテレビで観れる。
とりあえず、芸人のネタ動画を数時間視聴。 「ちょっと何言ってるかわからないんですけど」を数十回聞いてるうちに、気を失って昼寝(笑)
テレビで映すと画像は荒いけど、なぜかテレビだとじっくりみちゃうねーyoutube^^
これで5000円なら全然ありだなー・・・
・・・って、そんなことをするために買ったんじゃない。アプリからchromecastに繋ぎたいんだよぉぉぉぉぉ!(笑)
というわけで、この辺からやっと真面目な話^^;
chromecastには、アプリから操作するためのAPIがある。
でもね、ここを見ても、いまいちピンとこないのです。APIの体系がよくわからない。
なぜって、同じようで微妙に異なる用語が散在していて整理されていないから。
なので、ちゃんと整理。
用語 |
説明 |
スマホやPCと、chromecastやスピーカーなどとを接続するAPI全体の名前。 |
|
SenderとReceiver |
コンテンツ送信元であるスマホなどをSender、コンテンツを受け取って表示、音声出力する機器側をReceiverと呼ぶ。 Sender API / Sender Applicationなどと表現したりする。Receiverも然り。 |
iOS用のSender API。 |
|
CAF |
これが理解に苦しむ。 |
Remote Display API |
通常のSender API、Receiver APIだと、Youtubeなど、chromecastが対応している、ネット上の動画や音声の出力しかできない。 |
ちなみに、Sender / Receiverっていうか、そもそも、スマホなどからテレビにコンテンツを渡すことを「cast」と呼んでるんだから、casterとcasteeでいいんでないの?と思うのは俺だけ・・・?全体的に、Google Cast SDK回りの用語に一貫性がない。。。
そんなわけで、よくわからないけど、Remote Display APIを使用する前提で前に進んでみよう・・・続くっ