Quick version: how to send the correct Content-Range headers when you do not know the length of the body?
I have a FLAC file. I want to transcode it to MP3 and immediately transfer it to the user. I have something like this so far:
function transcode(file) { var spawn = require('child_process').spawn var decode = spawn('flac', [ '--decode', '--stdout', file ]) var encode = spawn('lame', [ '-V0', '-', '-' ]) decode.stdout.pipe(encode.stdin) return encode } var express = require('express') var app = express() app.get('/somefile.mp3', function (req, res) { res.setHeader('Accept-Ranges', 'bytes') res.setHeader('Content-Range', 'bytes') res.setHeader('Content-Type', 'audio/mpeg') transcode(file).stdout.pipe(res) })
It works as intended, but it is "streaming", so I can’t miss it. Apparently I need to do Content-Range stuff. Usage: https://github.com/visionmedia/node-range-parser
function sliceStream(start, writeStream, readStream) { var length = 0 var passed = false readStream.on('data', function (buf) { if (passed) return writeStream.write(buf); length += buf.length if (length < start) return; passed = true writeStream.write(buf.slice(length - start)) }) readStream.on('end', function () { writeStream.end() }) } var parseRange = require('range-parser') app.get('/somefile.mp3', function (req, res) { var ranges = parseRange(Infinity, req.headers['range']) if (ranges === -1 || ranges === -2) return res.send(400); var start = ranges[0].start res.setHeader('Accept-Ranges', 'bytes') res.setHeader('Content-Type', 'audio/mpeg') if (!start) { res.setHeader('Content-Range', 'bytes') transcode(file).stdout.pipe(res) return } res.setHeader('Content-Range', 'bytes ' + start + '-') sliceStream(start, transcode(file).stdout, res) })
This is where I am stuck. Since I do not wait for the whole song to be encoded, I do not know the size of the song. Since I just got canceled in Chrome, I assume that the Content-Range header is in the wrong format without size.
Also, I'm just now opening the song in my browser, so I assume that it uses the <audio> element.
Suggestions?