在Node.js服务器

时间:2015-08-04 09:37:57

标签: jquery node.js html5 video blob

我正在开发一个WebRTC应用程序,它使用Node.js在两个客户端之间建立连接,使用RTCMulticonnection。它是单向视频,双向音频连接。接收视频流的客户端具有存储从视频流创建的剪辑的功能。目前,我有一些代码,可以以HTML blob的形式创建剪辑。需要捕获存储在blob中的信息并将其存储在Node.js服务器本地的文件中。

上传

目前,我正在使用formidable模块使用FormData对象通过jQuery ajax请求将blob上传到服务器。这些文件存储为没有文件扩展名的二进制文件,而不是MP4或其他类似的视频格式。我需要的是一种方法,将FormData blob转换为视频文件格式并将其存储在本地(HTML页面上的blob视频是'video / webm'格式)或利用此二进制文件进行下载的方式,所以它可以稍后在客户端显示为视频。

客户端

connection.streams[recStreamId].stopRecording(function (blob) {

            var form = document.createElement('form');
            var mediaElement = document.createElement('video');
            mediaElement.autoplay = false;
            mediaElement.controls = true;
            mediaElement.src = URL.createObjectURL(blob.video);
            mediaElement.style.width= '100%';
            form.appendChild(mediaElement);
            document.getElementById("saved-videos").appendChild(form);


            var filename = Date.now();

            uploadToServer({cid: cid, vidpath: filename, fname: "video", blob: blob.video});
            uploadToServer({cid: cid, vidpath: filename, fname: "audio", blob: blob.audio});

            return true;

        }, {audio: true, video: true});

服务器侧

var mkdirp = require('mkdirp');
var formidable = require('formidable');

var app = protocol.createServer(options, function (req, res) {

var router = {
    post: {},
    get: {}
};

router.post['/upload_video'] = function(req, res){

    console.log("Uploading");

    var form = new formidable.IncomingForm();

    var path;
    var fname;
    var vid;
    var vidpath;

    form.parse(req, function(err, fields, files){
        if (err)
            res.writeHead(err.status, err.headers);
            res.end();

        cid = fields.cid;
        vidpath = fields.vidpath;
        fname = fields.fname;
        vid = files.data;

        console.log(fields);
    });

    form.on('end', function(){

        //Directory specific to the user with ID=cid
        path = videoPath+cid+"/";

        //If the directory does not already exist, create it
        mkdirp(path, function(err) { 
            if (err){
                res.writeHead(err.status, err.headers);
                res.end();
            }

            path = path + vidpath + "/";

            mkdirp(path, function(err){
                if (err){
                    res.writeHead(err.status, err.headers);
                    res.end();
                }

                console.log(vid);

                fs.copy(vid.path, path + fname, function(err) {  
                    if (err){
                        res.writeHead(err.status, err.headers);
                        res.end();
                    }
                });
            });
        });
    });
}
}

文件已成功存储在服务器端。如果我在浏览器中打开其中一个视频文件,则视频会成功播放。这不是强制性功能,因为它们永远不会从服务器端打开,但是它们需要在客户端可检索和显示。

下载

我目前正在使用fs.readfile下载这些文件。由于此blob同时具有视频和音频组件,因此以下列格式将一个blob存储到服务器:

__dirname + userid + "/" + videoid + "/video" // video component
__dirname + userid + "/" + videoid + "/audio" // audio component

//Example - C:/project/videos/user4/video2/video
//Example - C:/project/videos/user4/video2/audio

服务器侧

使用fs.readFile下载这些文件,并通过HTTP响应将返回的缓冲区发送到客户端。

router.get['/downloadVideo'] = function(req, res){
    var query = url.parse(req.url, true).query;

    var response = {query: query};

    if (query.video == "true") query.video = true;
    if (query.video == "false") query.video = false;
    if (query.audio == "true") query.audio = true;
    if (query.audio == "false") query.audio = false;

    var num_remaining = 0;
    if (query.audio) num_remaining++;
    if (query.video) num_remaining++;

    if (query.video){
        fs.readFile(videoPath + query.cid + "/" + query.dir + "/video", function(err, buf){

            console.log("Downloading " + query.dir + "/video");

            num_remaining--;

            response.videobuf = buf;

            if (num_remaining == 0)
                res.end(JSON.stringify(response));
        });
    }

    if (query.audio){
        fs.readFile(videoPath + query.cid + "/" + query.dir + "/audio", function(err, buf){

            console.log("Downloading " + query.dir + "/audio");

            num_remaining--;

            response.audiobuf = buf;

            if (num_remaining == 0)
                res.end(JSON.stringify(response));
        });
    }
}

客户端

使用jQuery和ajax下载视频。 displayVideo()中的数据对象包含两个缓冲区 - videobuf和audiobuf--它们是通过fs.readFile()下载的文件中的缓冲区。这就是问题所在。正在创建的blob已成功创建,但数据在显示视频的范围内不正确。视频元素已创建,但视频格式不正确。

function downloadVideos(data){
    var paths = JSON.parse(data).data;

    console.log(paths);
    for (var p in paths){
        var path = paths[p];

        var query = ""; 
        query += "?dir="+path.dir;
        query += "&video="+path.video;
        query += "&audio="+path.audio;
        query += "&cid="+cid;

        $.ajax({
            type: "GET",
            url: url + "/downloadVideo"+query,
            data: {}
        }).done(displayVideo);
    }
}

function displayVideo(data, textStatus, response){
    var result = JSON.parse(data);
    console.log(result);

    var blob = new Blob(result.videobuf.data, {type: "video/webm"});

    console.log(blob);

    var mediaElement = document.createElement('video');
    mediaElement.id = result.query.dir;
    mediaElement.autoplay = false;
    mediaElement.controls = true;
    mediaElement.src = URL.createObjectURL(blob);
    mediaElement.style.width= '100%';
    document.getElementById("saved-videos").appendChild(mediaElement);
}

我知道这是很多信息,我希望尽可能多地包含详细信息,以便明确我的所有功能所在以及我如何完成所有工作。如果需要其他任何东西请告诉我,但我认为这应该涵盖所有内容。

0 个答案:

没有答案