2014-01-07 53 views
0

如何從互聯網上讀取音頻流(例如http://70.36.96.24:13384/;stream.mp3)並使用Scala語言將其內容保存到本地磁盤?如何在scala中讀取網絡流?

我試圖做到這一點的:

val stream = new URL("http://70.36.96.24:13384/stream.mp3").openStream() 

但它會引發此異常:

java.io.IOException: Invalid Http response 
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1342) 
at java.net.URL.openStream(URL.java:1037) 
at .<init>(<console>:15) 
at .<clinit>(<console>) 
at .<init>(<console>:7) 
at .<clinit>(<console>) 
at $print(<console>) 
    ... 

同樣的命令works。這等流媒體URL:如

http://174-123-32-173.webnow.net.br/98fm.mp3

更新:此代碼工作perf在Linux上,而不是在Mac上。有人知道原因嗎?

UPDATE2:實際上,此代碼適用於Java 6,但不適用於Java7。這與操作系統無關。

+0

我認爲鏈接已損壞。你可以用瀏覽器試試 – jilen

+1

你在Linux和Mac上安裝了哪個版本的Java? – tuxdna

+1

你是對的:用Java 6它的工作原理與Java 7它給出的錯誤:-) –

回答

3

您的代碼不起作用,因爲服務器沒有發送有效的HTTP響應。請注意,發回HTTP請求,正在等待迴應... 200無頭,假定HTTP/0.9

$ wget -O- "http://70.36.96.24:13384/;stream.mp3" 
--2014-01-20 17:09:12-- http://70.36.96.24:13384/;stream.mp3 
Connecting to 70.36.96.24:13384... connected. 
HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9 
Length: unspecified 
Saving to: `STDOUT' 

    [<=>                             ] 0   --.-K/s    ICY 200 OK 
icy-notice1:<BR>This stream requires <a href="http://www.winamp.com/">Winamp</a><BR> 
icy-notice2:SHOUTcast Distributed Network Audio Server/Linux v1.9.8<BR> 
icy-name:Radio Brasileirissima 
icy-genre:Musica Brasileira 
icy-url:http://radiobrasileirissima.com.br 
content-type:audio/mpeg 
icy-pub:0 
icy-br:64 

....BINARY CONTENT SKIPPED.... 

您仍然可以通過跳過第幾行,直到字符序列\r\n\r\n,其中icy-br:64端讀取數據,並開始實際的音頻內容。爲此,您可以創建一個Socket,連接到它,併發送一個GET請求到`/;stream.mp3' 和讀取數據:

val timeout = 2000 
val host = "70.36.96.24" 
val port = 13384 
val socket = new Socket 
val endPoint = new InetSocketAddress(host, port) 
socket.connect(endPoint, timeout); 
// Here you send the GET request and read back the response. 
// Every time you read the response, you have to skip 
// the first few bytes until `\r\n\r\n` 

EDIT1

注:您的GET請求必須包括額外的換行符爲它是一個HTTP請求

 
GET /;stream.mp3 HTTP/1.1 

這裏是在同一個URL工作示例:

def socketurl = { 
    val timeout = 2000 
    val host = "70.36.96.24" 
    val port = 13384 
    val socket = new Socket 
    val endPoint = new InetSocketAddress(host, port) 
    socket.connect(endPoint, timeout); 
    val (in, out) = (socket.getInputStream(), socket.getOutputStream()) 
    val httpRequest = "GET /;stream.mp3 HTTP/1.1\r\n\r\n" 
    val command = httpRequest.getBytes() 
    println(httpRequest) 
    out.write(command) 

    var buf = Vector(0, 0, 0, 0) 
    var c = in.read() 
    var cont = true 
    while (c != -1 && cont) { 
     buf = buf.drop(1) :+ c 
     print(c.toChar) 
     if (buf(0) == '\r' && buf(1) == '\n' && buf(2) == '\r' && buf(3) == '\n') { 
     cont = false 
     println("Its a match") 
     } 
     c = in.read() 
    } 

    while (c != -1) { 
     // keep buffering the data from here on! 
    } 
    } 

// call the method 
socketurl 
+0

我試過這個: val socket = new Socket val endPoint = new InetSocketAddress(url.getHost(),url.getPort ()) socket.connect(endPoint,5000) val stream = socket.getInputStream() val path = url.getPath() val command =(「GET」+ path +「\ n」) socket.getOutputStream ().write(command.toCharArray()。map(_。toByte)) socket.getOutputStream()。flush() 但是當我從socket.getInputStream()讀取它時,它總是空的...... –

+1

您的GET請求必須包含額外的換行符才能成爲HTTP請求「GET /;stream.mp3 HTTP/1.1 \ r \ n \ r \ n」 – tuxdna

+0

@DanielCukier:我已經更新了代碼。請檢查。它現在應該適合你。 – tuxdna