RecordRTC works in Mac but not Windows - javascript

I am using angular 4 to implement an application which records audio using RecordRTC. I have implemented this in Mac it is working fine both safari and chrome.
But same code is not working in Windows 10.
Here is my code :
private stream: MediaStream;
private recordRTC: any;
#ViewChild('video') video;
ngAfterViewInit() {
// set the initial state of the video
let video:HTMLAudioElement = this.video.nativeElement;
video.muted = false;
video.controls = true;
video.autoplay = false;
}
toggleControls() {
let video: HTMLAudioElement = this.video.nativeElement;
video.muted = !video.muted;
video.controls = !video.controls;
video.autoplay = !video.autoplay;
}
successCallback(stream: MediaStream) {
var options = {
mimeType: 'audio/webm', // or video/webm\;codecs=h264 or video/webm\;codecs=vp9
bitsPerSecond: 128000 // if this line is provided, skip above two
};
this.stream = stream;
this.recordRTC = RecordRTC(stream, options);
this.recordRTC.startRecording();
let video: HTMLAudioElement = this.video.nativeElement;
video.src = window.URL.createObjectURL(stream);
this.toggleControls();
}
errorCallback() {
//handle error here
}
processVideo(audioVideoWebMURL) {
let video: HTMLAudioElement = this.video.nativeElement;
let recordRTC = this.recordRTC;
video.src = audioVideoWebMURL;
this.toggleControls();
var recordedBlob = recordRTC.getBlob();
recordRTC.getDataURL(function (dataURL) { });
}
startRecording() {
let mediaConstraints = {
audio: true
};
navigator.mediaDevices
.getUserMedia(mediaConstraints)
.then(this.successCallback.bind(this), this.errorCallback.bind(this));
}
stopRecording() {
let recordRTC = this.recordRTC;
recordRTC.stopRecording(this.processVideo.bind(this));
let stream = this.stream;
stream.getAudioTracks().forEach(track => track.stop());
}
How to make it work in windows?

Related

Recrod audio to flac file using MediaRecorder in electron.js/Chrome

I can record audio to ogg file in Electron and Chrome by creating blob this way
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
Full example code is this
if (navigator.mediaDevices) {
console.log('getUserMedia supported.');
const constraints = { audio: true };
let chunks = [];
navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
const mediaRecorder = new MediaRecorder(stream);
visualize(stream);
record.onclick = function() {
mediaRecorder.start();
console.log(mediaRecorder.state);
console.log("recorder started");
record.style.background = "red";
record.style.color = "black";
}
stop.onclick = function() {
mediaRecorder.stop();
console.log(mediaRecorder.state);
console.log("recorder stopped");
record.style.background = "";
record.style.color = "";
}
mediaRecorder.onstop = function(e) {
console.log("data available after MediaRecorder.stop() called.");
const clipName = prompt('Enter a name for your sound clip');
const clipContainer = document.createElement('article');
const clipLabel = document.createElement('p');
const audio = document.createElement('audio');
const deleteButton = document.createElement('button');
clipContainer.classList.add('clip');
audio.setAttribute('controls', '');
deleteButton.innerHTML = "Delete";
clipLabel.innerHTML = clipName;
clipContainer.appendChild(audio);
clipContainer.appendChild(clipLabel);
clipContainer.appendChild(deleteButton);
soundClips.appendChild(clipContainer);
audio.controls = true;
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
chunks = [];
const audioURL = URL.createObjectURL(blob);
audio.src = audioURL;
console.log("recorder stopped");
deleteButton.onclick = function(e) {
const evtTgt = e.target;
evtTgt.parentNode.parentNode.removeChild(evtTgt.parentNode);
}
}
mediaRecorder.ondataavailable = function(e) {
chunks.push(e.data);
}
})
.catch(function(err) {
console.log('The following error occurred: ' + err);
})
}
I want to create flac file so I tried
const blob = new Blob(chunks, { 'type': 'audio/flac; codecs=flac' });
When I check output file type using Linux file command I get webM in both cases.
How can I get output file in flac format?

WebRTC, getDisplayMedia() does not capture sound from the remote stream

