0

上級:

同じエンコーダーを 2 つの異なる方法で使用します。

方法 #1: 生のオーディオを録音してファイル全体に保存し、すべてが終了したらファイルを圧縮します。結果完璧なオーディオ

方法 #2: 生のオーディオを録音し、フレームごとにエンコードします。結果音飛び

方法 2 でスキップが発生するのはなぜですか?

低レベル

方法 1 のコード (FileOutputStream fos に書き込み、すべての書き込みが終了したら圧縮)

public void writeSample(short[] buf) throws IOException {
            byte[] byteArray = Util.toByteArray(buf,false);
            bytesWritten += byteArray.length;
            fos.write(byteArray);
        }

方法 2 のコード

public void writeSample(short[] buf) throws IOException {
            byte[] byteArray = Util.toByteArray(buf,false);
            bytesWritten += byteArray.length;
            encoder.encode(byteArray);
        }

ほぼ完璧: ウェイ #2 の短い buf の長さは 15360 です。これは奇数サイズの数値であるため、この手法を採用しました: しかし、まだわずかに聞こえるスキップがあります:

      ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
      byte[] readme = new byte[4096];
      int count = bais.read(readme);
      while ( count != -1 ) {
        System.out.println("READING :"+count+ " bytes");
        if(bais.available() < 4096) {
          System.out.println ("LESS THAN 4096 available: "+bais.available());
          byte[] remain = new byte[bais.available()];
          bais.read(remain);
          aacEncoder.encode(remain);
          break;
        }
        aacEncoder.encode(readme);
        count = bais.read(readme);
      }
4

1 に答える 1

0

取引は次のとおりです。エンコーダーがエンコードするとき、常に同じ時間がかかるとは限りません。後で使用するために一部のデータを隠しておくだけの場合もあれば、実際に大量の計算処理を行う場合もあります。MP3「フレーム」全体をエンコードするのに十分なオーディオを待つ必要があります。そうしないと、データが隠されます。

数値計算が必要な新しいデータの呼び出しが発生するたびに、音声が表す時間よりも長くかかると、ドロップアウトが発生するリスクがあります。

解決策は、レコード スレッドにバッファを埋めさせ、2 番目のスレッドにすべての処理を行わせることです。これにより、動作が遅くなったり、予測できない時間がかかったりする可能性があります。これには、エンコードとファイルへの書き込みが含まれます。

バッファについては、Android 2.3 以降をターゲットにしている場合は、パイプされたI / Oを使用できます。これは技術的にはブロックするためリングバッファではありませんが、私の経験では十分に機能します。(この API は以前のバージョンの android で使用できますが、バッファー サイズを設定することはできません。うーん!)

オーディオ IO が実際に概念的にどのように機能するかを理解するには、次のリンクが役立つ場合があります。

于 2012-11-20T20:48:33.563 に答える