6

デバイスのアプリのフォルダーに保存されている画像とビデオを提供するためにGCDWebServerを使用するクライアント iOS アプリケーションがあります。NSSearchPathDirectory.DocumentDirectory

アプリの起動時に、 のインスタンスを開始GCDWebServerし、リクエスト用のファイル レスポンス ハンドラを追加します。

self.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerFileRequest.self) { request in

    return GCDWebServerFileResponse(file: self.filePathForResponse(request.URL))
}

アプリの実行中にデバイスからファイルを正常にダウンロードできることを確認できます。

curl -O http://192.168.0.15:8080/files/IMG_1213-1280x720.MOV

私のアプリは、上記のような URL をメディア チャネルに送信することで Chromecast デバイスと通信し、Chromecast レシーバー アプリは指定された URL でビデオを読み込んで再生します。これまでのところすべて問題ありません。

私の問題は、現在再生中のビデオのシーク サポートを実装したいということです。メディア チャネルにシーク要求を送信するとすぐに、「壊れたパイプ」エラーが発生しGCDWebServer、ビデオの再生が中断されます。サーバーからのログは次のとおりです。

....
[DEBUG] Connection sent 32768 bytes on socket 24
[DEBUG] Connection sent 32768 bytes on socket 24
[ERROR] Error while writing to socket 24: Broken pipe (32)
[DEBUG] Did close connection on socket 24

私が問題を最もよく理解しているのは、通常の再生はファイルを最初から最後までダウンロードするのと同じであり、これは通常の で提供できるため機能するということですがGCDWebServerFileResponse、シークはファイルの別の部分に「ジャンプ」することと同じであり、私はこのようなファイルの読み取りが私の構成で機能するかどうかはわかりません。

  • これを機能させるために構成できる方法はありますGCDWebServerか? これを行うライブアプリがいくつかあるため、問題を解決できることはわかっています。
  • HLS や RTSP などの他のプロトコルをサポートするサーバーを使用する必要がありますか?
  • ビデオ ファイルを特定の方法でエンコードする必要がありますか?

参考までに、 Swifterという別の HTTP サーバーも試しましたが、同じ問題が発生しました。

4

1 に答える 1

4

iOS'AVPlayerは、最初にファイル サイズを要求し、次にサーバーに要求内の目的の範囲を含むデータのチャンクを要求します。この回答では、 のネットワーク アクティビティAVPlayerが示され、応答ステータス コードは206、つまりPartial Contentです。

したがって、必要なデータのチャンクのみで応答する必要があります。

webServer?.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerRequest.self, asyncProcessBlock: { (request, completionBlock) in
  let response = GCDWebServerFileResponse(file: path, byteRange: request.byteRange)
  completionBlock(response)
})

request.byteRangeを呼び出して が定義されているかどうかを確認することが重要であることに注意してくださいrequest.hasByteRange()

私が提供したコードを使用して、AVPlayerまたは Web ブラウザーを使用してビデオを再生し、スクラブ/時間のシークが完全に機能することができました。

于 2016-06-14T02:24:22.817 に答える