I have a web application of my own, which is based on the peerjs library (It is a video conference).
I'm trying to make a recording with 'MediaRecorder', but I'm facing a very unpleasant case.
The code for capturing my desktop stream is the following:
let chooseScreen = document.querySelector('.chooseScreenBtn')
chooseScreen.onclick = async () => {
let desktopStream = await navigator.mediaDevices.getDisplayMedia({ video:true, audio: true });
}
I then successfully apply my received desktopStream to videoElement in DOM:
const videoElement = doc.querySelector('.videoElement')
videoElement.srcObject = desktopStream
videoElement.muted = false;
videoElement.onloadedmetadata = ()=>{videoElement.play();}
For example, I get desktopStream on the page with an active conference where everyone hears and sees each other.
To check the video and audio in desktopStream I play some video on the video player on the desktop.
I can hear any audio from my desktop but audio from any participant cannot be heard.
Of course, when I put the desktopStream in MediaRecorder I get a video file with no sound from anyone except my desktop. Any ideas on how to solve it?
Chrome's MediaRecorder API can only output one track.
The createMediaStreamSource can take streams from desktop audio and microphone, by connecting both together into one object created by createMediaStreamDestination it gives you the ability to pipe this one stream into the MediaRecorder API.
const mergeAudioStreams = (desktopStream, voiceStream) => {
const context = new AudioContext();
// Create a couple of sources
const source1 = context.createMediaStreamSource(desktopStream);
const source2 = context.createMediaStreamSource(voiceStream);
const destination = context.createMediaStreamDestination();
const desktopGain = context.createGain();
const voiceGain = context.createGain();
desktopGain.gain.value = 0.7;
voiceGain.gain.value = 0.7;
source1.connect(desktopGain).connect(destination);
// Connect source2
source2.connect(voiceGain).connect(destination);
return destination.stream.getAudioTracks();
};
It is also possible to use two or more audio inputs + video input.
window.onload = () => {
const warningEl = document.getElementById('warning');
const videoElement = document.getElementById('videoElement');
const captureBtn = document.getElementById('captureBtn');
const startBtn = document.getElementById('startBtn');
const stopBtn = document.getElementById('stopBtn');
const download = document.getElementById('download');
const audioToggle = document.getElementById('audioToggle');
const micAudioToggle = document.getElementById('micAudioToggle');
if('getDisplayMedia' in navigator.mediaDevices) warningEl.style.display = 'none';
let blobs;
let blob;
let rec;
let stream;
let voiceStream;
let desktopStream;
const mergeAudioStreams = (desktopStream, voiceStream) => {
const context = new AudioContext();
const destination = context.createMediaStreamDestination();
let hasDesktop = false;
let hasVoice = false;
if (desktopStream && desktopStream.getAudioTracks().length > 0) {
// If you don't want to share Audio from the desktop it should still work with just the voice.
const source1 = context.createMediaStreamSource(desktopStream);
const desktopGain = context.createGain();
desktopGain.gain.value = 0.7;
source1.connect(desktopGain).connect(destination);
hasDesktop = true;
}
if (voiceStream && voiceStream.getAudioTracks().length > 0) {
const source2 = context.createMediaStreamSource(voiceStream);
const voiceGain = context.createGain();
voiceGain.gain.value = 0.7;
source2.connect(voiceGain).connect(destination);
hasVoice = true;
}
return (hasDesktop || hasVoice) ? destination.stream.getAudioTracks() : [];
};
captureBtn.onclick = async () => {
download.style.display = 'none';
const audio = audioToggle.checked || false;
const mic = micAudioToggle.checked || false;
desktopStream = await navigator.mediaDevices.getDisplayMedia({ video:true, audio: audio });
if (mic === true) {
voiceStream = await navigator.mediaDevices.getUserMedia({ video: false, audio: mic });
}
const tracks = [
...desktopStream.getVideoTracks(),
...mergeAudioStreams(desktopStream, voiceStream)
];
console.log('Tracks to add to stream', tracks);
stream = new MediaStream(tracks);
console.log('Stream', stream)
videoElement.srcObject = stream;
videoElement.muted = true;
blobs = [];
rec = new MediaRecorder(stream, {mimeType: 'video/webm; codecs=vp8,opus'});
rec.ondataavailable = (e) => blobs.push(e.data);
rec.onstop = async () => {
blob = new Blob(blobs, {type: 'video/webm'});
let url = window.URL.createObjectURL(blob);
download.href = url;
download.download = 'test.webm';
download.style.display = 'block';
};
startBtn.disabled = false;
captureBtn.disabled = true;
audioToggle.disabled = true;
micAudioToggle.disabled = true;
};
startBtn.onclick = () => {
startBtn.disabled = true;
stopBtn.disabled = false;
rec.start();
};
stopBtn.onclick = () => {
captureBtn.disabled = false;
audioToggle.disabled = false;
micAudioToggle.disabled = false;
startBtn.disabled = true;
stopBtn.disabled = true;
rec.stop();
stream.getTracks().forEach(s=>s.stop())
videoElement.srcObject = null
stream = null;
};
};
Audio capture with getDisplayMedia is only fully supported with Chrome for Windows. Other platforms have a number of limitations:
there is no support for audio capture at all under Firefox or Safari;
on Chrome/Chromium for Linux and Mac OS, only the audio of a Chrome/Chromium tab can be captured, not the audio of a non-browser application window.

