Dear All,
experimenting with http streams (write audio stream to the file) and can't figure out, what it wrong happening here:
import std/[httpclient, streams]
const radioURL = "http://radio-station.com/mp3.com"
var buf : array[512, char]
proc downloadStream() =
var client = newHttpClient()
let res = client.get(radioURL).bodyStream
defer : res.close()
let f = newFileStream("radiostr.mp3", fmWrite)
defer : f.close()
while true:
discard res.readData(addr(buf), 512)
f.writeData(buf.addr, 512)
res.flush()
downloadStream()
Strategy is pretty simple here:
I ended up with getting huge empty mp3 file. Even if I read few chars to array - array is empty.
Thank you
Thanks for your feedback, meanwhile this code is just a probing version, while I'm using lldb debugger. I was mostly interested in the correctness of the method I apply here.
The stream I want to fetch is : http://live.advailo.com/audio/mp3/icecast.audio And I'm getting zeros in buffer.
Another stream is : http://uk2.internet-radio.com:8171/stream It's freezing on retrieving bodyStream (apparently because port isn't 80)
let res = client.get(radioURL).bodyStream
Unfortunately, I don't know (yet) how to catch possible exceptions for the streams.
Well, I dont really know Nim well. Actually I havent used it at all for the last few years. I just visit the forum sometimes to follow the news.
Anyway, this time I've tried to download from those URLs with wget. It says
request sent, awaiting response... 200 OK
Length: unspecified [audio/mpeg]
I suspect that your example doesnt work because content-length is not determined for live audio. I mean, probably this use case is not supported by Nim's stdlib but as I said, I dont know Nim well, so I'm not really sure if thats the case or how to fix it, sorry
Managed to solve the problem using net sockets. Raw code (Control+C interrupts recording and closes stream and socket) without catching exceptions and async:
import std/[net,streams,strutils]
const Url = "uk2.internet-radio.com"
const Port = Port(8171)
const BufSize = 1024
let sock = newSocket()
var meta : seq[string]
var data : string
let fs = newFileStream("radio.mp3", fmWrite)
sock.connect(Url, Port)
let req = "GET /stream HTTP/1.0\r\nHost:uk2.internet-radio.com\r\n\r\n"
sock.send(req)
proc controlC() {.noconv.} =
fs.close()
sock.close()
echo "Stopping recording. Exiting"
quit(0)
setControlCHook(controlC)
while true:
while true: # Collecting metadata
data = sock.recvLine().strip()
if data.len > 0:
meta.add(data)
else:
echo "Metadata: ",meta
break
echo "Starting recording"
while true: # Main loop to fetch the stream chunks
discard sock.recv(data, BufSize)
fs.write(data)