WebRTC-Experiment
WebRTC-Experiment copied to clipboard
RecordRTC and best way and how to save on server
Hi Mauz Have been playing with your experiments - they are great and very interesting. Please excuse me but I am not a java script person at all - my limitation is a small (very) bit of jQuery - php etc. I have no problem with so if you have already answered this question I apologise.
So I run the RecordRTC "file/s" on my server I can record video and I can stop, I can then view that video (in terms of your demo page), but how do I/can I send/save the file which I assume is a temp file(?) to the server.
The demo page shows this:
/* stop recording video and save recorded file to disk */ recorder.stopVideo(function(recordedFileURL) { window.open(recordedFileURL); });
but is that actually saving the file because my basic understanding is that just opens another window.
Lets say I run the demo on page "record.php" and I have a folder "recordings" how do I get the file into recordings and save it?
Cheers
See this answer.
- Get
Blob
object instead ofDataURL
- POST it over the server using
FormData
object
RecordRTC
will be fixed in next commits. You can change this line to use blobURL
instead of blobURL2
:
getBlob: function () {
return blobURL;
}
And POST
it like this:
blob = recorder.getBlob();
formData = new FormData();
formData.append('key', blob);
xhr.send(formData);
Hi Mauz, thanks for that, as said java not strong point so I guess formData.append('key', blobURL); key is the "field" name? xhr.send() is "submitting the form"? do I then use say a php script to move the file the same way as an upload? Sorry for being thick - Oh and where is it being sent to? I can't see a reference to the page/folder?
Did this ever get resolved? Would be nice to see a demo working with this posting to PHP. HELP please.
Hi Muaz. Sorry for the tweet, I didn't see this bug manager. I tried the following :
blob = recorder.getBlob();
formData = new FormData();
formData.append('audio-result', blob, 'audioresult');
function reqListener () {
console.log(this.responseText);
};
var xhr = new XMLHttpRequest();
xhr.onload = reqListener;
xhr.open("POST", "save.php", true);
xhr.send(formData);
And my save.php
just var_dump($_POST)
.
Works well with a string (formData.append('audio-result', 'test string', 'audioresult');
) but not with the blob. It seems to be empty. Any idea what's wrong ?
Thank you for your time and for this lib.
@raphaelyancey, check this demo. Here is PHP code
<?php
foreach(array('video', 'audio') as $type) {
if (isset($_FILES["${type}-blob"])) {
$fileName = $_POST["${type}-filename"];
$uploadDirectory = "uploads/$fileName";
if (!move_uploaded_file($_FILES["${type}-blob"]["tmp_name"], $uploadDirectory)) {
echo("problem moving uploaded file");
}
echo($uploadDirectory);
}
}
?>
And JavaScript code:
var fileType = 'video'; // or "audio"
var fileName = 'ABCDEF.webm'; // or "wav"
var formData = new FormData();
formData.append(fileType + '-filename', fileName);
formData.append(fileType + '-blob', blob);
xhr('save.php', formData, function (fileURL) {
window.open(fileURL);
});
function xhr(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
callback(location.href + request.responseText);
}
};
request.open('POST', url);
request.send(data);
}
Try the demo: https://www.webrtc-experiment.com/RecordRTC/PHP/
It works like a charm, thank you @muaz-khan
Hi, I'm using this: blob = recorder.getBlob(); to get Blob data, but blob alway is 'undefined', when log mediaRecorder.recordedBlob have the recorded blob data.
What's wrong in here ?
recordRTC.stopRecording(function() {
var blob = recordRTC.getBlob(); // it'll NEVER be undefined
});
You need to use stopRecording
method's callback.
where is the file save before uploading the server?
Thanks
I am using this in Spring MVC application and not able to obtain blob from post request. How to do it it Servlets / Spring MVC way.
Whenever i click on start recording, it says RecordRTC is not defined. How can i solve this error? do i have to define it somewhere?
Hello Assalam-u-Alaikum Muaz i really really appreciate your work i learn alot from you and i applied many thing in real world applications now can you please tell me how i can record a video which drop on server without browser open and video record should save in selected storage device
Hi Muaz A/s, Thanks a lot to provide great solutions for developers, can we implement this in django/python?
Hi Muaz,
it's not working on iphone, is it not compatible with ios or I'm missing something?
Thanks!
IOS doesnt support webrtc without it being within an app. No browser support.
On Mar 6, 2018 2:32 AM, "umairm638" [email protected] wrote:
Hi Muaz,
it's not working on iphone, is it not compatible with ios or I'm missing something?
Thanks!
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/muaz-khan/WebRTC-Experiment/issues/48#issuecomment-370719570, or mute the thread https://github.com/notifications/unsubscribe-auth/ABBTlkSEMTolvNQ6ZfufadR1dBCFlgFxks5tblfDgaJpZM4Au2xH .
Hi Mauz, Is there any reference to upload recording using JAVA spring MVC.
Thanks, Amit
Hi Amit,
First you have to send blob to your controller and create a file like
mp4, then you can do whatever you want, you can send blob with ajax I have done this with django (python) but doesn't matter, see only javascript:
function captureCamera(callback) { navigator.mediaDevices.getUserMedia({ audio: true, video: true }).then(function(camera) { callback(camera); }).catch(function(error) { alert('Unable to capture your camera. Please check console logs.'); console.error(error); }); } function stopRecordingCallback() { //video.play(); recorder.camera.stop(); //recorder.destroy(); //recorder = null; } var recorder; // globally accessible document.getElementById('btn-start-recording').onclick = function() { this.disabled = true; captureCamera(function(camera) { setSrcObject(camera, video); video.play(); recorder = RecordRTC(camera, { type: 'video', }); recorder.startRecording(); // release camera on stopRecording recorder.camera = camera; document.getElementById('btn-stop-recording').disabled = false; }); }; document.getElementById('btn-stop-recording').onclick = function() { this.disabled = true; recorder.stopRecording(stopRecordingCallback); document.getElementById('btn-play-recording').disabled = false; document.getElementById('btn-upload').disabled = false; };
$("#btn-upload").on("click", function(){ this.disabled = true; document.getElementById('btn-play-recording').disabled = true; if(!recorder || !recorder.getBlob()) return; var blob = recorder.getBlob(); uploadBlob(blob); })
//ajax calling function uploadBlob(blob) { var formData = new FormData(); formData.append('video-blob', blob); formData.append('video-filename', 'demo.mp4'); $.ajax({ url: "{{SITE_URL}}/upload-video/", type: "POST", data: formData, processData: false, contentType: false, success: function(response) { $('#select_recordtype').modal('toggle'); $('#hiddenUrl').val(response.toString()); $('.recorder_box').hide(); var video = $('', { id: 'video', src: response, type: 'video/mp4', controls: true }); video.appendTo($('.selected_video')); $('.selected_video').show(); //alert('Successfully uploaded.'); //$("#record_now").hide().css('display','none'); //$("#pre-video").show().css('display','block'); }, error: function(jqXHR, textStatus, errorMessage) { alert('Error:' + JSON.stringify(errorMessage)); } }); }
and in controller only you have to create file:
#file creater @csrf_exempt def create_file(request):
if request.method == 'POST':
filename = request.POST.get('video-filename', '')
file = request.FILES.get('video-blob', '')
if file:
if not os.path.exists('static/video-msg/'):
os.mkdir('static/video-msg/')
with open('static/video-msg/' + filename, 'wb+') as
destination: for chunk in file.chunks(): destination.write(chunk) return HttpResponse('Created!') else: return HttpResponse("Blob getting Error")
else:
return HttpResponse("No Request given")
Best Regards,
Kashif AnwarSoftware Engineer Mobile: +919718577858
On Thu, May 3, 2018 at 3:36 PM, amitrathi1982 [email protected] wrote:
Hi Mauz, Is there any reference to upload recording using JAVA spring MVC.
Thanks, Amit
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/muaz-khan/WebRTC-Experiment/issues/48#issuecomment-386247686, or mute the thread https://github.com/notifications/unsubscribe-auth/AWnstDQ5258jFK2Bfp2rHsq9NV50cXF0ks5tutbCgaJpZM4Au2xH .
Dear Kashif, Thanks a lot for your response. It is working now.
Now I am getting one popup when starting recording: Please enable this command line flag: "--enable-usermedia-screen-capturing" Can you please help me how can I resolve it? Is there anything which can be downloaded automatically if required as page loads or handle programmatically.
Thanks a lot once more for your kind support.
Have you include RecordRTC.js?
Since var recorder is using this js, if so then error shouldn't happen, if you are getting some other please see something else going wrong, check you camera permission.
On Fri 4 May, 2018, 3:13 PM amitrathi1982, [email protected] wrote:
Dear Kashif, Thanks a lot for your response. It is working now.
Now I am getting one popup when starting recording: Please enable this command line flag: "--enable-usermedia-screen-capturing" Can you please help me how can I resolve it? Is there anything which can be downloaded automatically if required as page loads or handle programmatically.
Thanks a lot once more for your kind support.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/muaz-khan/WebRTC-Experiment/issues/48#issuecomment-386552316, or mute the thread https://github.com/notifications/unsubscribe-auth/AWnstM6F8kffcmj3JbpQ2Qryfi9rAsHOks5tvCKvgaJpZM4Au2xH .
Hi Kashif, Thanks for the response. Actually my requirement is to capture a particular window (say mozila/chrome or where this application is running) only with audio. It will also be good if I can capture only that Tab of browser window (If it can happen). So I did below steps:
- I am using "https://www.webrtc-experiment.com/RecordRTC/" demo and chosen "Microphone+Screen".
- I have downloaded this HTML at my local and downloaded all the ".JS" (including RecordRTC.js and other dependent JS) to my local from CDN URL.
- I ran this sample from localhost, On mozila it is working fine. But in chrome it is showing that popup. "Please enable this command line flag: "--enable-usermedia-screen-capturing" and showing "onMediaCapturingFailed: {name: "NotAllowedError", message: "Invalid state", constraint: undefined, toString: ƒ}" in browser console. Although in demo it is workiing fine (https://www.webrtc-experiment.com/RecordRTC/). So my stuck point is should I enable/add some security bypass code or something else. Please help me here.
Another point is: When I am doing it on mozila it show one popup to choose which window I want to record/share. Is there any setting/option where I can set default window to select automatically the window where application is running (current window).
Point 3: After stopping recording when I play this recording in new tab, it shows one URL: "http://localhost:8080/0eb129a1-1fd6-44a0-b78a-1071689ef5f5". My expectation here is, can we upload this video on server (As stream) directly even before stoping.
Thanks a lot Kasif once again.
@amitrathi1982 To fix screen capturing issues on localhost or on any https domain:
- Download this chrome plugin source code, modify
manifest.json
formatches
attribute only to set your own domain's permissions. Now openchrome://extensions/
and click "Load unpacked extension" button to locate the extension directory. - Otherwise use getScreenId.js. Which requires this plugin installation. However please make sure to run getScreenId only on localhost or on a real HTTPs domain. Don't run getScreenId on jsfiddle or inside-iframes. Iframes are not supported.
Here is a simple demo explains how to use getScreenId with RecordRTC.
Regarding "upload in realtime": the best solution is use a media-server where you will open RTCPeerConnection connections with the server.
RecordRTC accepts timeSlice
and ondataavailable
options that allows you get blobs instantly and upload to server after fixed intervals. Here is a simple demo. However your server must merge all files into a single file after recording finishes. Here is a similar demo using ffmpeg on server-side using nodejs. You can check a socketio demo as well.
Dear Mauz, Thanks for clarification. I am using below code to get screenId:
getScreenId(function (error, sourceId, screen_constraints) { // error == null || 'permission-denied' || 'not-installed' || 'installed-disabled' || 'not-chrome' // sourceId == null || 'string' || 'firefox'
if(navigator.userAgent.indexOf('Edge') !== -1 && (!!navigator.msSaveOrOpenBlob || !!navigator.msSaveBlob)) {
navigator.getDisplayMedia(screen_constraints).then(stream => {
document.querySelector('video').srcObject = stream;
}, error => {
alert('Please make sure to use Edge 17 or higher.');
});
return;
}
navigator.mediaDevices.getUserMedia(screen_constraints).then(function (stream) {
document.querySelector('video').srcObject = stream;
// share this "MediaStream" object using RTCPeerConnection API
}).catch(function (error) {
console.error(error);
});
}, 'pass second argument only if you want to capture speakers as well');
It is capturing screen successfully but audio (Microphone) is not being captured. I read above that to capture, we need to pass 2nd paramater (pass second argument only if you want to capture speakers as well). So which type of this parameter will be . Is that booelan "true" or else. I passed "true" but audio not captured.
Full function where I merged above code is given here: I know you might be busy in some important task, but please get few moment and take a look:
function captureAudioPlusScreen(config) { // Firefox screen capturing addon is open-sourced here: https://github.com/muaz-khan/Firefox-Extensions // Google Chrome screen capturing extension is open-sourced here: https://github.com/muaz-khan/Chrome-Extensions/tree/master/desktopCapture console.log("captureAudioPlusScreen function called.."); if(DetectRTC.browser.name === 'Firefox' || isLocalHost()) { **getScreenId(function (error, sourceId, screen_constraints) { // error == null || 'permission-denied' || 'not-installed' || 'installed-disabled' || 'not-chrome' // sourceId == null || 'string' || 'firefox'
console.log("sourceId-->"+sourceId + " : "+screen_constraints);
if(sourceId && sourceId != 'firefox') {
screen_constraints = {
video: {
mandatory: {
chromeMediaSource: 'screen',
maxWidth: 1920,
maxHeight: 1080,
minAspectRatio: 1.77
}
}
};
if (error === 'permission-denied')
return alert('Permission is denied.');
if (error === 'not-chrome')
return alert('Please use chrome.');
if (!error && sourceId) {
screen_constraints.video.mandatory.chromeMediaSource = 'desktop';
screen_constraints.video.mandatory.chromeMediaSourceId = sourceId;
}
}
navigator.getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
navigator.getUserMedia(screen_constraints, function (stream) {
console.log(" document.querySelector('video').src--"+ document.querySelector('video').src);
config.onMediaCaptured(stream);
addStreamStopListener(stream, function() {
config.onMediaStopped();
});
// document.querySelector('video').src = stream;
// share this "MediaStream" object using RTCPeerConnection API
}, function (error) {
console.error('getScreenId error', error);
alert('Failed to capture your screen. Please check Chrome console logs for further information.');
});
},'pass second argument only if you want to capture speakers as well');
}**
window.postMessage('get-sourceId', '*');
}
Hello Mauz, Thanks for your help. Now I am able to save audio and video using getScreenId.js.
I am using timeSlice option and set 20 seconds to upload data to server in chunks. Code: options.ondataavailable = function(blob) { button.blobs.push(blob); uploadBlob(blob, new Date().getTime()); };
In this case only first is opening in VLC player and subsequent files are not opening. Even first file size is around is 800KB and after that around 600 KB. Can you please guide here what I am missing.
To send file on server, code is: //ajax calling function uploadBlob(blob, fileName) { var formData = new FormData(); formData.append('video-blob', blob); formData.append('video-filename', "Demo_"+fileName+".mp4"); $.ajax({ url: "http://localhost:8080/services/recording/upload.html", type: "POST", data: formData, processData: false, contentType: false, success: function(response) { button.blobs.pop(blob); console.log("After length-"+button.blobs.length); }, error: function(jqXHR, textStatus, errorMessage) { alert('Error:' + JSON.stringify(errorMessage)); } }); }
@amitrathi1982 are you able to capture speakers? You may need to use CDN link or getScreenId script from this repo: https://github.com/muaz-khan/getScreenId
BTW, you need to merge all files using ffmpeg. Or maybe you can try this on nodejs server:
// i donno if this works on nodejs
var file = new Blob(arrayOfAllPieces, {
type: 'video/webm'
});
// write file to disk using fs.write
Did you check these demos?
- https://github.com/muaz-khan/RecordRTC/tree/master/RecordRTC-to-Nodejs
- https://github.com/muaz-khan/RecordRTC/tree/master/PHP-and-FFmpeg
Hi Mauz, Good morning! After merging, only first file (first 20 second recording) has audio and other (after 20 second) are silent.. Details are here: As I mentioned above I am using timeSlice option and set 20 seconds to upload data to server in chunks. So there is around 3 files for 1 minute recording. When I run directly only first file opened but not others. Now I merged all the recordings and after merging a single file is created and it runs successfully. But here is the issue in audio of subsequent files. After merging, only first file (first 20 second recording) has audio and other (after 20 second) are silent. Is there issue in sending recording file. I am missing something in subsequent files while sending to server?
Thanks again Mauz.
Hi Muaz, Sorry for wrong name in last posts
I am using time slice and every blob object as separate file. I believe that first blob object has some extra information that's why it is opening in VLC after saving and subsequent blob objects does not have that information. That's why subsequent blob objects are less in size. Am I correct? Please confirm and suggest some solution. I need your help.
Using below function: options.ondataavailable = function(blob) { button.blobs.push(blob); uploadLatestBlobToServer(blob); };
When I am uploading whole recording in single shot, then it is fine:
button.recordRTC.stopRecording(function(url) { if(button.blobs && button.blobs.length) { var blob = new File(button.blobs, getFileName(fileExtension), { type: mimeType }); //Upload this blob as last recording file when recording ends. button.recordRTC.getBlob = function() { return blob; }; uploadBlob(blob); } } });
Thanks a lot.
Hello Muaz, Everyone, Can you please help me in merging resulted multiple .mp4 files in to one. Right now I am using FFMPEG by below commands: Step1: Convert all files one by one in to intermediate file- 1. ffmpeg -i E:\recordings\Demo_1525840692968.mp4 -qscale:v 1 intermediate1.mpg 2. ffmpeg -i E:\recordings\Demo_1525840703000.mp4 -qscale:v 1 intermediate2.mpg 3. ffmpeg -i E:\recordings\Demo_1525840707080.mp4 -qscale:v 1 intermediate3.mpg Step 2: Merge intermediate files to one single "mpg" format file- ffmpeg -i concat:"intermediate1.mpg|intermediate2.mpg|intermediate3.mpg" -c copy intermediate_all.mpg Step 3: Convert last merged "mpg" format file to .mp4 ffmpeg -i intermediate_all.mpg -qscale:v 2 output.mp4
Can you please suggest single command to merge these or less steps. I used below command too. It show merged but when play, only first file merged and play.
Thanks, Amit
@amitrathi1982 Please move this thread to RecordRTC git so that I can easily track & comment:
- https://github.com/muaz-khan/RecordRTC/issues
BTW, one last comment. You can replace RecordRTC code with this lib and it will play complete recording after when it is merged:
- https://github.com/streamproc/MediaStreamRecorder
PS. I need to test RecordRTC-timeSlice myself before making a comment about it. I'll add a similar demo to RecordRTC git as well. [timeSlice+ffmpeg]
Thanks a lot Muaz. I will try it. Your views always valuable for me. Thanks once again.