saving video giving Black Screen

I Am trying to save my my video but i keep getting a black video any reason a to why this could be happening
I have attached my code below for reference
i have kept the stat recording and stop recording button separate so that can use it late to bind other event-listeners
How would i go about saving my video
Jquery Is initialized above using jquery3
<video autoplay id="videoElement"></video>
<br>
<button style="height: 90px;width: 200px" id="start">Start</button>
<button style="height: 90px;width: 200px" id="stop">Stop</button>
download
<script>
$(function(){
var sessionkey = ""
var currentgesture = 4;
var key = "";
var width = 640; // We will scale the photo width to this
var height = 0; // This will be computed based on the input stream
var streaming = false;
var constraints = {
video: true,
audio: false,
width: {exact: 640},
height: {exact: 480},
frameRate: { ideal: 10, max: 12 }
}
const video = document.querySelector('video');
//Check For WebCam
function hasGetUserMedia() {
return !!(navigator.mediaDevices &&
navigator.mediaDevices.getUserMedia);
}
if (hasGetUserMedia()) {
runVideo()
} else {
alert('Not Supported! Please use another browser');
}
var chunks = []
;
var mediaRecorder
function runVideo(){
navigator.mediaDevices.getUserMedia(constraints).
then(async (stream) => {
mediaRecorder= new MediaRecorder(stream,{ mimeType: 'video/webm'})
video.srcObject = stream;
mediaRecorder.onstart = function(e) {
chunks = []
};
mediaRecorder.ondataavailable = function(e) {
chunks.push(e.data);
console.log(chunks)
};
mediaRecorder.onstop = function(e) {
var blob = new Blob(chunks,{ 'type' : 'video/webm' });
console.log(blob)
downloadLink = document.getElementById('download');
downloadLink.href = URL.createObjectURL(blob);
downloadLink.download = 'acetest.webm';
// socket.emit('radio', blob);
};
console.log(mediaRecorder)
});
}
$("#start").click(function(){
mediaRecorder.start()
})
$("#stop").click(function(){
mediaRecorder.stop()
})
</script>

how can i save videos in webm format instead of mkv format

I need a help. I have a javascript code in my site that record videos and save them on the server. The format in which the videos are saved depends on the browser I am using, because if I use Opera or Chrome, the videos are saved in MKV format, if I use Firefox instead, the videos are saved in WEBM format. The problem is that the videos I save using Opera and Chrome (i.e. MKV) Firefox cannot read them, while Opera and Chrome read the WEBM videos generated with firefox without problems.
How can I make Opera and Chrome also save videos in WEBM so I no longer have the problem?
JavaScript code:
let constraintObj = {
audio: true,
video: {
facingMode: "user",
width: { min: 640, ideal: 1280, max: 1920 },
height: { min: 480, ideal: 720, max: 1080 }
}
};
// width: 1280, height: 720 -- preference only
// facingMode: {exact: "user"}
// facingMode: "environment"
//handle older browsers that might implement getUserMedia in some way
if (navigator.mediaDevices === undefined) {
navigator.mediaDevices = {};
navigator.mediaDevices.getUserMedia = function(constraintObj) {
let getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
if (!getUserMedia) {
return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
}
return new Promise(function(resolve, reject) {
getUserMedia.call(navigator, constraintObj, resolve, reject);
});
}
}else{
navigator.mediaDevices.enumerateDevices()
.then(devices => {
devices.forEach(device=>{
console.log(device.kind.toUpperCase(), device.label);
//, device.deviceId
})
})
.catch(err=>{
console.log(err.name, err.message);
})
}
navigator.mediaDevices.getUserMedia(constraintObj)
.then(function(mediaStreamObj) {
//connect the media stream to the first video element
let video = document.querySelector('video');
if ("srcObject" in video) {
video.srcObject = mediaStreamObj;
} else {
//old version
video.src = window.URL.createObjectURL(mediaStreamObj);
}
video.onloadedmetadata = function(ev) {
//show in the video element what is being captured by the webcam
video.play();
};
//add listeners for saving video/audio
let start = document.getElementById('btnStart');
let stop = document.getElementById('btnStop');
let save = document.getElementById('btnSave');
let vidSave = document.getElementById('vid2');
let mediaRecorder = new MediaRecorder(mediaStreamObj);
let chunks = [];
var blob = null;
document.getElementById("vid2").style.visibility = "hidden";
document.getElementById("btnSave").style.visibility = "hidden";
var contatore=0;
var dontstop=0;
save.addEventListener('click', (ev)=>{
contatore = 0;
const formData = new FormData();
formData.append('video', blob);
fetch('videoRec', {
method: 'POST',
body: formData
})
.then(response => { console.log('upload success, ');
document.getElementById('response').innerHTML="Video salvato con successo, ";
})
.catch(error => {console.log('error');
document.getElementById('response').innerHTML="Errore durante il caricamento del video. Riprova.";
})
});
start.addEventListener('click', (ev)=>{
dontstop=1;
//if user already started video before, ask him if want to save that video before
//recording another video
if(contatore!=0){
var domanda=confirm("Il video appena registrato andrĂ  eliminato. Vuoi Procedere?");
if (domanda === false) {
exit;
}
}
//when user's recording, vid2 must be hidden
if(document.getElementById("vid2").style.visibility=="visible"){
document.getElementById("vid2").style.visibility="hidden";
document.getElementById("btnSave").style.visibility="hidden";
document.getElementById('response').innerHTML=" ";
}
//start recording
mediaRecorder.start();
console.log(mediaRecorder.state);
//disable start button and enable stop button
document.getElementById('btnStart').disabled=true;
document.getElementById('btnStop').disabled=false;
//contatore increments when user records, so if he starts another rec without stopping before
//ask him if want to save the last video
contatore++;
var timeleft = 5; //video must be 120 seconds
downloadTimer = setInterval(function(){
if(timeleft <= 0){
//after 120 seconds record will stops automatically
clearInterval(downloadTimer); //the countdown disappared
document.getElementById("countdown").innerHTML = "Finished";
mediaRecorder.stop();
console.log(mediaRecorder.state);
document.getElementById('btnStart').disabled=false;
document.getElementById('btnStop').disabled=true;
video.onloadedmetadata = function(ev) {
chunks.push(ev.data);
};
// vid2 appears
document.getElementById("vid2").style.visibility = "visible";
document.getElementById("btnSave").style.visibility = "visible";
blob = new Blob(chunks, { 'type' : 'video/webm;' });
chunks = [];
let videoURL = window.URL.createObjectURL(blob);
vidSave.src = videoURL;
} else {
//else countdown continues
document.getElementById("countdown").innerHTML = timeleft + " seconds remaining";
}
timeleft -= 1;
}, 1000)
})
stop.addEventListener('click', (ev)=>{
if(dontstop!=1){
exit;
}
mediaRecorder.stop();
console.log(mediaRecorder.state);
document.getElementById('btnStart').disabled=false;
document.getElementById('btnStop').disabled=true;
clearInterval(downloadTimer);
document.getElementById("countdown").innerHTML = "Finished";
document.getElementById("vid2").style.visibility = "visible";
document.getElementById("btnSave").style.visibility = "visible";
});
mediaRecorder.ondataavailable = function(ev) {
chunks.push(ev.data);
}
mediaRecorder.onstop = (ev)=>{
blob = new Blob(chunks, { 'type' : 'video/webm;' });
chunks = [];
let videoURL = window.URL.createObjectURL(blob);
vidSave.src = videoURL;
}
})
.catch(function(err) {
console.log(err.name, err.message);
});
Thank you very much!
Gennaro
you can try to fix the mimetype to video/webm;codecs=VP8, it should work with any browser supporting MediaRecorder

how to detect headphone and cam in recordrtc

How to detect headphone and cam when calling start recording function in recordRTC liabrary.
btnStartRecording.onclick = function() {
btnStartRecording.disabled = true;
captureUserMedia(function(stream) {
mediaStream = stream;
videoElement.src = window.URL.createObjectURL(stream);
videoElement.play();
videoElement.muted = true;
videoElement.controls = false;
// it is second parameter of the RecordRTC
var audioConfig = {};
if (!isRecordOnlyAudio) {
audioConfig.onAudioProcessStarted = function() {
// invoke video recorder in this callback
// to get maximum sync
videoRecorder.startRecording();
};
}
audioRecorder = RecordRTC(stream, audioConfig);
if (!isRecordOnlyAudio) {
// it is second parameter of the RecordRTC
var videoConfig = {type: 'video'};
videoRecorder = RecordRTC(stream, videoConfig);
}
audioRecorder.startRecording();
// enable stop-recording button
btnStopRecording.disabled = false;
});
};
If any method in captureUserMedia that detects devices and return error message.

Categories

Resources