2012-11-02 179 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`