Javascript 将用计算机摄像机拍摄的视频从网站发送到服务器

Javascript 将用计算机摄像机拍摄的视频从网站发送到服务器,javascript,ajax,html5-video,video-capture,getusermedia,Javascript,Ajax,Html5 Video,Video Capture,Getusermedia,我正试图让一台电脑或安卓设备从摄像机中录制视频,并将其发送到一台服务器上存储。该系统必须基于网络,并且需要连续发送视频片段 以下是javascript中的代码: var camera = (function() { var options; var video, canvas, context; var renderTimer; function initVideoStream() { video = document.createElement

我正试图让一台电脑或安卓设备从摄像机中录制视频,并将其发送到一台服务器上存储。该系统必须基于网络,并且需要连续发送视频片段

以下是javascript中的代码:

var camera = (function() {
    var options;
    var video, canvas, context;
    var renderTimer;

    function initVideoStream() {
        video = document.createElement("video");
        video.setAttribute('width', options.width);
        video.setAttribute('height', options.height);

        navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
        window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;

        if (navigator.getUserMedia) {
            navigator.getUserMedia({
                video: true
            }, function(stream) {
                options.onSuccess();

                if (video.mozSrcObject !== undefined) { // hack for Firefox < 19
                    video.mozSrcObject = stream;
                } else {
                    video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
                }

                initCanvas();
            }, options.onError);
        } else {
            options.onNotSupported();
        }
    }

    function initCanvas() {
        canvas = document.getElementById("canvas");//options.targetCanvas || document.createElement("canvas");
        canvas.setAttribute('width', options.width);
        canvas.setAttribute('height', options.height);

        context = canvas.getContext('2d');

        // mirror video
        if (options.mirror) {
            context.translate(canvas.width, 0);
            context.scale(-1, 1);
        }

        startCapture();
    }

    function startCapture() {
        video.play();

        renderTimer = setInterval(function() {
            try {
                context.drawImage(video, 0, 0, video.width, video.height);
                options.onFrame(canvas);
            } catch (e) {
                // TODO
            }
        }, Math.round(1000 / options.fps));
    }

    function stopCapture() {
        pauseCapture();

        if (video.mozSrcObject !== undefined) {
            video.mozSrcObject = null;
        } else {
            video.src = "";
        }
    }

    function pauseCapture() {
        if (renderTimer) clearInterval(renderTimer);
        video.pause();
    }

    return {
        init: function(captureOptions) {
            var doNothing = function(){};

            options = captureOptions || {};

            options.fps = options.fps || 30;
            options.width = options.width || 640;
            options.height = options.height || 480;
            options.mirror = options.mirror || false;
            options.targetCanvas = options.targetCanvas || null; // TODO: is the element actually a <canvas> ?

            initVideoStream();
        },

        start: startCapture,

        pause: pauseCapture,

        stop: stopCapture
    };
})();

var imgSender = (function() {
    function imgsFromCanvas(canvas, options) {
        var context = canvas.getContext("2d");
        var canvasWidth = canvas.width; //# pixels horizontally
        var canvasHeight = canvas.height; //# pixels vertically
        var imageData = context.getImageData(0, 0, canvasWidth, canvasHeight); //Vector of all pixels
        options.callback(canvasWidth, canvasHeight, imageData.data);
    }

    return {
        fromCanvas: function(canvas, options) {
            options = options || {};
            options.callback = options.callback || doNothing;
            return imgsFromCanvas(canvas, options);
        }
    };
})();

var FPS = 30; //fps
var minVideoTime = 5; //Seconds that every video clip sent will take
var arrayImgs = []; //Array with all the images that will be sent to the server
var videoTime = 0; //Number of seconds of video stored in videoTime
(function() {
    var capturing = false;

    camera.init({
        width: 160,
        height: 120,
        fps: FPS,
        mirror: true,

        onFrame: function(canvas) {
            imgSender.fromCanvas(canvas, {
                callback: function(w,h,image) {
                    arrayImgs.push(image);
                    videoTime += 1/FPS;
                    if (minVideoTime <= videoTime) {
                        sendToPhp(w,h,videoTime*FPS);
                        arrayImgs = [];
                        videoTime = 0;

                        function sendToPhp(width,height,numFrames) {
                            $.ajax({
                                type: "POST",
                                url: "sendToServer.php",
                                data: {
                                    arrayImgs: arrayImgs,
                                    width: w,
                                    height: h,
                                    nframes: numFrames
                                },

                                async: true, // If set to non-async, browser shows page as "Loading.."
                                cache: false,
                                timeout:500, // Timeout in ms (0.5s)

                                success: function(answer){
                                    console.log("SUCCESS: ", answer);
                                },
                                error: function(XMLHttpRequest, textStatus, errorThrown){
                                    console.log("ERROR: ", textStatus, " , ", errorThrown);                             }
                            });
                        }
                    }
                }
            });
        },

        onSuccess: function() {
            document.getElementById("info").style.display = "none";

            capturing = true;
            document.getElementById("pause").style.display = "block";
            document.getElementById("pause").onclick = function() {
                if (capturing) {
                    camera.pause();
                } else {
                    camera.start();
                }
                capturing = !capturing;
            };
        },

        onError: function(error) {
            // TODO: log error
        },

        onNotSupported: function() {
            document.getElementById("info").style.display = "none";
            document.getElementById("notSupported").style.display = "block";
        }
    });
})();
var-camera=(函数(){
var期权;
视频、画布、上下文;
var渲染器;
函数initVideoStream(){
视频=document.createElement(“视频”);
video.setAttribute('width',options.width);
video.setAttribute('height',options.height);
navigator.getUserMedia=navigator.getUserMedia | | navigator.webkitGetUserMedia | | navigator.mozGetUserMedia | | navigator.msGetUserMedia;
window.URL=window.URL | | | | | | | window.mozURL | | | window.msURL;
if(navigator.getUserMedia){
navigator.getUserMedia({
视频:真的
},函数(流){
options.onSuccess();
如果(video.mozSrcObject!==未定义){//hack for Firefox<19
video.mozSrcObject=流;
}否则{
video.src=(window.URL&&window.URL.createObjectURL(stream))| | stream;
}
initCanvas();
},options.onError);
}否则{
options.onNotSupported();
}
}
函数initCanvas(){
canvas=document.getElementById(“canvas”);//options.targetCanvas | | document.createElement(“canvas”);
canvas.setAttribute('width',options.width);
canvas.setAttribute('height',options.height);
context=canvas.getContext('2d');
//镜像视频
if(options.mirror){
context.translate(canvas.width,0);
背景量表(-1,1);
}
startCapture();
}
函数startCapture(){
video.play();
renderTimer=setInterval(函数(){
试一试{
context.drawImage(视频,0,0,video.width,video.height);
选项。onFrame(画布);
}捕获(e){
//待办事项
}
},数学四舍五入(1000/options.fps);
}
函数stopCapture(){
pauseCapture();
if(video.mozSrcObject!==未定义){
video.mozSrcObject=null;
}否则{
video.src=“”;
}
}
函数pauseCapture(){
if(渲染器)clearInterval(渲染器);
video.pause();
}
返回{
初始化:函数(captureOptions){
var doNothing=function(){};
选项=captureOptions | |{};
options.fps=options.fps | | 30;
options.width=options.width | | 640;
options.height=options.height | | 480;
options.mirror=options.mirror | | false;
options.targetCanvas=options.targetCanvas | | null;//TODO:元素实际上是一个元素吗?
initVideoStream();
},
开始:startCapture,
暂停:暂停暂停,
停止:停止捕获
};
})();
var imgSender=(函数(){
函数IMGSFROMCAvas(画布,选项){
var context=canvas.getContext(“2d”);
var canvasWidth=canvas.width;//#水平像素
var canvasHeight=canvas.height;//#垂直像素
var imageData=context.getImageData(0,0,canvasWidth,canvasHeight);//所有像素的向量
回调(画布宽度、画布高度、imageData.data);
}
返回{
fromCanvas:函数(画布,选项){
选项=选项| |{};
options.callback=options.callback | | doNothing;
返回imgsFromCanvas(画布,选项);
}
};
})();
var FPS=30//fps
var-minVideoTime=5//发送每个视频剪辑所需的秒数
var arrayImgs=[]//包含将发送到服务器的所有映像的数组
var-videoTime=0//存储在videoTime中的视频秒数
(功能(){
var=false;
camera.init({
宽度:160,
身高:120,
fps:fps,
镜子:是的,
onFrame:函数(画布){
imgSender.fromCanvas(画布{
回调:函数(w、h、图像){
arrayImgs.push(图像);
视频时间+=1/FPS;

如果(minVideoTime用于您的用例,您应该使用。这将允许您将视频录制为WebM块,您可以在后台上载到服务器。WebM/VP8(或mp4)在压缩视频方面比您现在所做的即席MJPEG做得好得多


另请参见,其中包括尚未实现此功能的浏览器的兼容层,等等。

谢谢!我没有找到一个完美的解决方案,但我最终使用RecordRTC获得了与我想要的类似的功能,因此感谢您的提示!