HTML5 Video Tag Volume Support - html

i had a question
on some devices like iPad and Android Tables you cannt change Volume of Video Tags becuase Volume API dont supported on this devices. have yo a idea how i can detect if this isnt support?

The best I could come up with is this:
function volumeChangeSupported () {
var ua = navigator.userAgent.toLowerCase();
// got information from jplayer:
var noVolume = /ipad|iphone|ipod|android|blackberry|windows ce|windows phone|webos|playbook/.exec(ua);
if (noVolume) {
if (noVolume[0] === 'android' && /gecko/.test(ua)) {
// Firefox on android DOES support changing the volume:
return true;
}
else {
return false;
}
}
return true;
}
This doesn't really "detect" support for changing the volume. I got this information partly from jPlayer and partly from my own experience testing Firefox 19 on an old Android 3 tablet. Who knows if Firefox on an Android phone or a different Android version behaves differently.
But before this I tried to detect volume change support like this:
function volumeChangeSupported () {
var audio = new Audio();
audio.volume = 0.5;
return audio.volume === 0.5;
}
This yielded the correct result for iPhone Safari and Android Firefox, but not for other Android Browsers (the "Android Browser" and "Dolphin", which can't change the volume but had audio.volume === 0.5 to be true).

Related

Are there requirements in the iPhone (iOS 13) settings for HTML5 Speech Synthesis to work?

I've already searched and found a couple of questions about speech synthesis issues on iOS.
Like this one:
JS Speech Synthesis Issue on iOS
I have implemented all the work-arounds I could find and I don't have any error in the console. Still I get no sound while it works fine on Android and desktop. Even the codepen shared in the question above doesn't work but the author claims it should.
So, this question is more about the device / OS itself: is there anything in an iOS device such as the iPhone, that could prevent text to speech to work? (yes, I checked the volume)
My iOS version is 13.4.1
For completeness sake, my code looks like this:
let hasEnabledVoice = false
/**
* Bug in some browser that dont load voices
*/
if (window.speechSynthesis) {
// Preload voices
speechSynthesis.getVoices()
/**
* iOS hack
* https://stackoverflow.com/questions/32193704/js-speech-synthesis-issue-on-ios/62587365#62587365
*/
document.addEventListener('click', () => {
if (hasEnabledVoice) {
return
}
const fakeUtterance = new SpeechSynthesisUtterance('Hello')
fakeUtterance.volume = 0
speechSynthesis.speak(fakeUtterance)
hasEnabledVoice = true
})
}
function speak(sentence) {
if (window.speechSynthesis) {
const utterance = new SpeechSynthesisUtterance(sentence)
utterance.voice = speechSynthesis.getVoices()[0]
utterance.volume = 1
utterance.rate = 0.9
speechSynthesis.speak(utterance)
}
}

mediastreamtrack.getsources not supported in firefox, how to do the equivalent

is there an equivalent way to get the list of video devices connected to the PC? I have an external webcam connection in addition to the build-in one.
mediastreamtrack.getsources is working in chrome but firefox reported "TypeError: MediaStreamTrack.getSources is not a function". I am running firefox version 25.0.1
Thanks!
Please use below-mentioned code. It is working properly giving all audio and video devices list.
navigator.mediaDevices.enumerateDevices()
.then(function (devices) {
devices.forEach(function (device) {
var option = document.createElement('option');
option.value = device.deviceId;
if (device.kind === 'videoinput') {
option.text = device.label || 'camera' + (videoSelect.length + 1);
videoSelect.appendChild(option);
} else if (device.kind == 'audioinput') {
option.text = device.label || 'mic' + (audioSelect.length + 1);
audioSelect.appendChild(option);
}
});
})
.catch(function (err) {
console.log(err.name + ": " + err.message);
});
MediaDevices.enumerateDevices() is now supported by Firefox and Chrome.
As of Nightly 28.0a1 Firefox does not have anything equivalent to Chrome's MediaStreamTrack.getSources. So, no, there is not currently a way to get a list of the local audio and video devices in Firefox.
I asked the developers working on Firefox's WebRTC implementation and they say this is a planned feature but no ETA on when it will land. You can view the irc log (scroll to 16:17) if you're curious.
Also, here's the relevant part in the draft W3C spec.
As of Firefox 34, MediaStreamTrack is now available.
https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack

Using html5 to capture microphone input on mobile chrome

I am trying to record from the microphone using HTML5 in Chrome 29 Beta for Android (it has enabled web audio support in its beta 29). In the code below, ProcessAudio is the web audio filter function, in which I receive the input buffer from the microphone. I get the correct sample size. However, the audio pcm samples in mobile chrome are always zero. Does chrome disable the input to the audio filters in its mobile version? Has anybody got audio recording working using HTML5 in chrome mobile version?
The following code works fine in chrome (desktop version).
<!DOCTYPE HTML>
<html>
<head>
<script>
function GetMedia(obj, fnSuccess, fnFailure)
{
if(navigator.getUserMedia)
{
return navigator.getUserMedia(obj, fnSuccess, fnFailure);
}
else if(navigator.webkitGetUserMedia)
{
return navigator.webkitGetUserMedia(obj, fnSuccess, fnFailure);
}
else if(navigator.mozGetUserMedia)
{
return navigator.mozGetUserMedia(obj, fnSuccess, fnFailure);
}
else if(navigator.msGetUserMedia)
{
return navigator.msGetUserMedia(obj, fnSuccess, fnFailure);
}
alert("no audio capture");
}
var incrementer = 0;
function ProcessAudio(e)
{
var inputBuffer = e.inputBuffer.getChannelData(0);
var outputBuffer = e.outputBuffer.getChannelData(0);
outputBuffer.set(inputBuffer, 0);
document.getElementById("display").innerText =
incrementer + " " + inputBuffer[0];
incrementer++;
}
var context = null;
function Success(localMediaStream)
{
context = new window.webkitAudioContext();
var microphone = context.createMediaStreamSource(localMediaStream);
var node = context.createScriptProcessor(4096, 1, 1);
node.onaudioprocess = ProcessAudio;
microphone.connect(node);
node.connect(context.destination);
}
function Error(err)
{
alert("no audio support");
}
function load(e)
{
GetMedia({audio:true,video:false}, Success, Error);
}
</script>
</head>
<body onload="load(event)">
<div>Audio Player</div>
<div id="display"></div>
<video id="localvideo" autoplay="autoplay" style="opacity:1"></video>
</body>
</html>
We now have Web Audio input working in Chrome for Android Beta (31.0.1650.11).
There's an issue with inputBuffer in Chrome beta for Android right now - it always contains zeros (at least on those devices that I tested) as you mentioned - confirmed. That ain't much of help but for demo purposes the best I could achieve right now is playing "live" input stream via <audio> object. See here. Hit "record" and then start playing the audio object. The rest beyond that is TARFU in the current beta. Guess I'm waiting for G-folks to patch it asap. What I found out though, is that zingaya.com works fine (that is, records your audio and plays it back to you) on Chrome Beta for Android. Just try them out and they'll play back your stream. Apparently, this is made by leveraging WebRTC. In other words you evidently can record an audio stream that way, I haven't figured out how to do it just yet. Post it up if you come up with something. G-guys are working fast on the other hand - they've released a new beta version less than a week ago that at least can play audio fetched with XHR. The version prior to that couldn't do that even.

How do I detect Chromium specifically vs. Chrome?

Is there a way to detect if a visitor to my site is running Chromium as opposed to Google Chrome? Even basic UA sniffing (which I know is bad practice) would suffice for my particular case, but it appears that Chromium and Chrome share the same UA string – is that correct? Is there any other way that I can differentiate between the two?
Note:
This no longer works, because now all Chrome-based-navigators have all plugins.
New Chromium-versions do have the PDF-plugin, too.
But they also have Chromium-plugins, so if any plugin starts with "Chromium", it's Chromium:
function isChromium() {
for (var i = 0, u = "Chromium", l = u.length; i < navigator.plugins.length; i++) {
if (navigator.plugins[i].name != null && navigator.plugins[i].name.substr(0, l) === u)
return true;
}
return false;
}
Also, use this to identify Microsoft Chredge (aka. Anaheim)
function isEdg() {
for (var i = 0, u = "Microsoft Edg", l = u.length; i < navigator.plugins.length; i++) {
if (navigator.plugins[i].name != null && navigator.plugins[i].name.substr(0, l) === u)
return true;
}
return false;
}
Chrome ships with a built-in PDF reader, Chromium doesn't.
You could detect this by using JavaScript:
function isChrome() { // Actually, isWithChromePDFReader
for (var i=0; i<navigator.plugins.length; i++)
if (navigator.plugins[i].name == 'Chrome PDF Viewer') return true;
return false;
}
This method is not 100% reliable, because users can copy the PDF reader binary from Chrome to their Chromium directory, see this answer on Ask Ubuntu.
There's almost no difference between Chromium and Chrome (certainly not in the rendering or JavaScript engine), so why do you want to spot the difference?
Starting with Chromium 84 there's a new method called User-Agent Client Hints reference
You can check if the userAgentData property exists and look for brand data. It will return an array that looks something like this.
[{
"brand": " Not;A Brand",
"version": "99"
}, {
"brand": "Google Chrome",
"version": "91"
}, {
"brand": "Chromium",
"version": "91"
}]
userAgentData.brands will contain varying values in a varying order, so don't rely on something appearing at a certain index. Instead check if the property exists in the array.
if (navigator.userAgentData) {
let vendors = window.navigator.userAgentData.brands;
if (vendors.filter(e => e.brand === 'Google Chrome').length > 0) {
console.log('Chrome')
} else {
console.log('Chromium')
}
}
Here is a variation to Paul W.'s answer that works for Chromium version 42 and above:
function isChromium() { // Actually, isWithChromiumPDFReader
for (var i=0; i<navigator.plugins.length; i++)
if (navigator.plugins[i].name == 'Chromium PDF Viewer') return true;
return false;
}
This of course only works if the plugin has not been disabled by the user.
Here is another way, using SpeechSynthesis feature.
Google Chrome Browser ships TTS voices, where Chromium browsers (incl. Brave) do not. Voices can be installed manually, with espeak (on linux) however the Google voices all start with Google, where the manually installed voices do not. As far as I know the Chrome voices are propriety, not free.
The collection of voices is an Array where each voices looks like this:
{
voiceURI: "Google Deutsch",
name: "Google Deutsch",
lang: "de-DE",
localService: false,
default: true
}
We just need to find one who's name/URI starts with Google ...
function hasGoogleVoices() {
return window.speechSynthesis.getVoices()
.some(v => /^google/i.test(v.name));
}
(Tested on Linux for Chrome, Brave, Chromium and Firefox)
Please can someone check Safari and Windows. Thx.
Could not comment on https://stackoverflow.com/a/68428992/14238203 Josh Answer.
On latest Chrome and Chromium (Oct 2021) some of the solutions returns true for both, so I had to find a different solution.
I took https://stackoverflow.com/a/63724166/14238203 fliptopbox code and implmented Josh answer.
const isChrome = navigator.userAgentData.brands.some((v) => /^google/i.test(v.brand));
The issue with Josh answer is that if you try this when just loading a page, the getVoices() returns empty array until all the voices are loaded (page finished loading)
A promise solution to that here - https://stackoverflow.com/a/59786665/14238203
For my use case it was a bit cumbersome with the getVoices() so I used the user agent hints solution.

Does Safari implement the most current protocol for web sockets?

Straight from the first line of the HTML5 Rocks tutorial on web sockets it is not working.
var connection = new WebSocket('ws://html5rocks.websocket.org/echo', ['soap', 'xmpp']);
connection.onopen = function () { alert("open"); };
connection.onerror = function () { alert("error"); };
It works in chrome, opera, ie. It doesn't work in Safari. Am I doing something wrong?
http://jsfiddle.net/xSNpM/2/
apple stopped updating safari on windows. this works on an up to date version of safari.