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));
}
IlluminateSupportFacadesStorage::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:
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.
2
Answers
It seems that you are trying to send individual video frames as separate requests to the server and append them to create a full video. However, this approach is not sufficient for creating a playable video file.
To achieve your goal, you’ll need to use a video container format (e.g., MP4) and ensure that the video frames are encoded and organized correctly within the container.
Here’s an updated approach that utilizes the MediaRecorder API on the frontend and FFmpeg on the backend to create a playable video:
Backend (Laravel) Code:
Install FFmpeg (if not already installed) on your server. You can follow the instructions for your operating system to install FFmpeg.
Install the PHP-FFMpeg library for Laravel. You can install it using Composer:
Update your Laravel route and controller to handle video saving and concatenation:
In the above code, the first route ‘session/{id}/video/save’ is used to save each video chunk sent from the frontend. The {id} parameter represents the session ID or any other identifier you’re using.
The second route ‘session/concatenate-videos’ is used to trigger the concatenation of the saved video chunks into a single video file. You can modify the route URL as needed.
Make sure to adjust the route URLs and controller method names according to your specific application needs.
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: