プログラミングノート

一からものを作ることが好きなエンジニアの開発ブログです。

静止画をAirPlayする方法について

使っている人は結構使っているAirPlay。
弊社アプリでも多数の要望があり、静止画/動画のAirPlay機能を提供しています。


もう随分前になりますが、iOS4.3から動画の配信がサポートされ、MPMoviePlayerControllerについてはallowsAirPlayというオプション1つでAirPlayでの再生が可能となりました。それなら静止画もきっとAPIがあるだろうと思い色々と探してみたのですが、残念ながら該当する項目はありませんでした。


ということで自力で実装するしかなかったのですが、該当する情報がほぼない状態で大変でしたので、今回はこの静止画のAirPlay実装について紹介したいと思います。

調査に必要なもの

下記3点が必要です。AirPlayerはお手軽でいいのですが、残念ながらLionでは正常に動作しませんのでSnow LeoperdまでのOSが必要です。(通信内容を確認しなくてよいのであればAppleTVでも大丈夫)

AirPlay機器を検出する

Bonjour Browerは同一ネットワークのbonjourデバイスを検出してくれるツールです。AirPlay機器を起動後、Bonjour Browerでチェックしてみると、_airplay._tcp. という項目を発見できると思います。結論から言ってしまうと、ここに表示されるIPアドレスへ直接リクエストを送信することでAirPlay機器上で画像を表示することが可能となります。


AirPlayの通信仕様を探る

ではどのようなリクエストを飛ばせばよいのかを調べます。AirPlayerを起動している端末でPacket Peeperを起動後 "tcp port 7000" でフィルタリングし、パケットを確認できる状態にしておきます。



この状態で標準の写真アプリから該当のAirPlay機器に対してAirPlayを開始すると、こんな感じでガンガン流れてきます。



これでAirPlayのリクエストとしては下記の4種類あることが分かります。photoが写真の送信で、stopがAirPlay終了です。開始時にserver-infoとslideshow-featuresがリクエストされていますが、動作には直接関係がなく、実際には初めてphotoリクエストを受け取った時点でAirPlayが開始されます。

GET /server-info
GET /slideshow-features
PUT /photo
POST /stop

AirPlayを実装する

AirPlayの実装自体は単純です。Bonjour Browerで見つけたIPに対して上記リクエストを送信するだけで静止画が表示されます。色々端折ってますがこんな感じ。終了させる場合は、stopリクエストです。

#import "GTMHTTPFetcher.h"

- (void)pushImage{
  NSURL *url = [NSURL URLWithString:@"http://192.168.101.6:7000/photo"];
  
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  [request setHTTPMethod:@"PUT"];
  [request addValue:@"MediaControl/1.0" forHTTPHeaderField:@"User-Agent"];
  [request setHTTPBody:UIImageJPEGRepresentation(image, 0.8)];
    
  GTMHTTPFetcher *fetcher = [GTMHTTPFetcher fetcherWithRequest:request];
  [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError*error){
    if(error){
      // エラー処理
    }
  }];
}


1つ注意点としては、AirPlay機器にしばらくリクエストを送信しない状態が続くとAirPlayが終了してしまいます。正しい方法はよく分からないのですが、定期的にserver-infoリクエストを送信するという対策で上手く行っています。

その他必要なこと

今回はテストなのでIPを直接指定しましたが、実際には自分で機器を検出する必要があります。Bonjour Browerを実装するようなものなのですが、こちらについては、iPhoneでBonjour使ってホストを見つける/見つけてもらうが大変参考になりました。