2014-02-27 35 views
0

我正在用Java製作一個shoutcast服務器,並且我在路上碰到了一個碰撞。我的服務器可以流數據很好,如果我送客戶(VLC/WINAMP)的HTTP響應:Java中的SHOUTcast服務器

HTTP/1.1 200 OK\r\nContent-Type:audio/mpeg\r\n\r\n\ 

,然後開始流式傳輸的文件,但是,當我向客戶端發送一個冰冷的迴應,聲音開始變得一有點波濤洶涌,有時候速度很快。有時它會同時播放播放列表中所有歌曲的一小塊,但如果斷開客戶端連接並重新連接,它可以正常播放,在這種情況下可能會有點波動和吱吱作響。我試圖連接到互聯網上的shoutcast服務器,它們看起來完美無瑕。 (我也是在24KB塊送我的數據)

這裏是我的ICY響應

String respond = "ICY 200 OK\r\n" 
        +"icy-notice1: <BR> This stream requires" 
        + "<a href=\"http://www.videolan.org/\">VLC</a><BR>\r\n" 
        + "icy-notice2: Lee Shoutcast<BR>\r\n" 
        + "icy-name: Lee's Mix\r\n" 
        + "icy-genre: Rock\r\n" 
        + "icy-url: http://localhost:9025\r\n" 
        + "content-type: audio/mpeg\r\n" 
        + "icy-pub: 1\r\n" 
        + "icy-metaint: 24576\r\n" 
        + "icy-br: 96\r\n\r\n"; 

我所做的閱讀一點點,發現我必須在格式發送客戶端數據Header | DataChunk | Header .....所以我查了一下如何做這個頭文件,並將其作爲一個測試運行來看看它是否可以解決這個問題。

String header = ""; 

    String heading ="StreamTitle='The year of the ram';" 
      + "StreamUrl='someaddress:9025';"; 

    byte []headingBytes = heading.getBytes(); 

    int NumberOfBlocks = ((headingBytes.length - 1)/16) + 1; 

    int toPad = NumberOfBlocks*16 - headingBytes.length; 


    header = NumberOfBlocks + "StreamTitle='The year of the ram';" 
      + "StreamUrl='http://someaddress:9025';"; 


    String finalStr = header + padding(toPad); 

    System.out.println(finalStr); 

    byte []finalByte = finalStr.getBytes(); 

    return finalByte; 

填補方法只是增加了零的字符串右邊:

public String padding(int numberOfPads) 
{ 
    String ret = ""; 

    for(int i = 1; i <= numberOfPads; i++) 
    { 
     ret += "0"; 
    } 

    return ret; 
} 

結果字符串爲:

5StreamTitle='The year of the ram';StreamUrl='http://someaddress:9025';000000000000 

我然後將字符串轉換爲字節和寫入這些頭字節到流然後寫我的24kb塊,然後標題等。這似乎並沒有幫助這種情況。是否有什麼我做錯了SHOUTcast,因爲它與ICEcast完美配合?

P.S我知道代碼看起來有點亂,可能會更好,但這只是一個測試。我也發送這個常量字符串作爲測試,看看它是否有幫助。該計劃是要做到這一點,如果它的工作。

任何幫助表示讚賞。

我的信息是從

編輯:

這是我很確定何時發送字節(此代碼是在一段時間(true)loop)

  buffer = new byte[24576]; 

      //read the file into the buffer 
      bytesRead = song.read(buffer); 

      //start streaming the file. 
      outputStream.write(buffer); 

將24KB歌曲讀入緩衝區,然後寫入輸出流。我刪除了編寫元數據的代碼位,但是我在outputStream.write(buffer)之前編寫了元數據。

VLC和wimamp做派冰冷的元數據= 1

回答

1

首先,我建議模仿的ICY 200 OK Shoutcast一樣的狀態行。改爲使用HTTP/1.0 200 OK。這樣你就可以更好地與客戶端兼容。

現在,您的服務器行爲不同的原因是由於元數據,因爲您懷疑。 icy-metaint響應標頭控制元塊之間的間隔。您應該只插入此標題並在客戶端請求時返回元數據。客戶端必須發送icy-metadata: 1來請求元數據。否則,您只能發送流數據。

你沒有說明你如何確定何時插入元數據,但我懷疑你遇到了一個常見的誤解。要發送給客戶端的第一個數據應該是流數據,而不是元數據。流數據需要以元間隔響應頭指定的增量發送。

[24,576 bytes of stream] [metablock] [24,576 bytes of stream] [metablock] etc. 

最後,您正在填充您的元區塊不正確。不要使用字面值0,請使用NUL字節。 0x00

+0

我添加了如何確定何時發送編輯下的問題中的塊。這個元區塊包含什麼?這和我以前用空字節做過的一樣嗎?我將查找如何用連續的空值填充字符串。 我感謝您的幫助,我會提出建議的更改,謝謝 –