I'm just trying to work on my javascript skills and I am trying to make a page that will load up an HTML5 video at random from an array.
Once the video is loaded I am trying to set it so once the video is clicked it will trigger the function to randomize a new video from the array and output the result into the HTML video code.
So every time the user clicks a video will be randomized and begin playing on the page.
I believe I am pretty close with the code I have written so far, but I can't seem to get it to randomize after it clicked on every click.
Here is my code
HTML
<a href="#" class="click">
<section>
<div>
<video loop autoplay>
<source src="videos/1.mpg" type="video/ogg">
<source src="videos/1.webm" type="video/mp4">
Your browser does not support the <code>video</code> element.
</video>
</div>
</section>
</a>
JavaScript
// Loads in Notifier
$(document).ready(function(){
swal({ title: "Tap or Swipe to randomize",
confirmButtonColor: "#FF1D23",
confirmButtonText: "Cool!",
imageUrl: "images/thumbs-up.jpg",
timer: 4000
});
});
//Array of Videos
var videos = [
[{type:'mp4', 'src':'videos/1.mp4'}, {type:'webm', 'src':'videos/1.webm'}],
[{type:'mp4', 'src':'videos/2.mp4'}, {type:'webm', 'src':'videos/2.webm'}],
];
//onClick + Action
$(function() {
$('a.click').click(function(e) {
e.preventDefault();
var randomIndex = parseInt(Math.random()*videos.length);
$(this).find('videos').append('<source src="'+videos[randomIndex]+'" />');
});
});
function getRandomVideo() {
var number = Math.floor(Math.random()*video.length);
document.write('<source src="'+videos[number]+'" />');
}
$(function() {
$('a.click').click(function(e) {
e.preventDefault();
console.log("hello world");
var number = Math.floor(Math.random()*videos.length);
$(this).html('<source src="'+videos[number]+'" />');
});
});
See this fiddle
//onClick + Action
$('a.click').click(function(e) {
e.preventDefault();
var randomIndex = parseInt(Math.random()*videos.length);
$(e.currentTarget).find('video').html('<source src="'+videos[randomIndex][0].src+'" type="video/ogg" /><source src="'+videos[randomIndex][1].src+'" type="video/mp4" />');
});
I left your data structure alone, although it could be structured better.
Couple of issues. First, you aren't creating your HTML string correctly. You have to use videos[randomIndex][0].src (notice the src). Secondly, you are .append() when you should be .html(). And lastly, you .find('videos') instead of .find('video'). The tag is a video (no S).
EDIT:
Also, you can't do $(this).find(...) in that context. this refers to the click event, not the a tag. You need to get the TARGET of the event $(e.currentTarget).find('video'), not the event.
videos[number][0].src for .mp4 format
and
videos[number][1].src for .webm format
and make sure to correct object declaration:
{type:'mp4', 'src':'videos/2.mp4'}
should be {type:'mp4', src:'videos/2.mp4'}
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.
The question of how can JavaScript call the next video has been asked as I have thoroughly researched this topic before posting. However, in the situation that I will describe, a video is running after an onclick event calls the function: function(e) and I need to be able to call the next video by calling the function(e) again once the code detects an ended event by using the addEventListener method.
I have posted all my code below. In addition I have added comments to illustrate what I “think” is happening. I am brand new to JavaScript and have recently retired, so I have had time to research the Internet to try and piece together what is taking place. Please feel free to clarify my commented code as I would appreciate being set straight on what I have wriiten.
I have also made an attempt to put the code on jsfiddle
https://jsfiddle.net/dan2004/tuouh36d/
but it only seems to function in Chrome.
My main question to everyone is in regard to the statement:
document.getElementById('videoPlayer').addEventListener('ended',handler,false);
If I call a function outside of the function, I can issue a message via an alert, but if I call the function that I am in (handler(e)) I cannot get the next video to run. Somehow I need to be able to call the handler(e) function and send it the next onclick event.
Thanks for any help.
var video_playlist, links, i, videotarget, filename, video, source;
// Gets the video object from <div id="player"> in the HTML
video_playlist = document.getElementById("player");
// "links" is an array which contains all the <a href> tags in the <div id="playlist">.
// This div is located within <div id="player"> and contains a clickable playlist.
links = video_playlist.getElementsByTagName('a');
// This "for loop" scrolls through the links array of <a href> attributes and
// assigns an "onclick = handler" event to each one.
for (i=0; i<links.length; i++) {
links[i].onclick = handler;
};
// e is an [object MouseEvent]
function handler(e) {
// The handler function receives the full path to the mp4 file when it is clicked on in the playlist.
// The "preventDefault" method stops the function from following that path.
// This is so the data in the path may be parsed and manipulated below
e.preventDefault();
// videotarget grabs the href attribute of the item clicked on
// in the "playlist". This is the full path to the video file.
videotarget = this.getAttribute("href");
// Through the use of substr, filename grabs that part of the href which
// does not include the extension.
filename = videotarget.substr(0, videotarget.lastIndexOf('.')) || videotarget;
// The variable "video" contains the video object. This is obtained by using document.querySelector().
// This document method uses the css id class, #player, and grabs the [object HTML VideoElement].
// The [object HTML VideoElement] resides in <div id="player">
video = document.querySelector("#player video");
//Removes the poster attribute in the video tag
video.removeAttribute("poster");
// The source variable is used to hold an array of all the source tags in the
// [object HTML VideoElement] from <div id="player">.
source = document.querySelectorAll("#player video source");
// Using the substring extracted from the user's click choice in <div id="playlist">
// the three file types for browsers to choose from are concatenated to the string.
// These thre source files are then stored under the video object located in <div id="player">.
source[0].src = filename + ".mp4";
source[1].src = filename + ".webm";
source[2].src = filename + ".ogv";
// The video object will load the appropriate source[].src file then play it
video.load();
video.play();
// When the video ends the following statement will call the function test()
// which will then broadcast the alert message "Video Ended"
document.getElementById('videoPlayer').addEventListener('ended',test,false);
// This statement will not call the handler function in order to play the next video selection.
// document.getElementById('videoPlayer').addEventListener('ended',handler,false);
}; // function handler(e)
function test(){
alert("Video Ended");
};
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Video Playlist Tutorial</title>
<style>
body {font-family:Arial, Helvetica, sans-serif;background:#fff}
.center {text-align:center;width:640px;margin:0 auto;}
#player {background:#000; padding:10px;width:640px;margin:0 auto;border-radius:10px;}
#player video {width:640px;}
#playlist {background:#333;list-style:none;padding:0;margin:0; width:640px;}
#playlist h1 {font: 24px Arial, Helvetica, sans-serif; color:#FFF; font-weight:bold;padding:5px 2px;margin:0;}
#playlist a {color:#eeeedd;background:#333;padding:10px 5px;display:block;text-decoration:none;border-bottom:1px solid #222;}
#playlist a:hover {text-decoration:none; background:#999;color:#000}
</style>
</head>
<body>
<div id="player"> <!-- Assign id to video tag for ended event and to call handler to play next video -->
<video id="videoPlayer" controls="controls" width="640" height="360" preload="auto" autoplay >
<source src="1.mp4" type="video/mp4" />
<source src="1.webm" type="video/webm" />
<source src="1.ogv" type="video/ogg" />
</video>
<div id="playlist">
<h1>Videos</h1>
Bear <br>
Buck Bunny
</div>
</div>
<script>
</script>
</body>
</html>
Seeing as your handler() function relies on this being the clicked element, you can't just call that function, you'd have to also set the this-value to the next anchor etc. and trigger the event in a way that makes it look like it was triggered by the actual element.
An easier way to do this, would be to just decouple the playing logic, get the next element, and play the video
var video_playlist = document.getElementById("player");
var links = video_playlist.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
(function(j) {
links[j].addEventListener('click', function(e) {
handler.apply(this, [e, j])
});
})(i);
};
function handler(e, index) {
e.preventDefault();
var videotarget = this.getAttribute("href");
play(videotarget, index).addEventListener('ended', function() {
index = (++index) >= links.length ? 0 : index;
play(links[index].getAttribute("href"), index);
});
};
function play(videotarget) {
var filename = videotarget.substr(0, videotarget.lastIndexOf('.')) || videotarget;
var video = document.querySelector("#player video");
var source = document.querySelectorAll("#player video source");
video.removeAttribute("poster");
source[0].src = filename + ".mp4";
source[1].src = filename + ".webm";
source[2].src = filename + ".ogv";
video.load();
video.play();
return video;
};
<div id="player">
<!-- Assign id to video tag for ended event and to call handler to play next video -->
<video id="videoPlayer" controls="controls" width="640" height="360" preload="auto" autoplay>
<source src="1.mp4" type="video/mp4" />
<source src="1.webm" type="video/webm" />
<source src="1.ogv" type="video/ogg" />
</video>
<div id="playlist">
<h1>Videos</h1>
Bear
Buck Bunny
</div>
</div>
I am trying to use a intro sound for the mp3 files. After playing the intro the original track should start to play. i mean the original mp3 plays right after the intro ends. Here i have this:
<script type="text/javascript" src="js/jquery.min.js"></script>
<audio id='top' onended="playOrg();" preload='none' src='http://www.sounddogs.com/previews/59/mp3/607322_SOUNDDOGS__th.mp3' type='audio/mpeg'> </audio>
<a href='#' class='btn' id='audioControl'> START </a>
And here the javascript part:
<script type="text/javascript">
var yourAudio = document.getElementById('top');
var ctrl = document.getElementById('audioControl');
ctrl.onclick = function () {
var pause = ctrl.innerHTML === 'STOP';
$('.btn').html('START');
$('audio').trigger('pause');
ctrl.innerHTML = pause ? 'START' : 'STOP';
var method = pause ? 'pause' : 'play';
yourAudio [method]();
return false; };
function playOrg(){
yourAudio.setAttribute('onended','orgPlayed()');
yourAudio.src='http://www.sounddogs.com/sound-effects/59/mp3/606540_SOUNDDOGS__sf.mp3';
yourAudio.play();
console.log('playOrg()');
}
function orgPlayed(){
yourAudio.setAttribute('onended','playOrg()');
yourAudio.src='http://www.sounddogs.com/previews/59/mp3/607322_SOUNDDOGS__th.mp3';
yourAudio.pause();
yourAudio.currentTime = 0;
console.log('orgPlayed()');
}
</script>
When i press start the file plays and on the end it calls the playOrg() function witch should change some attributes and should play the original track. Then the second file should play and on its end this time the orgPlayed() function should be called and set back the attributes so that it is ready for the other play.
So i want to use intro track for all my track on the site. But i can't accomplish that. i appreciate any upcoming help.
PS: Actually there is a loop for all tracks in my original code but i summarised it here. Please don't ask why i couldn't find better mp3 test files :).
I found the my problem. Instead of reloading the new track with "currentTime=0" i tried to reload with "load()" , and now it works. I guess sometime we need to sleep over such problems :). Thanks to everyone ;).
<audio id='top' onended="playOrg();" preload='none' src='top10/intro/1.mp3' type='audio/mpeg'> </audio>
<a href='#' class='btn' id='audioControl'>START</a>
<script type="text/javascript">
var yourAudio = document.getElementById('top');
var ctrl = document.getElementById('audioControl');
ctrl.onclick = function () {
if (ctrl.innerHTML=='START') {
ctrl.innerHTML='STOP';
yourAudio.play();
}else if (ctrl.innerHTML=='STOP'){
ctrl.innerHTML='START';
yourAudio.pause();
}
}
function playOrg(){
var myPlayer= document.getElementById('top');
myPlayer.setAttribute('onended','orgPlayed()');
myPlayer.src='top10/tarkan.mp3';
myPlayer.pause();
myPlayer.load();
myPlayer.play();
}
function orgPlayed(){
var myPlayer= document.getElementById('top');
myPlayer.setAttribute('onended','playOrg()');
myPlayer.src='top10/intro/1.mp3';
myPlayer.pause();
myPlayer.load();
ctrl.innerHTML='START';
}
</script>
now i realised another way to solve this. i could use two audio tags with one intro source and the other the original source. and then after the first one ends i could play the second using either a function or directly onended="document.getElementById('top2').play();"
i mean something like this:
<audio id='top1' onended="play second(with a function or directly)" preload='none' src='intro' type='audio/mpeg'> </audio>
<audio id='top2' onended="make ready for another play (with a function or directly)" preload='none' src='original' type='audio/mpeg'> </audio>
<a href='#' class='btn' id='audioControl'>START</a>
I am building a player logic that loads a movie, plays it to the end, reacts to the "ended" event and sets a new source, that has to be looped until the user interacts. Then, film2 gets played and "switches into loop" as well so i'm loading another src and setting options to loop for the loop.
I just couldn't get it to work.
Here is my code:
<video id="video_1" preload="auto" width="100%" height="100%">
<source src="video/dummy/dummy_film1.mp4" type='video/mp4'>
</video>
And here is my js:
function initialVideoFinished(){
_myPlayer.off('ended', initialVideoFinished);
console.log('video1 finished - video js READY');
console.log('myPlayer id == ' + _myPlayer);
_V_('video_1', {'loop' : 'true'});
_myPlayer.src('video/dummy/dummy_loop1.mp4');
_myPlayer.play();
ni_resize();
}
I tried a lot of variations. Loop in "" or without or _myPlayer.loop = true; V(...) oder just videojs(..) but the new video src never loops.
I also tried replacing the whole tag. This works, but then I lose my reference to the player object.
How can I do this?
You can use loop(true):
var myPlayer = videojs("my_video_1");
function initialVideoFinished(event) {
console.log("end");
myPlayer.off('ended', initialVideoFinished);
myPlayer.src("http://example.com/newsource.mp4");
myPlayer.loop(true);
myPlayer.play();
}
myPlayer.on('ended', initialVideoFinished);
I'm using the following code to trigger fullscreen when a user clicks on the play button on a <video> element:
var video = $("#video");
video.on('play', function(e){
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.mozRequestFullScreen) {
video.mozRequestFullScreen();
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen();
}
});
But nothing happens when I click the play button.
Any idea's why?
EDIT: Here's my HTML code:
<video width="458" height="258" controls id='video' >
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.mp4' type="video/mp4">
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.ogv' type="video/ogg">
<source src='<?= bloginfo('template_directory'); ?>/inc/pilot.webm' type="video/webm">
</video>
There are a couple things going on here:
First, in your code, video is a jQuery object, not the actual video element. For a jQuery object, you can reference it like this:
var actualVideo = video[0]; // (assuming '#video' actually exists)
Second, for security and good user experience, browsers will only let you trigger full screen inside a user-triggered event, like a 'click'. You can't have every web page going to full screen as soon as you visit it, and you can cause a video to start playing automatically, which would violate that rule.
So an alternative solution would be to request fullscreen in a click event, like this:
var video = $("#video");
video.on('click', function(e){
var vid = video[0];
vid.play();
if (vid.requestFullscreen) {
vid.requestFullscreen();
} else if (vid.mozRequestFullScreen) {
vid.mozRequestFullScreen();
} else if (vid.webkitRequestFullscreen) {
vid.webkitRequestFullscreen();
}
});
Ideally, you'd probably want to build out a more complete player ui, but this should give you the general idea.
A less verbose way to toggle full screen combining answers from this and other questions.
This should handle all browser flavours: chromium- and webkit-based, firefox, opera, and MS-based browsers.
var p = document.querySelector('#videoplayer');
if (!window.isFs) {
window.isFs = true;
var fn_enter = p.requestFullscreen || p.webkitRequestFullscreen || p.mozRequestFullScreen || p.oRequestFullscreen || p.msRequestFullscreen;
fn_enter.call(p);
} else {
window.isFs = false;
var fn_exit = p.exitFullScreen || p.webkitExitFullScreen || p.mozExitFullScreen || p.oExitFullScreen || p.msExitFullScreen;
fn_exit.call(p);
}
p represents the DOM object of the video element, and window.isFs is just a random variable for storing the current fullscreen state.
If your player is a jQuery object then you can get the underlying DOM-element with var p = player.get(0).