TooTallNate / node-lame

Node.js native bindings to libmp3lame & libmpg123
MIT License
567 stars 113 forks source link

Flowing issues when piping to a http response #78

Open LinusU opened 6 years ago

LinusU commented 6 years ago

For some reason the stream cuts out after just a few kilobytes, it seems like something is wrong with flowing/paused mode and back pressure buffering... just guessing here...

Minimal test case:

const LineIn = require('line-in')
const Lame = require('lame')
const http = require('http')

http.createServer((req, res) => {
  const input = new LineIn()
  const encoder = new Lame.Encoder()

  res.writeHead(200, { 'Content-Type': 'audio/mp3' })

  input.pipe(encoder).pipe(res)
}).listen(4001, () => {
  console.log('http://localhost:4001/')
})

The behaviour could then be observed with e.g. curl:

$ curl localhost:4001 > test.mp3
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  9113    0  9113    0     0   1904      0 --:--:--  0:00:04 --:--:--  1904^C

Here it hanged after receiving 9113 bytes.

For some strange reason the following code works:

  // ...

  input.pipe(encoder) // .pipe(res)

  setInterval(() => encoder.resume(), 1000)
  encoder.on('data', (data) => res.write(data))

@TooTallNate if you have any ideas that would be greatly appreciated! If you have time, would you mind just trying to run this on your computer and see if it works?

LinusU commented 6 years ago

I should also not that piping to a fs.createWriteStream('test.mp3') works perfectly 🤔

mikealeonetti commented 6 years ago

Having the same issue where it hangs for a bit when encoding and then after an arbitrary amount of time it resumes and flushes. For me it happens right before flush. It randomly will decide to either flush immediately or wait about a minute or so and then flush.

Is this basically the issue you're having?

LinusU commented 6 years ago

Oh, actually, I never tried waiting more than a few seconds, will do that and see if it starts pushing data again...

mikealeonetti commented 6 years ago

I can confirm that your

setInterval(() => encoder.resume(), 1000)

Works as a workaround. It works for me, too! Both decoding and encoding. What is the issue that it gets clogged?

I'm using node v6.9.4 on Gentoo and v6.10.2 on Ubuntu and the problem happens on both.