Target undefined
JakeStevenson opened this issue · 5 comments
I'm using the sample code and trying to read an mjpeg stream from a webcam, I get the following error:
TypeError: Cannot read property 'length' of null
at Buffer.copy (buffer.js:517:13)
at MjpegConsumer._transform (/Users/jakestevenson/Projects/testconsumer/node_modules/mjpeg-consumer/lib/mjpeg-consumer.js:55:15)
at MjpegConsumer.Transform._read (_stream_transform.js:179:10)
at MjpegConsumer.Transform._write (_stream_transform.js:167:12)
at doWrite (_stream_writable.js:221:10)
at writeOrBuffer (_stream_writable.js:211:5)
at MjpegConsumer.Writable.write (_stream_writable.js:180:11)
at Request.ondata (stream.js:51:26)
at Request.EventEmitter.emit (events.js:95:17)
at IncomingMessage. (/Users/jakestevenson/Projects/testconsumer/node_modules/request/request.js:925:12)
My code is pretty close to the example:
var request = require("request");
var MjpegConsumer = require("mjpeg-consumer");
var FileOnWrite = require("file-on-write");
var writer = new FileOnWrite({
path: './video',
ext: '.jpg',
filename: function(data) { return date.time; }
});
var consumer = new MjpegConsumer();
request("http://192.168.11.123:8080/a").pipe(consumer).pipe(writer);
It appears that the HTTP headers from the camera are either not providing Content-Length
or the Content-Length
is not matching the regex /Content-Length:\s*\d+/i
.
Could you test something? Just write the raw HTTP stream from the camera to a file so that I can take a look at the headers. The following code snippet should work. Note that you should only need to run the following code for a few seconds.
var request = require("request");
var fs = require("fs");
request("http://192.168.11.123:8080/a").pipe(fs.createWriteStream("raw.txt"));
All I'm interested is the first several lines of the raw.txt
file which should look like a variation of
--ipcamera
Content-Type: image/jpeg
Content-Length: 48628
<lots of random characters>
If you could copy and paste the header lines of the HTTP response in your next comment (or maybe there are no HTTP headers??), that'd be extremely helpful.
Just a bit of explanation - I use the Content-Length
header when allocating a Buffer for each JPEG. If Content-Length
isn't provided, a buffer is never created which causes the failure you're seeing (I guess I could throw a more useful exception in that case).
Also, the filename
function in your file-on-write
object should probably be something more like
filename: function(data) { return Date.now(); }
The way you currently have it looks similar to the use-case when hooking up to a motion stream.
It looks like you are right. It doesn’t seem to have a content-length header:
--arflebarfle
Content-type: image/jpeg
<binary data>
So I’ll end up having to figure out what the length is manually. Could you provide a way for us to provide that? Or some way we can automatically determine it by looking for the next set of headers?
Thanks for the quick response.
Alright, so try out commit b6f124a. I haven't pushed to npm as I wanted you to test with your camera before considering this fixed. You should be able to copy the updated lib/mjpeg-consumer.js
file over to your local setup to test.
The fix is to continually reallocate new Buffers via Buffer.concat
and search for the JPEG end of image marker (0xffd9) if there is no Content-Length
header. Continually creating new Buffer objects will be a tad slower and may cause a larger memory footprint, but I didn't test too thoroughly to know what the impact is.
Let me know if this fixes your problem.
Seems to work fine so far. I'm in the very early stages of trying to parse a video stream so I'm not sure about memory impact, but it's working great for me so far.
Thank you very much,
Awesome, glad to hear it's working for you. I've published version 0.4.0 of mjpeg-consumer to npm.The new version contains the changes needed to work without a Content-Length
header.
I just did some rough testing with/without Content-Length
on a VGA mjpeg stream, and it looks like memory usage is about 30-100% higher when Content-Length
is not provided. Granted, a 100% increase is an increase of like 25MB of RAM on my laptop, so depending on the system you're running on, this may be negligible.