JS/jQuery: Detect when a video's muted property is changed - javascript

I am trying to detect when a user mutes/unmutes or changes the volume of a html video so the next time a page with a video is loaded the previous audio settings can be applied. I have been able to set the video's mute state using $('video').prop('muted', sessionStorage.getItem('is-muted')); but I am unsure how to detect when the user changes the mute state so I can store it for the next time a page is loaded. For example:
// This never fires
$('video').on('change', function () {
sessionStorage.setItem('is-muted', $(this).prop('muted'));
});
How can I detect when the video mute/volume level is changed so I can persist it in storage?

You can use volumechange event and check prop.
const video = $('video');
video.on('volumechange', (e) => {
// check video.prop('muted');
});

There is a W3Schools.com page which gives an example of getting and setting audio and video volume with the DOM volume property.
in traditional JavaScript:
var vid = document.getElementById("myVideo");
vid.volume = 0.2;
To convert that to jQuery parlance in your case:
$('video').volume = 0.2;
If you have a look at the HTML 5.2 specification from W3C, specifically at the part about Effective Media Volume, it appears that a user can override media volume with their user-agent:
If the user has indicated that the user agent is to override the volume of the element, then the element’s effective media volume is the volume desired by the user. Abort these steps.
As well as many other possibly helpful HTML5 media properties.

Related

Is it possible to mute the whole webpage with javascript?

