4

連続してスクリーンショットを撮り、デスクトップからサウンドをキャプチャして、ライブ ビデオ ストリームとして公開する仕事をしています。ストリーム配信には Wowza Media Server 3.0.3 を使用しています。また、Xuggler を使用して画像フレームを生成し、それらをサウンド バッファーと共にパケットに入れます。次の問題があります。

プログラムを開始すると、イメージ フレームとサウンド パケットのパブリッシュが進行中です。Wowza コンソールから、パケットが発行されたことが通知されます。メディア プレーヤー (この場合は VLC) を開くと、ストリームのビデオ部分は魅力的に機能します (デスクトップから継続的にキャプチャされた画像フレームが表示されます) が、オーディオ部分は非常に貧弱です。つまり、ライブストリームの再生を開始すると、VLC はデスクトップから録音された約 3 秒間のサウンド部分をバッファリングし、より高速で再生します。より長い休憩の後、再びバッファリングして次のパートを再生します。私のコードでは、MP3 でエンコードされたサウンド iBuffer を継続的に送信し、それらをパケットにパブリッシュしているため、画像フレームとしてサウンドが継続的に再生されない理由がわかりません。

私の問題で誰かが答えや経験を得ることができますか?

画像フレームではなく、デスクトップサウンドをストリーミングするだけのコードからコピーを作成しました。これは、サウンドを取得し、エンコードして公開するために送信するスニペットです。

while (true)
    {
        byte buffer[] = new byte[line.available()];
        int count = line.read(buffer, 0, buffer.length);
        IBuffer iBuf = IBuffer.make(null, buffer, 0, count);

        //Itt írjuk a stream-be az audioframe-et
        _AudioWriter.encodeFrameToStream(iBuf, buffer, firstTimeStamp);
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

これは、iBuffer を取得して mp3 にエンコードする部分です。パケットとして公開した後:

public void encodeFrameToStream(IBuffer ibuffer, byte[] buffer, long firstTimeStamp) {
    long now = System.currentTimeMillis();
    long timeStamp = (now - firstTimeStamp);

    IAudioSamples outChunk = IAudioSamples.make(ibuffer, 1, IAudioSamples.Format.FMT_S16);
    if (outChunk == null)
    {
        return;
    }
    long numSample = buffer.length / outChunk.getSampleSize();
    outChunk.setComplete(true, numSample, 44100, 1, Format.FMT_S16, timeStamp);

    //System.out.println(outChunk + " =========== " + outChunk.getPts());
    IPacket packet2 = IPacket.make();
    packet2.setStreamIndex(0);
    getCoder2().encodeAudio(packet2, outChunk, 0);
    outChunk.delete();

    if (packet2.isComplete()) {
        //System.out.println("completed");
        getContainer().writePacket(packet2);
        //System.out.println("Size: "+packet2.getSize());
    }
}
4

1 に答える 1

0

関連するすべての要因を知るには、もう少しデバッグする必要があります。

  • 通常、オーディオ ストリームが異なるピッチで再生される場合、入力と出力のサンプル レートが一致しないことを意味します。現在、サンプル形式をFMT_S16に、サンプルレートを44.100 Hzに手動で設定しています。入力がすでにこのようにフォーマットされている限り、これは問題なく機能します。

    IAudioResampler入力と出力の間にを使用して、パケットのチャンネル数、サンプル形式、およびサンプル レートが正しいことを確認することができます。関数およびを の入力として使用IMediaWriterします。IStreamCodergetChannels()getSampleRate()IAudioResampler

  • Wowza Media Serverには詳しくありませんが、何らかのトランスコーディング自体を実行しているようです。あなたのコードからはわかりませんでしたが、ファイル コンテナーを使用する代わりに、Wowza に直接ストリーミングしているようです。ファイルに出力して、後で再生できるかどうかを確認できます。そうすれば、オーディオ/ビデオデータが適切にエンコードされているかどうかを確認できます。

    そうである場合、問題はおそらく Wowza にあります。コーデック、サンプル形式、サンプル サイズ、チャンネル、サンプル レート、ビットレートに特定の制限があるかどうかを確認してください。

    出力ファイルが再生されない場合は、オーディオ ストリームだけを書き込んで、ビデオを除外してみてください。それが再生される場合、問題はオーディオおよびビデオ データからのパケットの形成にあります。

  • 最後に、各ビデオ フレームとオーディオ サンプルを書き込むときに、タイムスタンプを出力してみてください。このようにして、すべてのデータ パケットが年代順できちんと整列されていることを確認できます。ビデオ ファイルのある時点でこれらのパケットの順序が間違っていると、ファイルを適切にストリーミングおよび再生できません。

たとえば、これは不正な形式のビデオ ファイルです。

0ms video frame  1
0ms audio sample 1
10ms video sample 2
8ms audio frame 2`
于 2014-05-15T00:15:41.087 に答える