2014-01-07 51 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