Saturday, 28 September 2013

Play Iteratee throttling

Play Iteratee throttling

I'm writing a streaming web radio framework using scala and Play. I'm
relying on Iteratees for the actual streaming, but I'm running into an
issue trying to prevent a greedy client from downloading data too quickly,
and consuming the stream for all the clients. To do so I've been trying to
create an Enumeratee that will throttle how quickly the Enumerator
produces data. Here's what my Enumeratee looks like
val throttlingIteratee = Iteratee.foldM[Array[Byte], Array[Byte]](new
Array[Byte](0)) {
(result, chunk) =>
val prom = Promise[Array[Byte]]()
timer.schedule(new TimerTask{
def run() = prom.success(result ++ chunk)
},1000)
prom.future
}
private val chunker = Enumeratee.grouped(
Traversable.take[Array[Byte]](31792) &>> throttlingIteratee
)
The idea is that I use the timer task to create a throttlingIteratee and
pair that with the Enumeratee.grouped function. This seems to work fairly
well, but I'm having trouble figuring out what value to use for the chunk
size. I want to have this produce chunks at about the same rate as the
audio plays. My audio file is encoded at 82kpbs, and I've tried to
calculate that in terms of bytes, but the values I come up with seem to be
too small, and the audio plays faster than the data is streamed.
My question is two fold. Is the basic approach I have in place a good one?
And if it is, how do I go about setting the chunk size in terms of the
audio file's bit rate.

No comments:

Post a Comment