Можно ли манипулировать данными камеры перед отправкой в ​​WebRTC? - PullRequest
0 голосов
/ 22 октября 2019

Мы пытаемся использовать фильтры (например, черно-белые, сепия), маски или что-то подобное на видеокадрах в WebRTC. Но мы пытаемся сделать это перед отправкой данных (я имею в виду кадры камеры). Конечно, мы можем изменить кадры на стороне получателя, но мы хотим сделать это на стороне отправителя? Можно ли манипулировать данными и т. Д. Видеокадры в вызове перед отправкой?

1 Ответ

0 голосов
/ 23 октября 2019

Нет и да.
Нет , для этого нет собственного метода WebRTC. Манипулирование добавленными MediaStreams в WebRTC предлагает только applyConstraints и Transceiver-sendEncodings , оба могут использоваться для манипуляции частотой кадров или измерениями видео, но они не делают того, что вы хотите.
Да , но вы должны использовать HTML5 Canvas API в сочетании с WebRTC. Если вы хотите применить черно-белый фильтр, ниже приведен фрагмент кода того, как вы можете это сделать, вы можете просто скопировать его в файл .html.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>grayscale example</title>
</head>
<body>
<video id="demo" autoplay></video>
<script>
    // I shamelessly copied this from https://www.permadi.com/tutorial/jsCanvasGrayscale/index.html
    function grayScaleCanvas(canvas, context){
        const width = canvas.width;
        const height = canvas.height;
        const frame=context.getImageData(0,0, width, height);
        // This loop gets every pixels on the image and puts the rgb average as value
        for (let i=0; i<height; i++){
            for (let j=0; j<width; j++){
                const index=(i*4)*frame.width+(j*4);
                const red=frame.data[index];
                const green=frame.data[index+1];
                const blue=frame.data[index+2];
                const average=(red+green+blue)/3;
                frame.data[index]=average;
                frame.data[index+1]=average;
                frame.data[index+2]=average;
            }
        }
        context.putImageData(frame, 0, 0);
    }

    // 1. paint the getUserMedia-Stream on a canvas,
    // 2. manipulate the canvas to create the grayscale-effect,
    // 3.return a canvas capture stream with the given framerate
    function streamToGrayScaledVersion(stream, fps=30, width=640, height=480){
        const video = document.createElement('video');
        video.autoplay = true;
        video.srcObject = stream;
        const canvas = document.createElement('canvas');
        canvas.width = width;
        canvas.height = height;
        const context = canvas.getContext('2d');
        const toCanvas = function(){
            context.drawImage(video, 0, 0, width, height);
            grayScaleCanvas(canvas, context);
            requestAnimationFrame(toCanvas);
        };
        requestAnimationFrame(toCanvas);
        return canvas.captureStream(fps);
    }

    const demoVideo = document.getElementById("demo");
    navigator.mediaDevices.getUserMedia({video: true})
        .then(streamToGrayScaledVersion)
        .then(stream => demo.srcObject = stream)
        .catch(console.error);
</script>
</body>
</html>

(Мои извинения занеудобство, я уже пытался создать для этого «настоящий» фрагмент StackOverflow, но всплыло что-то вроде ошибки источника безопасности, возможно, вызывая getUserMedia в фрагментах)

...