4

I'm trying to find a way to save the .png images produced when streaming video from the AR-Drone. The following code that uses the ar-drone module by felixge successfully streams the video to a browser, but I would like to take a screen-shot of this feed and save it to my drive for real-time image analysis.

I am attempting to use the screenshot module to save what appears in my browser when I connect to the host, but all this does is save a blank white image of the size that I specify (see below code). Is there a better way to save a still frame from the AR-Drone video (NOT save the .h264 video feed)?

Thank you.

 // Run this to receive a png image stream from your drone.
var arDrone = require('ar-drone'); //Call AR-drone module
var http = require('http'); //Allows video to be displayed to browser
var client = arDrone.createClient(); //Create AR-drone client--->IP address, video frame rate, image sizing

var pngStream = client.getPngStream(); //Fetch real-time video feed from quad
var fs         = require('fs');
var screenshot = require('node-webkit-screenshot');

client.config('general:navdata_options', 777060865); //turn on GPS
client.config('video:video_channel',3); //Switch feed to downward-facing camera

var lastPng;
pngStream 
  .on('error', console.log)
  .on('data', function(pngBuffer) {
lastPng = pngBuffer; //Store latest png still frame
});

var server = http.createServer(function(req, res) {
if (!lastPng) {
  res.writeHead(503);
  res.end('Did not receive any png data yet.');
  return;
}

res.writeHead(200, {'Content-Type': 'image/png'});
res.end(lastPng);
});

server.listen(8080, function() {
   console.log('Serving latest png on port 8080 ...');
})

screenshot({
   url : 'http://localhost:8080',
   width : 640,
   height : 360
})
.then(function(buffer){
   fs.writeFile('Drone.png', buffer, function(){ 
     console.log('Screenshot saved') ;
     screenshot.close();
  });
});

1 Answers1

2

The PngStream already gives you access to PNG images, all you need to do is write them to a file. The following code shows how to save a frame to a file every 5000 milliseconds:

var arDrone = require('ar-drone');
var client = arDrone.createClient();
var fs = require('fs');

var pngStream = client.getPngStream();
var frameCounter = 0;
var period = 5000; // Save a frame every 5000 ms.
var lastFrameTime = 0;

pngStream
  .on('error', console.log)
  .on('data', function(pngBuffer) {
    var now = (new Date()).getTime();
    if (now - lastFrameTime > period) {
      frameCounter++;
      lastFrameTime = now;
      console.log('Saving frame');
      fs.writeFile('frame' + frameCounter + '.png', pngBuffer, function(err) {
        if (err) {
          console.log('Error saving PNG: ' + err);
        }
      });
    }
  });

Here's what it looks like when you run the code:

[wiseman@Intercept node-ar-drone (master)]$ node temp.js
Saving frame
Saving frame
Saving frame
[...]

That run saved frames in frame1.png, frame2.png and frame3.png. Here's frame1.png:

enter image description here

I tested the code with the downward facing camera too and it worked just as well.

John Wiseman
  • 3,081
  • 1
  • 22
  • 31
  • Thank you for your input. Unfortunately, I tried this before and all it does is save a generic empty file (which, when you open it, reads "undefined"). Any ideas on how I could save an actual png file? Also, if there is a way to save a single still frame at a particular time stamp instead of the whole stream, that would be great! – Jared Duensing Jul 04 '15 at 05:46
  • I've edited my answer to give more details and fix a few small errors. The previous answer worked, it just saved the PNGs in files that had no extension. – John Wiseman Jul 07 '15 at 17:13