0

So basically I'm trying to send WebGL frames/screenshots to a server which may save these frames to the hard drive so I'll be able to merge these saved frames to video file. I have found this: Exporting video from webgl

I don't like to bother you guys with the WebGL related details... The only thing you should know that I would like to send the content of two client side JavaScript variables to the localhost node.js server. So these two client side variables are the following:

            var frame = frame + 1; //this is the frame counter
            var dataUrl = renderer.domElement.toDataURL("image/png"); //this is the encoded screenshot/frame

the receiver server side code is given by Joe Turner (this is running in node.js). So my question is: how to send the above mentioned two variable's content to this node.js code?

var http = require('http');
var querystring = require('querystring');
var fs = require('fs');

// Override so we don't decode spaces, and mess up the base64 encoding
querystring.unescape = function(s, decodeSpaces) {
    return s;
};

// Pad to follow the processing export format
function pad(num) {
    var s = "000" + num;
    return s.substr(s.length-4);
}

http.createServer(function (request, response) {
    request.content = '';
    request.addListener("data", function(data) {
        request.content += data;
    });

    request.addListener("end", function() {
        if (request.content.trim()) {
            request.content = querystring.parse(request.content);
            var data = unescape(request.content['data']);
            var frame = request.content['frame'];
            // Remove data:image/png;base64,
            data = data.substr(data.indexOf(',') + 1);
            var buffer = new Buffer(data, 'base64');
            fs.writeFile('screen-' + pad(frame) + '.png',
                         buffer.toString('binary'), 'binary');
        }
    });
    response.writeHead(200, {
        'Content-Type': 'text/plain',
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Headers': 'X-Requested-With'
    });
    response.end();
}).listen(8080, "127.0.0.1");

Should I do something like this?

            ...
            ...
            //WebGL related code
            ...
            ...
                            var frame = frame + 1;
                            var dataUrl = renderer.domElement.toDataURL("image/png");

                                $.ajax({
                                    url: "http://127.0.0.1:8080",
                                    type: "POST",
                                    data: {"data": dataUrl, "frame": frame}

                                });
            ...
            ...

For example let's see this experiment:

Three.js basic example

I changed this piece of code in the above experiment:

        pointLight.position.copy( camera.position );

        progress += frameTime;
        lastTimestamp = timestamp;
        renderer.render( scene, camera );
        stats.update();
        requestAnimationFrame( animate );

To this:

        pointLight.position.copy( camera.position );

        progress += frameTime;
        lastTimestamp = timestamp;
        renderer.render( scene, camera );
        stats.update();
        requestAnimationFrame( animate );

        var dataUrl = "data:image/png;base64,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";
        var frame = 10;

        $.ajax({
                url: "http://127.0.0.1:8080",
                type: "POST",
                data: {"data": dataUrl, "frame": frame}    
        });

But still cannot see any saved image file.

jbduzan
  • 1,106
  • 1
  • 14
  • 30
Fract
  • 323
  • 1
  • 6
  • 22
  • possible duplicate of [Pass array to ajax request in $.ajax()](http://stackoverflow.com/questions/8890524/pass-array-to-ajax-request-in-ajax) – bwright Jul 10 '15 at 11:22

1 Answers1

1

The code you wrote only needs to have the correct protocol in its url (you were missing "http://") :

var frame = frame + 1;
var dataUrl = renderer.domElement.toDataURL("image/png");

$.ajax({
        url: "http://127.0.0.1:8080",
        type: "POST",
        data: {"data": dataUrl, "frame": frame}    
});

From the code you posted, you can see the server is already parsing the request and extracting the two parameters you send in POST

if (request.content.trim()) {    
    request.content = querystring.parse(request.content);
    var data = request.content['data'];
    var frame = request.content['frame'];
    //...

Anything you add to the POST request in $.ajax can be retrieved by name when calling

request.content['name']

Just make sure the names you use in the client and server code match.

Also, the node.js code is receiving an escaped base64 string, which doesn't make this function work

data.substr(data.indexOf(',') + 1);

Since the ',' character is escaped.

To solve this just use the node built-in function unescape on the data string like this

var data = unescape(request.content['data']);
Vale
  • 1,912
  • 16
  • 22
  • It's fine, corrected my code, but node.js still not displaying anything or does not save any picture. Where should the pictures to be saved by node.js? – Fract Jul 10 '15 at 13:21
  • 1
    I updated my answer, after unescaping the data variable the server saves images correctly. The pictures get saved in the directory where you **execute** node.js. If you want to use a specific directory just add it before the filename `fs.writeFile(directoryPath + 'screen-' + pad(frame) + '.png', ...)` – Vale Jul 10 '15 at 14:00
  • Made these changes you suggested, but still no image on the directory path I've specified. I'm a newcomer to node.js. So just please doublecheck how to start the node.js with the script above. I copied and pasted the above node.js related code into a text file (xy.txt), then went to cmd (where xy.txt takes place) and typed "node xy.txt". I only see a black screen. No image created. – Fract Jul 10 '15 at 15:09
  • 1
    That's correct, you don't see any output on the server. After you start it with cmd you need to execute `$.ajax` from your javascript and send the parameters **while the server is still running**. If you're unsure try this [snippet](http://pastebin.com/2EsSuket) I was using to test your code right from your browser developer's console, it requires jquery, of course. – Vale Jul 10 '15 at 15:40
  • Please see: I've updated my original question. Unescaped the node.js code, tested all your codes. Ran a native three.js example with your code included meanwhile the node.js code was running. Still no saved image. May I ask you please to download the three.js experiment I just linked in my original question and implement the AJAX part into it? May I ask you please to give it a try on your side? – Fract Jul 13 '15 at 09:05