I am currently working with webRTC and therefore use the getUserMedia() function. When doing this a red icon appears inside the tab-header. Is there a way to remove this symbol? I set my microphone stream to undefined after a certain task, but the symbol is still shown there.
You have to stop the MediaStream (MediaStreamTracks) you've acquired with getUserMedia
stream.getTracks().forEach(track => track.stop());
stream.stop(); // deprecated in FFox
Related
Unfortunately, from time to time when making a one-on-one video call using react-native-webrtc one of the two video streams freezes or becomes black. Is there a way to detect when that happens programmatically? Thx in advance!
It looks like each video track has a listener that fires as soon as the stream freezes.
In react native it's the onmute listener:
stream.getVideoTracks().forEach(videoTrack => {
videoTrack.onmute = () => {
console.log("Frozen video stream detected!");
};
});
Note that in React Native detecting frozen streams with this method only seems to work for remote tracks!
To detect if a stream is currently frozen I use the muted property on the video track:
console.log(videoTrack.muted); // true when frozen
Another way I've found but haven't explored further is the getStats() method on the RTCPeerConnection. It returns a promise with a huge amount of data that can be used to detect frozen video streams and a lot more I suppose.
Chrome 73 added media key support for playing videos in the browser (e.g. YouTube). I'm trying to make a chrome extension that let's you use media keys for both Chrome and system media (like normal control for Spotify or media players). I can intercept the media key event in Chrome using the MediaSession API, but have no idea if it is possible to also 'free' the media key event and let it propagate to the next system media process. Does anyone even know it if possible/how I could do it?
This is how I am currently capturing the media key events ('play', 'pause', 'nexttrack' and 'previoustrack'):
window.onload = function() {
navigator.mediaSession.setActionHandler('play', function() {
console.log('play media key pressed');
playMedia(document);
});
}
Couldn't find a way to get JS to play system media, so to get around this I sent a message from the content scripts to the background process, which then sent a message to every tab, telling them to stop their respective videos (pause it and remove the source) to let the user play system media, and then restart the videos.
Since Apple disabled the ability to autoplay audio via HTMLMediaElement.play()
in javascript without user interaction, I am not sure how I should play a sound when a user gets a chat message before interacting with the DOM after the page loads.
socket.on("receive message", data => {
const receiveSound = new Audio("1.mp3");
messages.push(data);
receiveSound.play();
});
I tried playing the audio element on a mousemove event. I also tried to fake a click() through an element on a React ref to initially activate it. Neither solutions worked.
Is there a way to autoplay an audio element if there is a message coming in? It must be possible since YouTube can autoplay videos without interaction.
Every time I try to play the audio, I get this error:
Unhandled Rejection (NotAllowedError): The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
There is a way that you can make Safari play a sound without necessarily having to allow it there in the site settings.
According to the webkit documentation, it makes explicit that the user needs to interact to play the audio/video, in this case by the click, but he does not say that after you play some audio he lets you play any other audio then without any problem. With this in mind, you can for example run some script on your index.html where it will play your notification audio without any volume and then you can run it again without any problem, as in the example below:
function unlockAudio() {
const sound = new Audio('path/to/your/sound/notification.mp3');
sound.play();
sound.pause();
sound.currentTime = 0;
document.body.removeEventListener('click', unlockAudio)
document.body.removeEventListener('touchstart', unlockAudio)
}
document.body.addEventListener('click', unlockAudio);
document.body.addEventListener('touchstart', unlockAudio);
To run your code after this workaround, just do it this way:
function soundNotification() {
const sound = new Audio('path/to/your/sound/notification.mp3');
const promise = sound.play();
if (promise !== undefined) {
promise.then(() => {}).catch(error => console.error);
}
}
Remembering that the above example is just to show you an alternative, there are several ways you can solve this problem, just keep in mind that you will need to play some sound before...
What solved it for me was using HowlerJS
from Docs:
howler.js is an audio library for the modern web. It defaults to Web
Audio API and falls back to HTML5 Audio. This makes working with audio
in JavaScript easy and reliable across all platforms.
I am attempting to get a webpage to play a short notification sound whenever an icon changes colour. Using HTML5 this is the very simple matter of:
audio.play('ping.mp3');
...however, I need IE8 compatibility and audio.play() obviously causes an error whenever running in IE8 since the browser does not support HTML5.
I can live without the sound playing for IE8 users as there will still be a visible indication on screen, I just need to IE8-proof the code such that it doesnt throw an error and stop the script.
Try to check first if you can create the element. If yes, then it means audio tags are supported and then you can proceed with your code playing the audio
var hasAudioSupport = !!(document.createElement('audio').canPlayType);
I'm trying to remove a track from a MediaStream. MediaStream.removeTrack() removes the track from the stream, but the camera light is left on indicating that the camera is still active.
https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack?redirectlocale=en-US&redirectslug=DOM%2FMediaStreamTrack
This references a stop() method which I suppose would stop the camera completely, In chrome however I get "Object MediaStreamTrack has no method 'stop'"
Is there a way around this or do I have to stop the whole stream and then recreate it with the tracks I don't want gone? As an example, I want to remove the video track while the audiotrack is still there.
MediaStreamTrack.stop() is now added to the Chrome.
MediaStream.stop() is deprecated in Chrome 45.
You should use MediaStream.getVideoTracks() to get video tracks and stop the track using MediaStreamTrack.stop()
for stopping specific media stream, Maybe this help: (Link)
function stopStreamedVideo(videoElem) {
const stream = videoElem.srcObject;
const tracks = stream.getTracks();
tracks.forEach(function(track) {
track.stop();
});
videoElem.srcObject = null;
}
You need to call stop() on the MediaStream, not a MediaStreamTrack.
Take a look at simpl.info/gum. From the console, call stream.stop(): recording stops and the video camera light goes off.
It looks like the proper way to deal with this issue is to stop your MediaStream, recreate (and reattach) it as an audio-only one and then renegotiate the PeerConnection session. Unfortunately, Firefox currently doesn't support renegotiation mid-session.
The only viable hack is thus to also recreate the PeerConnection with the new MediaStream as suggested here (see "Adding video mid-call").