最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Record video stream from webcam and upload blob to server - Stack Overflow

programmeradmin2浏览0评论

so I have a site that can record a video stream from the users webcam and convert it to a blob using getUserMedia(). I now want to send this blob to the server so the video can be saved and processed. I am having trobule sending a blob file via ajax, I have tried using both the formData + XMLHttpRequest() method as well as pure ajax. It is imperetive for my application that users can record video and immediately send this video to my server.

Any help would be greatly appreciated.

so HTML:

    <div class="demo">
    <video id="preview" autoplay width="400" height="300"></video>
    <video id="recording" width="400" height="300" style="display:none;" controls></video>

    <div class="progress">
        <div class="progress-bar"></div>
        <span>01:00</span>
    </div>
    <button class="record">Record</button>
    <button class="upload">Upload</button>
</div>

Relevant JS functions:

function captureVideo () {
    const preview = document.querySelector('video#preview');
    const recording = document.querySelector('video#recording');
    navigator.mediaDevices.getUserMedia({video: true}).then((stream) => {
        preview.srcObject = stream;
        preview.captureStream = preview.captureStream || preview.mozCaptureStream;
        return new Promise(resolve => preview.onplaying = resolve);
    }).then(() => {
        let recorder = new MediaRecorder(preview.captureStream());
        let data = [];

        recorder.ondataavailable = event => data.push(event.data);
        recorder.start();
        log(recorder.state + " for " + (60000/1000) + " seconds...");

        let stopped = new Promise((resolve, reject) => {
            recorder.onstop = resolve;
            recorder.onerror = event => reject(event.name);
        });

        $('button.stop').click(function () {
            recorder.stop();
        });

        return Promise.all([ stopped ]).then(() => data);
    }).then ((recordedChunks) => {
        let recordedBlob = new Blob(recordedChunks, {
            type: "video/webm"
        });
        recording.src = URL.createObjectURL(recordedBlob);
        $('#preview').hide();
        $('#recording').show();
        log("Successfully recorded " + recordedBlob.size + " bytes of " +
            recordedBlob.type + " media.");
        $('button.upload').click(function() {
            sendVideoToAPI(recordedBlob);
        });
    }).catch(log);
}
function sendVideoToAPI (blob) {

    let fd = new FormData();
    let file = new File([blob], 'recording');

    fd.append('data', file);
    console.log(fd); // test to see if appending form data would work, it didn't this is pletely empty. 


    let form = new FormData();
    let request = new XMLHttpRequest();
    form.append("file",file);
    request.open("POST",  "/demo/upload", true);
    request.send(form); // hits the route but doesn't send the file
    console.log(request.response) // returns nothing

    // I have also tried this method which hits the route and gets a response however the file is not present in the request when it hits the server. 
    // $.ajax({
    //     url: Routing.generate('upload'),
    //     data: file,
    //     contentType: false,
    //     processData: false,
    //     error: function (res) {
    //         console.log(res);
    //     },
    //     success: function(res) {
    //         console.log(res);
    //     }
    // });
}

so I have a site that can record a video stream from the users webcam and convert it to a blob using getUserMedia(). I now want to send this blob to the server so the video can be saved and processed. I am having trobule sending a blob file via ajax, I have tried using both the formData + XMLHttpRequest() method as well as pure ajax. It is imperetive for my application that users can record video and immediately send this video to my server.

Any help would be greatly appreciated.

so HTML:

    <div class="demo">
    <video id="preview" autoplay width="400" height="300"></video>
    <video id="recording" width="400" height="300" style="display:none;" controls></video>

    <div class="progress">
        <div class="progress-bar"></div>
        <span>01:00</span>
    </div>
    <button class="record">Record</button>
    <button class="upload">Upload</button>
</div>

Relevant JS functions:

function captureVideo () {
    const preview = document.querySelector('video#preview');
    const recording = document.querySelector('video#recording');
    navigator.mediaDevices.getUserMedia({video: true}).then((stream) => {
        preview.srcObject = stream;
        preview.captureStream = preview.captureStream || preview.mozCaptureStream;
        return new Promise(resolve => preview.onplaying = resolve);
    }).then(() => {
        let recorder = new MediaRecorder(preview.captureStream());
        let data = [];

        recorder.ondataavailable = event => data.push(event.data);
        recorder.start();
        log(recorder.state + " for " + (60000/1000) + " seconds...");

        let stopped = new Promise((resolve, reject) => {
            recorder.onstop = resolve;
            recorder.onerror = event => reject(event.name);
        });

        $('button.stop').click(function () {
            recorder.stop();
        });

        return Promise.all([ stopped ]).then(() => data);
    }).then ((recordedChunks) => {
        let recordedBlob = new Blob(recordedChunks, {
            type: "video/webm"
        });
        recording.src = URL.createObjectURL(recordedBlob);
        $('#preview').hide();
        $('#recording').show();
        log("Successfully recorded " + recordedBlob.size + " bytes of " +
            recordedBlob.type + " media.");
        $('button.upload').click(function() {
            sendVideoToAPI(recordedBlob);
        });
    }).catch(log);
}
function sendVideoToAPI (blob) {

    let fd = new FormData();
    let file = new File([blob], 'recording');

    fd.append('data', file);
    console.log(fd); // test to see if appending form data would work, it didn't this is pletely empty. 


    let form = new FormData();
    let request = new XMLHttpRequest();
    form.append("file",file);
    request.open("POST",  "/demo/upload", true);
    request.send(form); // hits the route but doesn't send the file
    console.log(request.response) // returns nothing

    // I have also tried this method which hits the route and gets a response however the file is not present in the request when it hits the server. 
    // $.ajax({
    //     url: Routing.generate('upload'),
    //     data: file,
    //     contentType: false,
    //     processData: false,
    //     error: function (res) {
    //         console.log(res);
    //     },
    //     success: function(res) {
    //         console.log(res);
    //     }
    // });
}
Share Improve this question asked Oct 12, 2018 at 15:01 UUake UpUUake Up 4004 silver badges17 bronze badges 1
  • 1 I +1 this because of a clear explanation of how this works with FormData and posting capture files. Thanks. – Antony Commented Apr 7, 2020 at 16:01
Add a ment  | 

1 Answer 1

Reset to default 4

You are sending an ajax request you won't have the response immediately after the send() mand. you can access the response value using the request onload event

request.onload = function () {
            if (request.readyState === request.DONE) {
                if (request.status === 200) {
                    console.log(request.response);
                }
            }
        };
发布评论

评论列表(0)

  1. 暂无评论