I have a webpage which has a continuous(ish) livestream playing on it, but I want users only to be able to see and hear it at specific, exact times. I don't want them to have to keep disconnecting and reconnecting as this takes an unpredictable amount of time.
When the user loads the page, the livestream will autostart (muted and hidden - see below) and the user will have to unmute the video (even though they can't see it yet), but I don't want them to actually hear the livestream until the allocated time. I don't want them to have to manually unmute the video at the allocated times - My goal is to have everyone connected and stable so that (for example) at 10:04:30 precisely everyone can see and hear the livestream for 30 seconds, then it disappears (and mutes) until the next time at (say) 10:07:15 and so on. The process should happen in a way that allows the user to sit back in their armchair and not have to use their mouse or keyboard after the inital page load and unmuting of the livestream.
Dealing with the video side is easy - I can just show/hide a div with a black background that covers the video, but I'm not sure how to deal with the audio side of things. Is it possible to mute/unmute the webpage as a whole? Are there other ways to achieve this goal?
Another possible perspective is to have this done at the source somehow, by having the publisher connect and start publishing, but send blank video/audio until the right time, then switch over what is being sent. Again this needs to be done without the publisher having to keep reconnecting or do anything manually.
The publisher and viewers are all connecting using WebRTC.
Assuming something like the following:
<video id="vid" ...></video>
<div id="controls" ...>
<button id="mute-btn">Mute</button>
</div>
Then you need something like this:
const vid = document.querySelector('#vid')
const muteBtn = document.querySelector('#mute-btn')
vid.muted = true
window.userHasUnmuted = false
window.liveStreamStarted = false
muteBtn.addEventListener('click', () => {
window.userHasUnmuted = true
if (window.liveStreamStarted) {
vid.muted = false
}
}
// then, in callback for whenever live-stream starts...
if (window.userHasUnmuted) {
vid.muted = false
}
Original answer below
To mute a single audio or video element:
audioOrVideoElement.muted = true
To mute all audio or video elements on a page:
document.querySelectorAll('audio, video').forEach(el => el.muted = true)
Conversely, setting muted to false re-enables sound from that element.
For finer-tuned audio controls, you can also set the element's volume (in the range 0..1), for example:
document.querySelectorAll('audio, video').forEach(el => el.volume = 0.3)

Link button with video time

I'm trying to show a button only when the user reaches at a certain time of video, like button would appear only when the user has seen 20 minutes of video. Have no idea about it, would really appreciate inputs. Thanks
Well IF the video is playing through html5 (a video tag) NOT EMBEDDED the following code is one route you could take.
// the video element
var video = document.getElementsByTagName('video')[0];
// add an event listener for 'timeupdate'
video.addEventListener('timeupdate', function() {
// 20 mins in seconds
if ( this.currentTime == 1200) {
// code to add the button here...
}
}, false);
You should really check out html5 audio/video api
Not sure if you want to know how to make a button appear or how to check the the current time of a video clip.
I'm hoping it's the former. To check the time of video playback you can call the currentTime property of your video using javascript, as such:
// set your video element to a variable
var video = document.getElementById("my-video");
// get the current playback time of the video (returned in seconds) and set to variable
current_playback_time = video.currentTime;

Background Audio in Windows 8 App

I'm trying to get audio to work outside the app (I'm using the HTML5, Javascript approach) in Windows 8, so when you close the app the sound continues to work, from what I have researched on here and on other sites and I believe this is called in Windows 8 'background audio, I've followed all the tutorials on Microsoft Developer site, and have declared background audio in the app manifest as so:
<Extension Category="windows.backgroundTasks" StartPage="default.html">
<BackgroundTasks>
<Task Type="audio" />
<Task Type="controlChannel" />
</BackgroundTasks>
</Extension>
and where I have added the msAudioCategory="BackgroundCapableMedia" controls="controls" to my HTML5 audio tag as so:
<audio id="playback" msAudioCategory="BackgroundCapableMedia" controls="controls">
</audio>
and I've also added this to my default.js file which was apprently needed, although I'm not sure what this does
// Declare a variable that you will use as an instance of an object
var mediaControls;
// Assign the button object to mediaControls
mediaControls = Windows.Media.MediaControl;
// Add an event listener for the Play, Pause Play/Pause toggle button
mediaControls.addEventListener("playpausetogglepressed", playpausetoggle, false);
mediaControls.addEventListener("playpressed", playbutton, false);
mediaControls.addEventListener("pausepressed", pausebutton, false);
// The event handler for the play/pause button
function playpausetoggle() {
if (mediaControls.isPlaying === true) {
document.getElementById("playback").pause();
} else {
document.getElementById("playback").play();
}
}
// The event handler for the pause button
function pausebutton() {
document.getElementById("playback").pause();
}
// The event handler for the play button
function playbutton() {
document.getElementById("playback").play();
}
I have also tried changing the ID in the last part to have a hash tag as well but still when I press the start button to go back home the audio stops, am I doing something wrong?
Thanks
I believe you also need to handle the "stoppressed" event:
mediaControls.addEventListener("stoppressed", stop, false);
function stop() {
// Handle the stop event.
document.getElementById("playback").pause();
document.getElementById("playback").currentTime = 0;
}
The three steps for playing background audio in Windows 8 JavaScript apps are:
Decalare an audio background task in package.appxmanifest. Also list a StartPage. You did this correctly.
Set msAudioCategory="BackgroundCapableMedia". You did this.
Implement support for media controls. Media controls are buttons on remote controls or on certain keyboards that play, pause, or stop audio. See the Configure keys for media sample on MSDN for a working example. I was able to get the example to work when only handling "stoppressed" in addition to the 3 events you were already handling.
For more information, watch Your Metro style app, video and audio, part 2 from the 2011 Build conference. Background audio is covered beginning at around 31 minutes, 20 seconds into the video and lasts for about 10 minutes. Note that this video is from September, 2011, and covers the Developer Preview of Windows 8. The concepts still apply to the released versions of Windows 8 and Windows RT, but namespaces and attribute names are different in some places.

Preventing media to replay

There is an onClick event for a link, and I am playing some audio using these lines there:
tts = new Media(url, onSuccessTTS, onErrorTTS);
tts.play();
However, if user clicks second time on the link before it finishes playing the first media, it plays the same file simultaneously again. Is there any way to prevent playing if the media is currently being played?
There is a callback event for mediaStatus, but it is not documented.
http://docs.phonegap.com/en/1.0.0/phonegap_media_media.md.html
With the phonegap media api, you are manually creating an audio player. Therefore you must manage the state of your player programatically.
Since there should be one control for your media player, I would keep the state on the HTML DOM element that has the play button
//on click
var $el = $(this); //or $('someselector');
//check if you have already added the playing state to the element
if ($el.data('state') == 'playing') {
//pause or ignore
} else {
$el.data('state', 'playing'); //save state on element
tts = new Media(url, onSuccessTTS, onErrorTTS);
tts.play();
} // handle stopped if needed
BTW phonegap is up to version 2.0, so consider using the 2.0 media api.

Auto-Full Screen for a Youtube embed

I have a Youtube video embeded on a webpage.
Is it possible to have the video go full screen when the user presses play, using the HTML5 iframe with Youtube's API?
Using the Chromeless player is not an option as the website is intended for iPads.
Update November 2013: this is possible - real fullscreen, not full window, with the following technique. As #chrisg says, the YouTube JS API does not have a 'fullscreen by default' option.
Create a custom play button
Use YouTube JS API to play video
Use HTML5 fullscreen API to make element fullscreen
Here's the code.
var $ = document.querySelector.bind(document);
// Once the user clicks a custom fullscreen button
$(playButtonClass).addEventListener('click', function(){
// Play video and go fullscreen
player.playVideo();
var playerElement = $(playerWrapperClass);
var requestFullScreen = playerElement.requestFullScreen || playerElement.mozRequestFullScreen || playerElement.webkitRequestFullScreen;
if (requestFullScreen) {
requestFullScreen.bind(playerElement)();
}
})
This isn't possible with the youtube embed code or the youtube javascript API as far as I know. You would have to write your own player to have this functionality.
Doing some reading it looks like you can use the chromeless youtube player and it will resize itself to the width and height of its parent element.
That means that if you use the chromeless player you can resize the div with javascript with the play event is triggered.
No, this isn't possible, due to security concerns.
The end user has to do something to initiate fullscreen.
If you were to run an Adobe AIR application, you can automate the fullscreen activation w/o having end user do anything. But then it would be a desktop application, not a webpage.
I thought I would post an easier updated method to solving this one using html5.
.ytfullscreen is the name of the button or whatever you want clicked.
#yrc-player-frame-0 is going to be the name of your iframe.
jQuery(".ytfullscreen").click(function () {
var e = document.getElementById("yrc-player-frame-0");
if (e.requestFullscreen) {
e.requestFullscreen();
} else if (e.webkitRequestFullscreen) {
e.webkitRequestFullscreen();
} else if (e.mozRequestFullScreen) {
e.mozRequestFullScreen();
} else if (e.msRequestFullscreen) {
e.msRequestFullscreen();
}
});

Categories