I have video and text that I am displaying when user clicks play button (4 seconds). So my code looks like this:
$('video').on('play', function (e) {
$('#showText').delay(4000).show(0);
});
What I am trying to achieve is hide this text (#showText) 5 seconds before the end of the video. I didn’t find any solution for this, so if anybody can help with this I’ll be more than thankful.
To make this work you can use the standard events associated with media elements. Specifically play and timeupdate. The former you've already covered. The latter fires as the playback progresses. You can use it to check the current position and determine if it's less than 5 seconds from the end, like this:
var $showText = $('#showText');
$('video').on({
play: function() {
$showText.delay(4000).show(0);
},
timeupdate: function(e) {
if ((this.duration - this.currentTime) < 5 && $showText.is(':visible'))
$showText.hide();
}
});
#showText {
display: none;
}
video {
height: 175px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p id="showText">Lorem ipsum</p>
<video autobuffer controls autoplay>
<source id="mp4" src="http://grochtdreis.de/fuer-jsfiddle/video/sintel_trailer-480.mp4" type="video/mp4">
</video>
You can use video.js to get length of video then you can hide any element at any second before video is ending
var myPlayer = videojs('example_video_1'); //defining videojs
<video id="example_video_1" data-setup="{}" controls="">
<source src="my-source.mp4" type="video/mp4">
</video> //end defining videojs
$('#showText').delay(4000).show(0);
var lengthOfVideo = myPlayer.duration(); // length Of Video in seconds
$(#showText).oneTime(lengthOfVideo-5, function() { // 5 second before video ends
$("showText").hide();
});
Related
Is there any way we can make a HTML5 video to completely stop a video on mouseout?
By stop I mean resetting the video state, just as refreshing the page. All I could get is having the video on pause on mouseout, but this is not what I want.
Thank you.
jsbin:
https://jsbin.com/fenixinuku/edit?html,css,js,output
HTML:
<video class="myvideo" src="http://vjs.zencdn.net/v/oceans.mp4" width="auto" height="auto" alt=""></video>
JS:
$(document).ready(function() {
$(".myvideo").on("mouseover", function(event) {
$(this).get(0).play();
}).on('mouseout', function(event) {
$(this).get(0).pause();
});
})
EDIT:
Thank you guys, based on your answers I made an alternative to this by displaying the video poster as the first frame ( Thank you Terence Eden for suggestion).
The only small issue is that the image poster is flickering on mouseout..Any better solution ?
HTML:
<video class="myvideo" src="http://vjs.zencdn.net/v/oceans.mp4" width="auto" height="auto" alt="" poster="https://www.w3schools.com/images/w3html5.gif"></video>
JS:
$(document).ready(function() {
$(".myvideo").on("mouseover", function(event) {
$(this).get(0).play();
}).on('mouseout', function(event) {
this.load();
});
})
demo 2 jsbin: https://jsbin.com/kivisutici/1/edit?html,css,js,output
Removing the video src property and adding it again should work. Try this inside the mouseout event:
var video = $(this).get(0);
var source = video.src;
video.src = "";
video.src = source;
You can do two things.
First, set the current time to 0.
$(this).get(0).currentTime = 0;
That returns the player position to 0 mins, 0 seconds - as though you had refreshed the page.
Secondly, you can set the poster for the video. By default this is the first frame of the video - but you can set it to any external JPG that you want.
You need to change you mouseout to this
.on('mouseout', function(event) {
$(this).get(0).currentTime = 0
$(this).get(0).pause();
});
Demo
Please try the following and let me know if it worked for you.
// Link here: https://www.w3schools.com/tags/av_prop_currenttime.asp
$(".myvideo"). mouseout(function() {
$(this).get(0).currentTime = 0;
});
or
$(".myvideo"). mouseout(function() {
$(this).currentTime = 0;
});
This is the sample code for stop video, using pause function on mouse-out in HTML5.
<script>
function testover(e)
{
//e.src="movie.mp4";
e.play();
}
function testout(ee)
{
ee.pause();
ee.currentTime =0;
//ee.src=null;
}
</script>
<video width="320" height="240" onmouseover="testover(this)" onmouseout="testout(this)" controls>
<source src="movie.mp4" type="video/mp4">
<source src="movie.ogg" type="video/ogg">
Your browser does not support the video tag.
</video>
Please neglect if it is not useful.
Problem and question
In a reveal.js presentation, I want to include a long video file. I want to have the playblack stop at certain positions, so that I have time to explain to the audience what they’re seeing. Then, I want to have the playback continue when I click. How can I do this?
Unsuccessful attempts so far
My attempts are as follows. I split the video file into parts 1.webm, 2.webm, 3.webm and so on, such that each part ends where I want to have a break. My idea then is to
Override the keydown event of Reveal.js so that it doesn’t go to the next slide, but instead executes my Javascript. How can I do something like this?
<div class="slides">
<section class="video-stepper">
<video>
<source data-src="1.webm" type="video/webm" />
</video>
</section>
</div>
<script>
$(function() {
// How can I do this?
Reveal.addEventListener('click', function(event) {
if ($(event.currentSlide).hasClass('video-stepper')) {
event.preventDefault();
// change 'src' of the video element and start the playback.
}
});
});
</script>
Use fragments and autoplay the video when it is shown:
<div class="slides">
<section class="video-stepper">
<video class="fragment current-visible video-step">
<source data-src="1.webm" type="video/webm" />
</video>
<video class="fragment current-visible video-step">
<source data-src="2.webm" type="video/webm" />
</video>
<video class="fragment current-visible video-step">
<source data-src="3.webm" type="video/webm" />
</video>
</section>
</div>
<script>
$(function() {
Reveal.addEventListener('fragmentshown', function(event) {
if ($(event.fragment).hasClass('video-step')) {
event.fragment.play();
}
});
});
</script>
And some CSS taken from the question Hide reveal.js fragments after their appearance, so that the fragments stack on top of each other:
.fragment.current-visible.visible:not(.current-fragment) {
display: none;
height:0px;
line-height: 0px;
font-size: 0px;
}
However, this comes with some fading in and out, which looks bad. How can I avoid the fading?
When entering the video slide, you can basically disable reveal.js by calling Reveal.disableEventListeners(), then bind your own logic to the keydown event until you’ve stepped through all videos, before enabling reveal.js again with Reveal.addEventListeners().
Some additional effort is required to avoid flickering when transitioning to the next video. You can add a new <video> element with the new video, place it on top of the current <video> with the help of CSS z-index, play the new video, then remove the old.
HTML
<section class="video-stepper">
<!-- Unlike the other <video> element, this one is not absolutely
positioned. We hide it with CSS, but use it to reserve space
on the slide and compute the optimal width and height. -->
<video class="placeholder stretch">
<source src="1.webm">
</video>
<video class="video-step" data-sources='["1.webm","2.webm","3.webm"]'></video>
</section>
CSS
.video-stepper {
position: relative;
}
video.video-step {
position: absolute;
top: 0;
left: 0;
}
video.video-step.front {
z-index: 10;
}
video.placeholder {
visibility: hidden;
}
Javascript
This is a bit lengthy, but works as desired.
Reveal.addEventListener('slidechanged', function(event) {
if ($(event.currentSlide).hasClass('video-stepper')) {
// When we enter a slide with a step-by-step video, we stop reveal.js
// from doing anything. Below, we define our own keystroke handler.
Reveal.removeEventListeners();
// Set the width and height of the video so that it fills the slide.
var stretcher = $(event.currentSlide).find('video.placeholder').get(0);
var video = $(event.currentSlide).find('video.video-step').get(0);
video.setAttribute('width', stretcher.getAttribute('width'));
video.setAttribute('height', stretcher.getAttribute('height'));
// Convert the data-sources attribute to an array of strings. We will
// iterate through the array with current_video_index.
var sources = JSON.parse(video.getAttribute('data-sources'));
var current_video_index = 0;
// Add a <source> element to the video and set the 'src' to
// the first video.
var source = document.createElement('source');
source.setAttribute('src', sources[0]);
video.appendChild(source);
document.addEventListener('keydown', function step_through_videos(event) {
if (event.which == 39) {
// right arrow key: show next video
// For the next video, create a new <video> element
// and place it on top of the old <video> element.
// Then load and play the new. This avoids flickering.
var new_video = $(video).clone().get(0);
var new_video_source = $(new_video).children('source').get(0);
new_video_source.src = sources[current_video_index];
new_video.load();
$(new_video).addClass('front video-step');
$(new_video).insertAfter(video);
new_video.play();
// Wait a little before removing the old video.
new Promise((resolve) => setTimeout(resolve, 500)).then(function() {
video.remove();
video = new_video;
$(video).removeClass('front');
});
current_video_index = current_video_index + 1;
event.preventDefault();
} else if (event.which == 37) {
// left arrow key: return the counter to previous video
current_video_index = current_video_index - 1;
event.preventDefault();
}
if (0 > current_video_index || current_video_index >= sources.length) {
// Reinstall reveal.js handlers.
document.removeEventListener('keydown', step_through_videos, true);
Reveal.addEventListeners();
console.log('Added reveal.js event listeners.');
}
}, true);
}
});
The following code is intended to play a series of short audio files in a sequence, as held in a javascript array named audio_sequence.
an .addEventListener('ended',function()) is used to trigger playback of each audio clip in the sequence.
This works as expected for the first 5 items in the array, playing each in turn, but then the audio elements start to play simultaneously and the sequence becomes jumbled.
I have tried several different approaches all yielding similar results.
Would very much appreciate any insights.
And example of the code running can be found here:
Play Sequence
Here's the javascript:
<script type="text/javascript">
var game_sounds = ["rooms", "bars", "food", "inveraray", "arse"];
var game_sequence = [0,1,2,3,4,0,1,2,3,4,0,1,2,3,4];
var sequence_position = 0;
function play_next(){
if (sequence_position < game_sequence.length){
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
audioElement.addEventListener('ended', function(){
sequence_position++;
play_next();
}, true);
audioElement.play();
}
}
function playSequence(){
sequence_position = 0;
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
// alert(game_sounds[game_sequence[sequence_position]]);
audioElement.addEventListener('ended', function(){
sequence_position++;
play_next();
},true);
audioElement.play();
}
</script>
& the html is as follows:
<a onClick="javascript:playSequence();" href="#"><h2>Play Sequence</h2></a>
<audio hidden id="rooms" preload="auto">
<source src="/audio/rooms.mp3">
</audio>
<audio hidden id="food" preload="auto">
<source src="/audio/food.mp3" >
</audio>
<audio hidden id="bars" preload="auto">
<source src="/audio/bars.mp3">
</audio>
<audio hidden id="inveraray" preload="auto">
<source src="/audio/inveraray.mp3">
</audio>
<audio hidden id="arse" preload="auto">
<source src="/audio/arse.mp3">
</audio>
What is causing the problem is that you are attaching the same event listener several times to each element, as they are in a loop. In a non particularly elegant but effective workaround, you could remove the listener before attaching it again:
var game_sounds = ["rooms", "bars", "food", "inveraray", "arse"];
var game_sequence = [0,1,2,3,4,0,1,2,3,4,0,1,2,3,4];
var sequence_position = 0;
function play_next(){
if (sequence_position < game_sequence.length){
playSequence();
}
}
function playSequence(){
var audioElement = document.getElementById(game_sounds[game_sequence[sequence_position]]);
// alert(game_sounds[game_sequence[sequence_position]]);
audioElement.removeEventListener('ended', prepareNextAudio);
audioElement.addEventListener('ended', prepareNextAudio, true);
audioElement.play();
}
function prepareNextAudio() {
sequence_position++;
play_next();
}
This code works and stops the playlist when each audio has been played for three times, which I guess is what you needed.
I have a page with two videos where the both videos are playing together. What I am doing is I am playing one video and I am playing another video without pausing previous one. Now, what I want is, the previous video should be paused when we are start playing another video. Please help in this regards. This should be taggle...
HTML
<video class="video" autobuffer controls>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4" />
</video>
<video class="video" autobuffer controls>
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv" type="video/ogg" />
</video>
jQuery
$('.video').on('play', function () {
$('.video').not($(this).get(0)).each(function () {
$(this).get(0).pause(); //Stops all videos except the current
});
});
DEMO jQuery
without jQuery
//add Event listener for all videos
var videos = document.getElementsByClassName('video');
for(var i = 0; i < videos.length; i++){
videos[i].addEventListener('playing', function(){ //on "play"...
controlVideos(this); //..call controlVideos
});
};
function controlVideos(current){
for(var i = 0; i < videos.length; i++){
if( videos[i] != current) videos[i].pause(); //stop video if it's not the current
}
}
DEMO without jQuery
I'm having trouble getting HTML5 audio to loop on my website: http://oclock.webs.com.
(It's an alarm which, when the alarm goes off, is supposed to loop a 1 second alarm sound over and over until you click OK on the alert box).
Simply including "loop" in the audio tag wasn't doing anything.
I found a helpful post on StackOverflow which lead me to this website: http://forestmist.org/2010/04/html5-audio-loops/
I knew Method 1 and 2 wouldn't work for me since they don't work on Firefox and are iffy on Chrome, and so Method 3 should have worked, unfortunately it didn't. Method 3 works when I'm on that website's page, but not when the code is included in my own page so I think there may be some conflicting code.
Relevant part of my webpage:
<audio id="audio1" preload>
<source src="media/alarm.ogg" type="audio/ogg" />
<source src="media/alarm.mp3" type="audio/mpeg" />
</audio>
<audio id="audio2" preload>
<source src="media/alarm.ogg" type="audio/ogg" />
<source src="media/alarm.mp3" type="audio/mpeg" />
</audio>
Relevant Javascript of the page:
if(timer==true && hours==hv && mins==mv && secs==sv){
document.getElementById("audio1").play();
alert("o'clock: Alarm ringing!");
document.getElementById("alarm").value="Set Alarm";
document.getElementById('audio1').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio2').play();
}, false);
document.getElementById('audio2').addEventListener('ended', function(){
this.currentTime = 0;
this.pause();
document.getElementById('audio1').play();
}, false);
}
else{
document.getElementById("audio1").pause();
document.getElementById("audio2").pause();
document.getElementById("audio1").currentTime = 0;
document.getElementById("audio2").currentTime = 0;
}
Intention: Upon the computer's time matching that of the selected time on the page, the audio alarm will repeat (loop) until the user clicks OK on the alert box popup.
Problem: Currently it only plays through the audio once, it doesn't loop. Where did I mess up?
"ended event" or "loop" property dose not work on some browsers.
So I used window.setInterval() for looping audio playing.
For this method, you should know play time of Audio file in advanced.
function playAudioWithLoop (/**HTMLAudioElement*/audio, /**Number*/length)
{
function onEnd (){
audio.play();
}
/* length is msec */
if(length > 0) {
audio.__timer = window.setInterval(onEnd, length);
}
}
function stopAudioWithLoop (/**HTMLAudioElement*/audio)
{
if(audio.__timer) {
audio.__timer = window.clearInterval(audio.__timer);
}
}
======================================================================
***playAudioWithLoop(document.getElementById("audio1"), 12*1000);***
***stopAudioWithLoop(document.getElementById("audio1"));***