0

This is my first time working with videos and it's a bit overwhelming.

Problem

I would like to be able to record user's screen and every 5 seconds send the recorded screen to my backend server. Then, on my backend server append each 5 seconds into a full video.

If I send 3 parts of 5 second, I would like to have the full 15 seconds video.

What I have tried

I have the following frontend code:


function accessRecord(id) {
    navigator.mediaDevices.getDisplayMedia({
        audio: false,
        video: true
    }).then(startStream).catch(failedStream)
}

function startStream(stream) {
    const mediaRecorder = new MediaRecorder(stream, {
        // I have tried adding a mimeType as well
        // mimeType: 'video/mp4'
    });

    mediaRecorder.start(5000);

    mediaRecorder.ondataavailable = (e) => {
        fetch('http://localhost/api/session/12/video/stream', {
            method: 'POST',
            body: new Blob([e.data]),
        }).then(() => {
            console.log('success')
        }).catch((e) => {
            console.log('error')
            console.log(e);
        })
    };
}

Then, on my backend server [Laravel] I do the following logic:

Route::post('session/{id}/video/stream', function (Request $request) {
    $videoData = $request->getContent();

    $filename = 'video_uuid-video.mp4';

    if (!file_exists(storage_path('app/videos/' . $filename))) {
        touch(storage_path('app/videos/' . $filename));
    }

    \Illuminate\Support\Facades\Storage::append('videos/' . $filename, $videoData);

    return response()->json(['message' => 'Video frame uploaded successfully']);
});

Whenever I stop the streaming, and I try to open the video on my MAC (MacOS) the video doesn't open:

enter image description here

I'm not sure what I'm doing wrong here. I would like to record every 5 seconds the video, then append to the current video and in the end (when the stream ends) I would like to be able to play the video.

Bruno Francisco
  • 3,841
  • 4
  • 31
  • 61
  • Have you tried it with any other video players? VLC (for example) can open almost any video file you can think of. If you can't open it with that, it probably confirms that the file isn't a valid MP4. – ADyson May 26 '23 at 11:13
  • @ADyson That's a great idea. Let me try to install it and get back to you – Bruno Francisco May 26 '23 at 11:14
  • P.S. What makes you think the recorded video will be in MP4 format, specifically? It's hard to find anything definitive about this (just from a bit of googling in the last few minutes) but I'd say it's more likely to be webm, if anything. [this](https://stackoverflow.com/questions/41739837/all-mime-types-supported-by-mediarecorder-in-firefox-and-chrome) is quite interesting. [this](https://manivannan-ai.medium.com/record-audio-video-image-and-gif-from-browser-using-videojs-record-2249fcc6ea9e) could also be useful to you, for context. – ADyson May 26 '23 at 11:18
  • @ADyson VLC shows 0 seconds for this video. It won't open it. Not exactly sure why it would be mp4. I tried saving it as webm as well but Google Chrome wouldn't play the video. I'm fairly new to working with videos. My knowledge about it has huge gaps – Bruno Francisco May 26 '23 at 11:21

1 Answers1

0

You can not combine or append video file to another video file using normal append like append text file.

You need an encoder, for an example FFMPEG

here the example code:

    $existing_file = 'video_uuid-video.mp4';
    $filename = rand(0,9999999).".mp4";

    if (!file_exists(storage_path('app/videos/'.$filename))) {
        touch(storage_path('app/videos/'.$filename));
    }

    Storage::put('videos/'.$filename, $videoData);
    shell_exec("ffmpeg -i $filename -i $existing_file -filter_complex \"concat=n=2:v=0:a=1\" -vn -y output.mp4");
Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73