【问题标题】:How to record desktop screen video using recordRTC node module of selected screen area?如何使用选定屏幕区域的recordRTC节点模块录制桌面屏幕视频?
【发布时间】:2017-06-23 12:02:02
【问题描述】:

我正在使用 NW.js 开发桌面应用程序,其中需要记录桌面屏幕的选定区域。目前使用 RecordRTC 节点模块录制视频。但这给了我全屏视频录制。如果有任何其他软件包可以跨平台(win/linux/mac)实现这一点,请提供帮助。

【问题讨论】:

    标签: node.js video-capture nwjs


    【解决方案1】:

    请查看此演示(名称为“使用 RecordRTC 记录裁剪屏幕”):

    这是完整的 HTML 代码(在任何 HTTPs 页面或 localhost 或 node-webkit 上尝试):

    <button id="btn-start-recording">Start Recording</button>
    <button id="btn-stop-recording" style="display: none;">Stop Recording</button>
    
    <br><hr>
    
    <div id="edit-panel" style="border-bottom: 1px solid;">
        <div>
            <label for="x">X</label>
            <input type="number" name="x" id="x" value="0" />
        </div>
        <div>
            <label for="y">Y</label>
            <input type="number" name="y" id="y" value="0" />
        </div>
        <div>
            <label for="w">Width (-1 = Full size)</label>
            <input type="number" name="w" id="w" value="-1" />
        </div>
        <div>
            <label for="h">Height (-1 = Full size)</label>
            <input type="number" name="h" id="h" value="-1" />
        </div>
    
        <button id="update" style="display: none;">Update X-Y Width-Height Coordinates</button>
    
        <canvas></canvas>
    </div>
    
    <video id="mediaElement"></video>
    
    <script src="https://cdn.webrtc-experiment.com/RecordRTC.js"></script>
    <script src="https://cdn.WebRTC-Experiment.com/getScreenId.js"></script>
    <script>
    // this script tag is taken from: https://github.com/andersevenrud/webrtc-screenshare-crop-demo
    var CROP_X = 10;
    var CROP_Y = 20;
    var CROP_W = 320; // default width
    var CROP_H = 240; // default height
    var VIDEO_WIDTH = 0;
    var VIDEO_HEIGHT = 0;
    var MAX_VIDEO_WIDTH = 1920;
    var MAX_VIDEO_HEIGHT = 1080;
    var _canvas;
    var _context;
    
    var htmlCanvasElement = document.querySelector('canvas');
    
    // Form elements
    document.getElementById("x").value = CROP_X;
    document.getElementById("y").value = CROP_Y;
    document.getElementById("w").value = CROP_W;
    document.getElementById("h").value = CROP_H;
    
    document.getElementById("update").onclick = function() {
        var x = document.getElementById("x").value << 0;
        var y = document.getElementById("y").value << 0;
        var w = document.getElementById("w").value << 0;
        var h = document.getElementById("h").value << 0;
    
        if (x >= 0) {
            CROP_X = x;
        }
        if (y >= 0) {
            CROP_Y = y;
        }
    
        CROP_W = w || 0;
        CROP_H = h || 0;
    };
    
    _context = htmlCanvasElement.getContext('2d');
    
    /**
     * Crops a video frame and shows it to the user
     */
    function CropFrame(ev, stream, video, callback) {
        callback = callback || function() {};
    
        _canvas = htmlCanvasElement;
    
        if (CROP_X < 0) {
            CROP_X = 0;
        }
        if (CROP_Y < 0) {
            CROP_Y = 0;
        }
        if (CROP_W <= 0) {
            CROP_W = VIDEO_WIDTH;
        }
        if (CROP_H <= 0) {
            CROP_H = VIDEO_HEIGHT;
        }
        if (CROP_W > MAX_VIDEO_WIDTH) {
            CROP_W = MAX_VIDEO_WIDTH;
        }
        if (CROP_H > MAX_VIDEO_HEIGHT) {
            CROP_W = MAX_VIDEO_HEIGHT;
        }
    
        _canvas.width = CROP_W;
        _canvas.height = CROP_H;
    
        _context.drawImage(video, CROP_X, CROP_Y, CROP_W, CROP_H, 0, 0, CROP_W, CROP_H);
    
        // We need to scale down the image or else we get HTTP 414 Errors
        // Also we scale down because of RTC message length restriction
        var scanvas = document.createElement('canvas');
        scanvas.width = _canvas.width;
        scanvas.height = _canvas.height;
    
        var wRatio = _canvas.width / 320;
        var hRatio = _canvas.height / 240;
        var maxRatio = Math.max(wRatio, hRatio);
        if (maxRatio > 1) {
            scanvas.width = _canvas.width / maxRatio;
            scanvas.height = _canvas.height / maxRatio;
        }
        scanvas.getContext('2d').drawImage(_canvas, 0, 0, scanvas.width, scanvas.height);
    
        callback(scanvas.toDataURL("image/jpeg"));
    }
    
    var recorder;
    
    function captureScreen(cb) {
        getScreenId(function(error, sourceId, screen_constraints) {
            navigator.getUserMedia(screen_constraints, cb, function(error) {
                console.error('getScreenId error', error);
    
                alert('Failed to capture your screen. Please check Chrome console logs for further information.');
            });
        });
    }
    
    var mediaElement = document.querySelector('#mediaElement');
    
    document.querySelector('#btn-start-recording').onclick = function() {
        document.querySelector('#btn-start-recording').style.display = 'none';
    
        navigator.getUserMedia = navigator.getUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
        captureScreen(function(screen) {
            var inited = false;
    
            mediaElement.ontimeupdate = function(ev) {
                if (!inited) {
                    VIDEO_WIDTH = mediaElement.offsetWidth;
                    VIDEO_HEIGHT = mediaElement.offsetHeight;
    
                    mediaElement.style.display = 'none';
                    document.querySelector('#edit-panel').style.display = 'block';
    
                    inited = true;
                }
    
                CropFrame(ev, screen, mediaElement);
            };
    
            mediaElement.src = URL.createObjectURL(screen);
            mediaElement.play();
            mediaElement.screen = screen;
    
            addStreamStopListener(screen, function() {
                document.querySelector('#btn-stop-recording').onclick();
            });
    
            // RecordRTC goes here
            var captureStream = htmlCanvasElement.captureStream();
            recorder = RecordRTC(captureStream, {
                type: 'video'
            });
            recorder.startRecording();
    
            document.querySelector('#btn-stop-recording').style.display = 'inline';
        });
    };
    
    document.querySelector('#btn-stop-recording').onclick = function() {
        document.querySelector('#btn-stop-recording').style.display = 'none';
    
        recorder.stopRecording(function() {
            var blob = recorder.getBlob();
    
            document.querySelector('#edit-panel').style.display = 'none';
            mediaElement.style.display = 'block';
    
            mediaElement.src = URL.createObjectURL(blob);
            mediaElement.play();
    
            if (mediaElement.screen && mediaElement.screen.getVideoTracks) {
                mediaElement.screen.stop();
                mediaElement.screen = null;
            }
    
            document.querySelector('#btn-start-recording').style.display = 'inline';
        });
    };
    
    function addStreamStopListener(stream, callback) {
        var streamEndedEvent = 'ended';
        if ('oninactive' in stream) {
            streamEndedEvent = 'inactive';
        }
        stream.addEventListener(streamEndedEvent, function() {
            callback();
            callback = function() {};
        }, false);
        stream.getAudioTracks().forEach(function(track) {
            track.addEventListener(streamEndedEvent, function() {
                callback();
                callback = function() {};
            }, false);
        });
        stream.getVideoTracks().forEach(function(track) {
            track.addEventListener(streamEndedEvent, function() {
                callback();
                callback = function() {};
            }, false);
        });
    }
    
    function querySelectorAll(selector) {
        return Array.prototype.slice.call(document.querySelectorAll(selector));
    }
    
    querySelectorAll('input').forEach(function(input) {
        input.onkeyup = input.oninput = function() {
            if (!document.querySelector('#update').onclick) return;
            document.querySelector('#update').onclick();
        };
    });
    </script>
    

    【讨论】:

    • 感谢您的回复。当我试图在 NW.JS 应用程序中执行它时,它在控制台中给了我以下错误:getScreenId 错误 NavigatorUserMediaError 约束名称:“”消息:“”名称:“InvalidStateError”proto:NavigatorUserMediaError 与此错误有关到 webkit 版本或 getScreenId 文件加载错误?
    • 请让这个包与 typescript 一起使用,比如 code intellisense
    • 感谢这个包,我喜欢它。请使其文档更清晰,并创建一些针对低级或中级开发人员的教程。由于没有适当的教程和代码智能感知,我发现使用这个包很困难。
    猜你喜欢
    • 1970-01-01
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    相关资源
    最近更新 更多