VideoJS HTML5 Video JS How to boost volume above maximum? - javascript

Its possible there's no solution to this but I thought I'd inquire anyway. Sometimes a video is really quiet and if I turn the volume of my computer up accordingly then other sounds I have become way too loud as a result. It would be nice to be able to boost the volume above maximum.
I did a search on google which literally turned up nothing at all, not even results related to videojs at all in fact. Some videos my Mac is almost at max volume to hear the video's speech well so it would not be feasible to start with everything at a lower volume and adjust accordingly.
I tried with:
var video = document.getElementById("Video1");
video.volume = 1.0;
And setting it to anything above 1.0 but the video then fails to open at all:
var video = document.getElementById("Video1");
video.volume = 1.4; /// 2.0 etc

Based on: http://cwestblog.com/2017/08/17/html5-getting-more-volume-from-the-web-audio-api/
You can adjust the gain by using the Web Audio API:
function amplifyMedia(mediaElem, multiplier) {
var context = new(window.AudioContext || window.webkitAudioContext),
result = {
context: context,
source: context.createMediaElementSource(mediaElem),
gain: context.createGain(),
media: mediaElem,
amplify: function(multiplier) {
result.gain.gain.value = multiplier;
},
getAmpLevel: function() {
return result.gain.gain.value;
}
};
result.source.connect(result.gain);
result.gain.connect(context.destination);
result.amplify(multiplier);
return result;
}
amplifyMedia(document.getElementById('myVideo'), 1.4);
The multiplier you pass to the function is at same level as the video volume, 1 being the 100% volume, but in this case you can pass a higher number.
Can't post any working demo or JSFiddle because Web Audio API requires a source from the same origin (or CORS compatible). You can see the error in the console: https://jsfiddle.net/yuriy636/41vrx1z7/1/
MediaElementAudioSource outputs zeroes due to CORS access restrictions
But I have tested locally and it works as intended.

If you have access to the source files, rather than trying to boost on the fly using Javascript (for that the Web Audio API answer from #yuriy636 is the best solution) then you can process the video locally using something like ffmpeg.
ffmpeg -i input.mp4 -filter:a "volume=1.5" output.mp4
This will apply a filter to the input.mp4 file that just adjusts the volume to 1.5x the input and creates a new file called output.mp4.
You can also set a decibel level:
ffmpeg -i input.mp4 -filter:a "volume=10dB" output.mp4
or review the instructions to normalize audio etc.

Related

How to choose a specific audio output device in Firefox or Chrome?

The bounty expires in 2 days. Answers to this question are eligible for a +100 reputation bounty.
Basj is looking for a canonical answer.
I'm building a low-latency sampler in the browser (using Javascript, WASM, etc.).
How to choose, from Javascript, a specific audio output device for Chrome or Firefox?
I see there is Audio Output API but there are not many examples (and by the way navigator.mediaDevices.selectAudioOutput is undefined on my Chrome 109).
For example, how to make Chrome use Asio4All as main output device?
(Note: using an ASIO device such as the free Asio4All driver can make the latency drop from 30 milliseconds to 5 milliseconds, even on an old computer).
There is also Audio Output Devices API which can be used to achieved the similar functionality.
// First Create a new audio element
var audio = new Audio("https://samplelib.com/lib/preview/mp3/sample-3s.mp3");
// Get the list of available audio output devices
navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
// Filter the devices to get only the audio output ones
var audioOutputDevices = devices.filter(function(device) {
return device.kind === "audiooutput";
});
// Log the devices to the console
console.log(audioOutputDevices);
// If there is at least one audio output device, use the first one as the output device
if (audioOutputDevices.length > 0) {
// Set the sink ID of the audio element to the device ID of the first audio output device
audio.setSinkId(audioOutputDevices[0].deviceId)
.then(function() {
// Play the audio
audio.play();
})
.catch(function(error) {
// Handle any errors
console.error(error);
});
}
})
The audioOutputDevices[] can be leveraged to choose between vaious output devices.

