1

ネットワーク経由でビデオ ストリームをブロードキャストできるようにする Android アプリケーションの最初の部分を開発しています。現在、次のように非常に直接的な方法でビデオを送信しています。

Socket socket = new Socket(InetAddress.getByName(hostname), port);
ParcelFileDescriptor pfd = ParcelFileDescriptor.fromSocket(socket);
recorder.setOutputFile(pfd.getFileDescriptor());

しかし残念ながら、それはあまり流動的ではありません。ソケット経由でデータ ストリームを送信する前に、データ ストリームをバッファリングしたいと考えています。私が試した方法の 1 つは、メディアを記録するために Android API を使用してストリームをファイルに書き込み、別のスレッドを使用してコンピューター上のサーバーにファイルをストリーミングすることです。

だから私の問題は次のとおりです。まだ書き込み中のファイルをソケットで送信するにはどうすればよいですか? BufferedInputStreamには読み取り用のブロッキング メソッドがないため、このようなことを試みましたが、成功しませんでした

while (inputStream.available() >= BUFFER_SIZE) {
  inputStream.read(buffer);
  outputStream.write(buffer);
}
outputStream.flush();

しかし、私がそうしているとき、ネットワークがデータストリームよりも速い場合、私はすぐにループから抜け出します.

それを行うための「良い」方法はありますか?私はアクティブな待機を行うことについて考えましたが、特にモバイルの場合、それは良い解決策ではありません. 別の方法は、次のようなことです。

while (true) {
  while (inputStream.available() < BUFFER_SIZE) {
    wait(TIME); 
  }
  inputStream.read(buffer);
  outputStream.write(buffer);
}
outputStream.flush();

しかし、それは私にとってはかなり汚いように聞こえます...もっと洗練された解決策はありますか?

4

2 に答える 2

1

これらの状況で私が行うことは、送信しようとしているデータの最後に到達するか、バッファーがいっぱいになるまで、バイト配列 (バッファー) を単純に埋める場合です。その場合、バッファはソケット送信ロジックに渡される準備ができています。確かに、これはビデオやオーディオでは行いませんが、「通常の」データに対してのみ行います。

注目に値するのは、これにより、そのデータの受信者に「ぎくしゃくした」ユーザー エクスペリエンスが提供されることです (ネットワークが短時間停止し、その後通常どおりに動作しているように見える場合があります... バッファがいっぱいになるまでの時間)。したがって、ビデオまたはオーディオのいずれかでバッファリングされたアプローチを使用する必要がある場合は、使用するバッファ サイズに注意してください。

ビデオのようなものでは、ストリーミングベースのロジックとバッファリングを使用するのは私の経験ですが、明らかにいくつかの異なる興味深い要件があります。

于 2011-04-08T03:06:23.847 に答える
0

これを行うきれいな方法は考えられませんが、1 つのオプションとして、ローカル ソケット ペアを作成し、ペアの「クライアント」側を MediaRecorder 出力 fd として使用し、ローカル サーバー ソケットとリモートサーバー。このようにして、データが存在するまでローカルサーバーでブロックできます。

もう 1 つの可能性は、ファイルベースのパイプ/fifo を使用することです (ディスクがいっぱいにならないようにするため) が、Java レイヤーが mkfifo 機能を公開しているかどうかを思い出せません。

いずれにせよ、読み取りがブロックされるはずなので、おそらくFileReaderを見たいと思うでしょう。

お役に立てれば、

フィル・レロ

于 2011-04-08T03:49:50.890 に答える