私はC#でライブラリを作成して、Airplayプロトコルを使用して写真とビデオをApple TVに送信するように取り組んでいます(特に第3世代で動作しますが、これが問題にならないことを願っています)。
Airplayのすべてのコマンドは、次の仕様に従ってポート70でHTTPです:http: //nto.github.com/AirPlay.html
私は写真とビデオの両方をAppleTVで再生することに成功しましたが、何をしてもAppleTVは30秒分のビデオしか再生しません。playコマンドを発行するC#クライアントが30秒で切断されているように見えます。これにより、AppleTVは再生セッションを終了します。
私がこれを考える理由:
- クライアントアプリを終了すると、30秒待つのと同じ動作が完全に発生します(基本的に接続を強制的に閉じます)。
- HttpWebRequestまたはTcpClient接続を手動で閉じると、同じ動作が発生します(再生セッションの途中)。
- GetResponse()呼び出しを防ぐためにブレークポイントを保持している時間に関係なく、WebRequestがメッセージの送信を開始してから30秒後にビデオが常にタイムアウトします。
- ビデオに別のソース(IIS、外部Webサーバー)を使用しても、動作は変わりません。
- ビデオがAppleTVにキャッシュされ、再ストリーミングされなかった後でも、タイムアウトが発生します。
私は、クライアントのリクエストがビデオの「再生」の間ずっと接続されている必要があると確信しています。私の知る限り、それを行うためにコーディングしました。私は本当に私の知恵の終わりにいます。HttpWebRequestと生のTcpClient(両方とも機能しますが両方ともタイムアウト)としてリクエストを実行すること、Recieve / Sendタイムアウトをクレイジーな数値に設定すること、Tcpストリームの読み取りをループすることなど、考えられるすべてのことを試しました。 「活動」があることを確認します。
AppleTVは私が「ねえ、再生を続けて」というメッセージを送信することを期待しているようですが、Web上のどのソースからもそのようなものはまだ見ていません。Http / Tcpの知識が不足しているため、これが私が行っていない愚かなことであることを願っています。
これが私のコードです:
Uri url = "http://somevideo.com/video.mov";
float startPosition = 0;
TcpClient tcpClient = new TcpClient("192.168.1.20",7000);
tcpClient.ReceiveTimeout = 100000;
tcpClient.SendTimeout = 100000;
//get the client stream to read data from.
NetworkStream clientStream = tcpClient.GetStream();
string body =
"Content-Location: " + url + "\n" +
"Start-Position: " + startPosition + "\n";
string request = "POST /play HTTP/1.1\n" +
"User-Agent: MediaControl/1.0\n" +
"Content-Type: text/parameters\n" +
"Content-Length: " + Encoding.ASCII.GetBytes(body).Length + "\n" +
"X-Apple-Session-ID:" + _sessionGuid.ToString() + "\n\n";
sendMessage(clientStream, request);
sendMessage(clientStream, body);
byte[] myReadBuffer = new byte[1024];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;
//incoming message might be bigger than the buffer
do
{
try
{
numberOfBytesRead = clientStream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.Append(Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
Thread.Sleep(10);//let the iOS device catch up sending data
}
catch (System.IO.IOException) { }
} while (tcpClient.Connected); //check if it's connected before checking for data available, as maybe the program might get quit and the sockets closed halfway through a read
注:telnetを使用して、ポート7000でAppleTVに接続し、ビデオ全体を再生するこのコマンドを貼り付けることができます。
POST /play HTTP/1.1
User-Agent: MediaControl/1.0
Content-Type: text/parameters
Content-Length: 89
X-Apple-Session-ID:fb6d816a-a5ad-4e8f-8830-9642b6e6eb35
Content-Location: http://192.168.1.11:82/2012/2012_03_11/IMG_1328.MOV
Start-Position: 0
ポート82でCassiniWebサーバーを実行していますが、これはIISでも機能します。これは、.Netスタックが30秒で内部で何かを実行して切断を引き起こしているというさらなる証拠を提供します。