no sound after call a method - setVideoProfile()

I have a problem, after subscribe to a remote stream I call a method - setVideoProfile() then there is no sound after that
this.client.on('stream-subscribed', (event) => {
let remoteStream = event.stream;
remoteStream.play(bindTag, {fit: 'contain'});
remoteStream.setAudioVolume(100);
remoteStream.setVideoProfile('120p_1');
});
when I comment //remoteStream.setVideoProfile('120p_1'); the sound works
I use AgoraRTC v2.8.0
has anyone encountered this?
setAudioVolume accepts only a number in the range [0,100] - both inclusive
Setting 0 mutes the audio and setting to 100 is maximum volume.
You can't pass in an arbitrary string like '120p_1'. That's why you do not hear any sound.
Update (from comments below)
You cant' set video profiles on remote streams. You can set this only on local streams. You should instead use dual streams and set a fallback mode if you want the user to receive a low-quality version of the remote video
client.enableDualStream(function() {
console.log("Enable dual stream success!")
}, function(err) {
console.log(err)
});
// Configuration for the receiver. When the network condition is poor, receive audio only.
client.setStreamFallbackOption(remoteStream, 2);
see full documentation:
video fallback https://docs.agora.io/en/Interactive%20Broadcast/fallback_web?platform=Web
dual streams https://docs.agora.io/en/Interactive%20Broadcast/API%20Reference/web/interfaces/agorartc.client.html#enabledualstream

IE 9 and 10 yield unexpected and inconsistent MediaError's

We have a set of HTML blocks -- say around 50 of them -- which are iteratively parsed and have Audio objects dynamically added:
var SomeAudioWrapper = function(name) {
this.internal_player = new Audio();
this.internal_player.src = this.determineSrcFromName(name);
// ultimately an MP3
this.play = function() {
if (someOtherConditionsAreMet()) {
this.internal_player.play();
}
}
}
Suppose we generate about 40 to 80 of these on page load, but always the same set for a particular configuration. In all browsers tested, this basic strategy appears to work. The audio load and play successfully.
In IE's 9 and 10, a transient bug surfaces. On occasion, calling .play() on the inner Audio object fails. Upon inspection, the inner Audio object has a .error.code of 4 (MEDIA_ERR_SRC_NOT_SUPPORTED). The file's .duration shows NaN.
However, this only happens occasionally, and to some random subset of the audio files. E.g., usually file_abc.mp3 plays, but sometimes it generates the error. The network monitor shows a successful download in either case. And attempting to reload the file via the console also fails -- and no requests appears in IE's network monitor:
var a = new Audio();
a.src = "the_broken_file.mp3";
a.play(); // fails
a.error.code; // 4
Even appending a query value fails to refetch the audio or trigger any network requests:
var a = new Audio();
a.src = "the_broken_file.mp3?v=12345";
a.play(); // fails
a.error.code; // 4
However, attempting the load the broken audio file in a new tab using the same code works: the "unsupported src" plays perfectly.
Are there any resource limits we could be hitting? (Maybe the "unsupported" audio finishes downloading late?) Are there any known bugs? Workarounds?
I think we can pretty easily detect when a file fails. For other compatibility reasons we run a loop to check audio progress and completion stats to prevent progression through the app (an assessment) until the audio is complete. We could easily look for .error values -- but if we find one, what do we do about it!?
Addendum: I just found a related question (IE 9/10/11 sound file limit) that suggests there's an undocumented limit of 41 -- not sure whether that's a limit of "41 requests for audio files", "41 in-memory audio objects", or what. I have yet to find any M$ documentation on the matter -- or known solutions.
Have you seen these pages on the audio file limits within IE? These are specific to Sound.js, but the information may be applicable to your issue:
https://github.com/CreateJS/SoundJS/issues/40 ...
Possible solution as mentioned in the last comment: "control the maximum number of audio tags depending on the platform and reuse these instead of recreating them"
Additional Info: http://community.createjs.com/kb/faq/soundjs-faq (see the section entitled “I load a lot of sounds, why am running into errors in Internet Explorer?”)
I have not experienced this problem in Edge or IE11. But, I wrote a javascript file to run some tests by looping through 200 audio files and seeing what happens. What I found is that the problem for IE9 and IE10 is consistent between ALL tabs. So, you are not even guaranteed to be able to load 41 files if other tabs have audio opened.
The app that I am working on has a custom sound manager. Our solution is to disable preloading audio for IE9 and IE10 (just load on demand) and then when the onended or onpause callback gets triggered, to run:
this.src = '';
This will free up the number of audio that are contained in IE. Although I should warn that it may make a request to the current page the user is on. When the play method in the sound manager is called again, set the src and play it.
I haven't tested this code, but I wrote something similar that works. What I think you could do for your implementation, is resolve the issue by using a solution like this:
var isIE = window.navigator.userAgent.match(/MSIE (9|10)/);
var SomeAudioWrapper = function(name) {
var src = this.determineSrcFromName(name);
this.internal_player = new Audio();
// If the browser is IE9 or IE10, remove the src when the
// audio is paused or done playing. Otherwise, set the src
// at the start.
if (isIE) {
this.internal_player.onended = function() {
this.src = '';
};
this.internal_player.onpause = this.internal_player.onended;
} else {
this.internal_player.src = src;
}
this.play = function() {
if (someOtherConditionsAreMet()) {
// If the browser is IE, set the src before playing.
if (isIE) {
this.internal_player.src = src;
}
this.internal_player.play();
}
}
}

