2012-11-02 175 views
4

我有一份工作,我必須從桌面上拍攝連續的截圖並捕獲聲音,然後將它們作爲實時視頻流發佈。我使用Wowza Media Server 3.0.3進行流發佈。我還使用Xuggler生成圖像幀並將它們與聲音緩衝區一起放入數據包中。我有以下問題:Xuggler音頻直播播放不連續

我開始我的程序,並正在發佈圖像幀和聲音數據包。 Wowza控制檯告訴我,數據包已發佈。當我打開一個媒體播放器(在這種情況下是VLC)時,流的視頻部分就像一個魅力(我可以看到從我的桌面上持續拍攝的圖像),但音頻部分非常差。我的意思是,當我開始播放直播時,VLC會緩存從我的桌面錄製的大約3秒長的聲音部分,並以更高的速度播放它。經過較長時間的休息後,再次緩衝並播放下一部分。在我的代碼中,我不斷髮送用MP3編碼的聲音iBuffers並將它們發佈到數據包中,所以我不明白爲什麼聲音不能像圖像幀一樣連續播放。

任何人都可以得到答案或任何經驗在我的問題?

我從我的代碼中創建了一個副本,我只是在桌面上聲音流,而不是圖像幀。 這是片段,在那裏我得到的聲音,並將其發送到編碼和發佈:

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()); 
    } 
} 

回答

0

我們必須要調試多一點去了解所有相關因素。

  • 通常當音頻流以不同的音高播放時,意味着輸入和輸出的採樣率不匹配。您目前正在手動將採樣格式設置爲FMT_S16,並將採樣率設置爲44.100 Hz。只要輸入已經以這種方式格式化,這將工作正常。

    您可能希望通過在輸入和輸出之間使用IAudioResampler來確保數據包具有正確的通道數,採樣格式和採樣率。使用IMediaWriterIStreamCoder函數getChannels()getSampleRate()作爲IAudioResampler的輸入。

  • 我不熟悉Wowza媒體服務器,但它似乎執行某種轉碼本身。我無法從你的代碼中知道,但似乎你直接流到Wowza而不是使用文件容器。你可以嘗試輸出到一個文件,看看你是否可以在之後播放它。這樣你可以檢查音頻/視頻數據是否被正確編碼。

    如果是這樣,問題可能與Wowza有關。檢查它是否對編解碼器,採樣格式,採樣大小,通道,採樣率和比特率有任何特殊的限制。

    如果輸出文件不能播放,請嘗試寫入音頻流並留下任何視頻。如果確實如此,那麼問題在於從音頻和視頻數據中形成數據包。

  • 最後,你可以嘗試輸出每個視頻幀和音頻樣本的時間戳,當你寫他們?通過這種方式,您可以確保所有數據包按年代順序排列整齊。如果在視頻文件中某些時刻這些數據包的順序錯誤,則無法正確流式傳輸和播放該文件。

例如,這是不正確的影片文件:

0ms video frame 1 
0ms audio sample 1 
10ms video sample 2 
8ms audio frame 2`