Web audio: Can't get ScriptProcessor node to work in Chrome

In web audio, I can't get the ScriptProcessor node to work in Chrome, although it works fine in Firefox.
// Create audio context (Chrome/Firefox)
var context;
if (window.AudioContext) {
context = new AudioContext();
} else {
context = new webkitAudioContext();
}
// Create oscillator and start it
oscillator = context.createOscillator();
oscillator.start(0);
// Set up a script node that sets output to white noise
var myscriptnode = context.createScriptProcessor(4096, 1, 1);
myscriptnode.onaudioprocess = function(event) {
console.log('Processing buffer');
var output = event.outputBuffer.getChannelData(0);
for (i = 0; i < output.length; i++) {
output[i] = Math.random() / 10;
}
};
// Connect oscillator to script node and script node to destination
// (should output white noise)
oscillator.connect(myscriptnode);
myscriptnode.connect(context.destination);
// NOTE: This commented-out code connects oscillator directly to
// destination, which works in Chrome as well as Firefox.
//oscillator.connect(context.destination);
Expected result of this sample is that it should play white noise at 1/10 volume (the oscillator is actually ignored).
You can try this code at http://jsfiddle.net/78yKV/3/ - be aware that on Firefox this URL will play white noise straight away! On Chrome 30, it doesn't give any errors, but also doesn't give any audio output. I also checked in Chrome 31 beta but saw the same results. The 'Processing buffer' log entry never appears.
To test the general audio system, if you uncomment the last line and connect the oscillator directly to the destination, it does play audio (the oscillator tone) correctly on Chrome. But I can't get the ScriptProcessor to work on Chrome.
I searched the net for tutorials etc. with ScriptProcessor but those I found either didn't come with runnable examples or didn't work (or were too complex).
(Just to make clear - this is a stripped-down sample and doesn't relate in any way to what I'm actually trying to do, so please don't tell me that I shouldn't use a ScriptProcessor to generate white noise. That's not what it's for; I do absolutely need ScriptProcessor to work for my real usage.)
I think most likely I am doing something very stupid like I have the wrong event name or something like that, but I can't find it. Can anyone help?
I now managed to check on several other machines and I think the problem is specific to the default audio device on my machine, which is a telephone handset using the Microsoft default USB audio driver. I've reported this to Google using the menu option in Chrome; my speculation is that the problem occurs because the handset only supports mono 16 kHz output, and somehow this causes Chrome to get confused.
I can reproduce the bug on a colleague's machine which has the same make of handset. To reiterate:
Firefox works correctly on both machines when using the handset.
Both machines work correctly in Chrome when you select a different output device.
The oscillator playback works correctly in Chrome even when using the telephone handset.
Final version of test code http://jsfiddle.net/78yKV/7/
function doStuff(osc) {
// Create audio context (Chrome/Firefox)
var context;
if (window.AudioContext) {
context = new AudioContext();
} else {
context = new webkitAudioContext();
}
// Set up a script node that sets output to white noise
var myscriptnode;
if (context.createScriptProcessor) {
myscriptnode = context.createScriptProcessor(4096, 1, 1);
} else {
myscriptnode = context.createJavaScriptNode(4096, 1, 1);
}
var buffer = 1;
myscriptnode.onaudioprocess = function(event) {
console.log('Processing buffer ' + (buffer++));
var output = event.outputBuffer.getChannelData(0);
for (i = 0; i < output.length; i++) {
output[i] = Math.random() / 10;
}
};
// Connect script node to destination
if (osc) {
oscillator = context.createOscillator();
oscillator.start(0);
oscillator.connect(context.destination);
} else {
myscriptnode.connect(context.destination);
}
}
The white noise playback from this script (well actually a slightly earlier test version but I think it's the same) works in Chrome 30 on Windows 7, Windows 8.1, Linux, and Android 4.1; on Firefox on Windows; on an iPad (latest OS); and on a Mac using Safari 6.0.5 as well (it breaks if you open the developer tools there, but as long as you don't, it works). It only fails when using the USB telephone handset (Polycom CX300) mentioned.
So in other words, as apsillers suggested, this still looks like a Chrome bug, but a rather specific one. (By the way I also tried the latest 'Canary' version of Chrome but it didn't help.)

jPlayer ends tracks 2-8% (a few seconds) too early?

I'm not sure what this could be... it's kind of hard to debug.
Basically when using jPlayer, each track ends a few seconds too early (mp3 format only).
I'm using S3/Cloudfront CDN for distribution, but I don't think that has anything to do with it (unless there is some weird header issue that could create symptoms like this). Ive tried it on about 5 different mp3's so far, all to the same effect.
Also, the .progress-bar doesn't get to 100% either, it ends at about 95% and then goes to the next playlist item.
var fnmApp = (function() {
var player = function() {
var options = {
swfPath : '<%= asset_path 'Jplayer.swf' %>'
, supplied : 'mp3'
, solution : 'html,flash'
, wmode : 'transparent'
, smoothPlayBar : false
};
var fnmPlaylist = new jPlayerPlaylist({
jPlayer: '#fnmp'
, cssSelectorAncestor: '#fnmp-container'
}, mixtapePlaylist, options);
$('.fnmp-container .jp-gui a').click(function(e) {
e.preventDefault();
});
};
return {
player: player
};
})();
Streaming MP3 files over HTTP is a bit problematic because it isn't typically possible to know how big that file is (in time or samples) until it is completely downloaded, and frames counted. Most players get around this by estimating time and then either updating that estimate as playback continues or simply rolling past the end of the file, should there still be data to play even after the original estimated length.
It sounds like what is happening is that the original estimated length is being used for the playback length. This is likely a bug with whatever is playing back audio, or the codec it is using. With jPlayer, you could be using either Flash or the browser via HTML5 for playback. Since forcing Flash over HTML5 is working in your case, I believe this is a bug in the build of Chrome that you are using. Unfortunately, there is no direct way to fix this problem, since it is out of your control. You can only work around it.

Categories