Display video duration from videoJS - javascript

I am working on an HTML5 video player with jQuery. For now I have my video player working very well but I want to get the variable for the video duration and show/display it in pure HTML page.
So from here you can take more info about this Jquery video player:
http://www.videojs.com/docs/api/
I think the variable for video duration is: myPlayer.duration();
How I can display this value in HTML?
Here is my HTML code to display the player:
<video id="vemvo-player" class="video-js vjs-default-skin" controls autoplay="true" width="950" height="534"
data-setup="{}">
<source src="[var.base_url]/uploads/[var.video_play]" type='video/flv' />
</video>
This is what I have tried to display this variable but it says that it is = "0" when on the video player it says that it's 4min:
<video id="vemvo-player" class="video-js vjs-default-skin" controls autoplay="true" width="950" height="534"
data-setup="{}">
<source src="[var.base_url]/uploads/[var.video_play]" type='video/flv' />
</video>
<div id="duration"></div>
<script type="text/javascript">
_V_("vemvo-player").ready(function(){
var myPlayer = this;
var howLongIsThis = myPlayer.duration();
$('#duration').html('Duration: ' + howLongIsThis);
});
</script>
Where is my mistake?

You can try this. It works for me.
var myPlayer = videojs('vemvo-player');
if (myPlayer.readyState() < 1) {
// wait for loadedmetdata event
myPlayer.one("loadedmetadata", onLoadedMetadata);
}
else {
// metadata already loaded
onLoadedMetadata();
}
function onLoadedMetadata() {
alert(myPlayer.duration());
$('#duration').html("Duration: " + myPlayer.duration());
}

var player = videojs('my-video', {
fluid:false, // videojs settings
controls:true,
height: '300'
});
$(document).ready(function(){
console.log(player.duration());
// will return video duration. Can't be used while page is loading.
console.log(player.currentTime());
// will return current time if video paused at some time. Intially it would be 0.
});

Those who might come here and are using videojs with Vue 3, also might work with similar frameworks like React.
Referring to this code and component usage - https://docs.videojs.com/tutorial-vue.html you can do the following changes to get the duration, height, and width.
// New Code here
this.player = videojs(
this.$refs.videoPlayer,
this.options,
function onPlayerReady() {
console.log("onPlayerReady", this);
}
);
this.player.one("loadedmetadata", () => {
var duration = this.player.duration();
console.log(`Duration of Video ${duration}`);
console.log(`Original Width of Video ${this.player.videoWidth()}`);
});

I was having troubles to get the real duration of videos (using videojs v7.18.*) resulting in bugged custom progressbar! The problem was that player.duration() always returns rounded number while player.liveTracker.seekableEnd() returns the real value but only after start event.
For example, if real duration is 13.456s, these values are returned for videojs player object p:
| On ready | On load | On start
----------------------------|-------------|---------|----------
p.duration() | 0 | 14 | 14
p.liveTracker.seekableEnd() | 14 | 14 | 13.456
I've ended up with this solution in React:
const onDurationChange = () => {
const dur = player?.liveTracker.seekableEnd() || player?.duration() || 0;
setDurationInSec(dur);
}
return <video ref={videoRef} onDurationChange={onDurationChange}>

As you're using jQuery, that can be done much easier :) You can use $.html to edit the html contents of a dom element. Your code will look something like this:
<div id="duration"></div>
<script type="text/javascript">
_V_("vemvo-player").ready(function(){
var myPlayer = this;
var howLongIsThis = myPlayer.duration();
$('#duration').html('Duration: ' + howLongIsThis);
});
</script>

Related

Randomize Background Video with Sound, after clicking function

I wrote this code a while back, and it allowed users to click and refresh the page to autoplay a RANDOM background video with sound.
This is the function that they click that loads the function
https://pastebin.com/0XXEHvQQ
<div align="center">
<p><font face="verdana" size="2">
<a onclick="ok()"> press me PLAY VIDS :)</a></font></p>
</div>
https://pastebin.com/PD5qdNDM
<div align="center">
<p><font face="verdana" size="2">
<a onclick="ok()"> -> press me to fix the site :) <-</a></font></p>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="js/parallax.js"></script>
<script>
// Pretty simple huh?
var scene = document.getElementById('scene');
var parallax = new Parallax(scene);
</script>
</script>
<script src="js/custom.js"></script>
<script>
let volumeInterval;
function loaded(){
setInterval(loop, 600);
volumeInterval = setInterval(volume, 1);
}
function unload(){
for (var i = 1; i < 99999; i++)
window.clearInterval(i);
console.log("unloaded");
}
function volume() {
try {
document.getElementsByTagName("video")[0].volume = 0.15;
console.log("done!");
clearInterval(volumeInterval);
}
catch (e) {
console.log("waiting..");
}
}
function ok() {
document.write(unescape(
and heres the unescaped code
https://pastebin.com/YJwbG2mC
<!-- VIDEO GRABBB -->
<video preload="auto" autoplay="true" loop="true">
<source id="player" src="5.mp4">
<script>
var video = document.currentScript.parentElement;
video.volume = 0.33;
//document.getElementById('player').currentTime = 20;
</script>
<script>
var video = document.getElementById("player");
video.addEventListener("timeupdate", function(){
if(this.currentTime >= 1000) {
location.reload();
}
});
</script>
<script type="text/javascript">
var video = document.getElementsByTagName('video')[0];
video.onended = function() {
location.reload();
};
</script>
<script>
document.getElementById("player").src = "/" + Math.floor((Math.random()*7)+1) + ".mp4";
</script>
</video>
No matter how I try to adjust the unescaped code, I can't get the MP4 to autoplay after clicking the function.
Here is my live site that I no longer can access: form.wtf
According to the HTML Spec on the Source Element,
Dynamically modifying a source element and its attribute when the element is already inserted in a video or audio element will have no effect. To change what is playing, just use the src attribute on the media element directly, possibly making use of the canPlayType() method to pick from amongst available resources. Generally, manipulating source elements manually after the document has been parsed is an unnecessarily complicated approach.
Therefore, no matter what you do to the source element, you can't change the video unless the new src is applied directly to the video element.
Replacing the source element also has no effect on the video that plays. The source element's src attribute may changed but the video will keep on playing.
Therefore, you should leave your source's src attribute empty until the JavaScript code sets it or
Leave out the source tag all together and apply the src straight to the video.
Math.floor(Math.random() * 7 + 1); is exactly the same thing as Math.ceil(Math.random() * 7);
document.querySelector('#player > source').src = `/${Math.ceil(Math.random() * 7)}.mp4`;
<video id="player" preload="auto" autoplay loop>
<source src="">
</video>

How do I make a random video play on pageload?

I'm trying to make a random video player in html/js.
It is supposed to play a different video on pageload and as soon as one video is over, it should play another one.
HTML
<video width="320" height="240" autoplay>
<source src="abcdefg.com/example1.mp4" type="video/mp4">
<source src="abcdefg.com/example2.mp4" type="video/mp4">
</video>
JS
<script>
var videos = [
[{type:'mp4', 'src':'abcdefg.com/example1.mp4'}],
[{type:'mp4', 'src':'abcdefg.com/example2.mp4'}],
];
$(function() {
var number = Math.floor(Math.random()*videos.length);
$(this).find('source').each(function(index){
videoSrc = videos[number][index].src;
$(this).attr('src', videoSrc);
$('video').load();
$('video').play();
});
});
</script>
However, my current code plays the same video every page reload and as soon as it's over, nothing happens.
How do I need to optimize my code so it automatically plays a different video on every pageload + when the previous video is over?
Try this,I have added an event listener to video end property and called the newvideo() function ,so that every time the video finishes a new random video is loaded from array.I could'nt find more video urls ,you can test and let me know if it works for you.
$(document).ready(function(){
var videos = [
[{type:'mp4', 'src':'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'}],
[{type:'mp4', 'src':'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'}],
[{type:'mp4', 'src':'http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4'}]
];
// selecting random item from array,you can make your own
var randomitem = videos[Math.floor(Math.random()*videos.length)];
// This function adds a new video source (dynamic) in the video html tag
function videoadd(element, src, type) {
var source = document.createElement('source');
source.src = src;
source.type = type;
element.appendChild(source);
}
// this function fires the video for particular video tag
function newvideo(src)
{
var vid = document.getElementById("myVideo");
videoadd(vid,src ,'video/ogg');
vid.autoplay = true;
vid.load();
//vid.play();
}
// function call
newvideo(randomitem[0].src)
// Added an event listener so that everytime the video finishes ,a new video is loaded from array
document.getElementById('myVideo').addEventListener('ended',handler,false);
function handler(e)
{
newvideo(randomitem[0].src)
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<video width="320" height="240" autoplay id="myVideo">
</video>

HTML5 Video If hash is equal to value set the audio to 1 else set the audio to 0 using Javascript Functions

Hello I am trying to set the HTML5's video audio level depending on the location hash for example if the hash is #home the video's audio should be 1.0 if the hash isn't #home then the audio level should be 0.0
I've had a play around and i can't seem to get it to work here is my code
and thank you for taking a look and for any help!
$(function() {
if (location.hash === "#home") {
videoAudio();
}
} else {
videoAudioMute();
});
function videoAudio() {
var vid = document.getElementById("myvideo");
vid.volume = 1.0;
}
function videoAudioMute() {
var vid = document.getElementById("myvideo");
vid.volume = 0.0;
}
html
<div class="background">
<video id="myvideo" poster="assets/img/slide1-background-img-pattern-01.jpg" controls="" autoplay="" loop="" >
<source src="assets/vid/Background.mp4" type="video/mp4">
<source src="assets/vid/Background.webm" type="video/webm">
<source src="assets/vid/Background.ogv" type="video/ogg">
</video>
</div>
You have a syntax error.
The correct version should be like:
$(function () {
if (location.hash === "#home") {
videoAudio();
} else {
videoAudioMute();
}
});
function videoAudio() {
var vid = document.getElementById("myvideo");
vid.volume = 1.0;
}
function videoAudioMute() {
var vid = document.getElementById("myvideo");
vid.volume = 0.0;
}
To give a proper answer to the question I think we need a little bit more information.
What you can do if you do not want to share more is console log location. This should give you an object with some properties in it. Hash is one of them. Check it and see if you are getting the data that you expect. If hash is not giving what you want you can try using some of the other properties as an identifier, like pathanme.
If the problem is not in the hash but it is in manipulating the audio level you can try jQuery. I have had a lot of headaches manipulating audio and video files with JavaScript but I have found that jQuery work the best.
Hope this helps.

HTML5 Video - How to do a seamless play and/or loop of several videos?

How can I reliably play several videos one after another seamlessly? As there is a small pause or flicker between playing 2 videos.
In my particular example I have 3 videos. I need to play all 3 of them seamlessly one after another, and I also need to loop middle video an arbitrary number of times (say 2 or 3). All of that needs to happen seamlessly and consistently across different browsers.
I've been trying everything under the moon, from starting video playback on video end, to using several video tags and hiding and replacing them, I even tried to implement this in Flash, but alas nothing works, and the same problem happens in current Flash as well.
I've seen this (or similar) question asked many times but I haven't seen a reliable solution yet.
Does anyone know a solution to this?
After trying various things I have finally been able to create what seems to be a working solution. I haven't tested this on older browsers or other OSes, but this works on latest versions of Chrome, IE, Firefox and Opera. (Although some more feedback of whether this works on other systems would be appreciated)
The idea is to have all 3 videos output frames to HTML5 canvas. The original videos are hidden and preloaded in advance to avoid pause between loading.
Here is the code:
var playCounter = 0;
var clipArray = [];
var $video1 = $("#video1");
var $video2 = $("#video2");
var $video3 = $("#video3");
$video1.attr("src", "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerEscapes.mp4");
$video2.attr("src", "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerJoyrides.mp4");
$video3.attr("src", "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4");
var timerID;
var $canvas = $("#myCanvas");
var ctx = $canvas[0].getContext("2d");
function stopTimer() {
window.clearInterval(timerID);
}
$('#startPlayback').click(function() {
stopTimer();
playCounter = $('#playbackNum').val();
clipArray = [];
// addd element to the end of the array
clipArray.push(1);
for (var i = 0; i < playCounter; i++) {
clipArray.push(2);
}
clipArray.push(3);
$video2[0].load();
$video3[0].load();
$video1[0].play();
});
function drawImage(video) {
//last 2 params are video width and height
ctx.drawImage(video, 0, 0, 640, 360);
}
// copy the 1st video frame to canvas as soon as it is loaded
$video1.one("loadeddata", function() {
drawImage($video1[0]);
});
// copy video frame to canvas every 30 milliseconds
$video1.on("play", function() {
timerID = window.setInterval(function() {
drawImage($video1[0]);
}, 30);
});
$video2.on("play", function() {
timerID = window.setInterval(function() {
drawImage($video2[0]);
}, 30);
});
$video3.on("play", function() {
timerID = window.setInterval(function() {
drawImage($video3[0]);
}, 30);
});
function onVideoEnd() {
//stop copying frames to canvas for the current video element
stopTimer();
// remove 1st element of the array
clipArray.shift();
//IE fix
if (!this.paused) this.pause();
if (clipArray.length > 0) {
if (clipArray[0] === 1) {
$video1[0].play();
}
if (clipArray[0] === 2) {
$video2[0].play();
}
if (clipArray[0] === 3) {
$video3[0].play();
}
} else {
// in case of last video, make sure to load 1st video so that it would start from the 1st frame
$video1[0].load();
}
}
$video1.on("ended", onVideoEnd);
$video2.on("ended", onVideoEnd);
$video3.on("ended", onVideoEnd);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div id="border">
<video id="video1" width="640" height="360" hidden>
<source type="video/mp4">
Your browser does not support playing this Video
</video>
<video id="video2" width="640" height="360" hidden>
<source type="video/mp4">
Your browser does not support playing this Video
</video>
<video id="video3" width="640" height="360" hidden>
<source type="video/mp4">
Your browser does not support playing this Video
</video>
<div>
<canvas id="myCanvas" width="640" height="360"> </canvas>
</div>
<div role="controls">
<div>
<label>
Times the middle video will repeat itself:
</label>
</div>
<div>
<input id="playbackNum" value="1" />
</div>
<p>
<button id="startPlayback">Start</button>
</p>
</div>
</div>
Please note, the code is not very pretty and would benefit from some cleanup and optimization, but at least this should show the way to work around the problem and implement a seamless playback of several videos in HTML5.
Also make sure to include jQuery source file in html file location for the code to work.
I have used VideoJS for some time and it allows seamless video playing.
http://videojs.com
You will be required jQuery for this. There are many other jQuery video players.

NaN out of get duration in Javascript

I have a problem to get out the duration of an mp4 video file when the html document is ready. My code:
(function ($, root, undefined) {
$(function () {
'use strict';
$(document).ready(function() {
var duration = $("section:first-child() video").get(0).duration;
alert(duration);
});
});
});
The script works in firefox but in chrome it returns an NaN. Im not a javascript professional and i use wordpress HTML5 Blank theme.
Thanks for your help and best regards.
You need to preload the video metadata for you to be able to access them. Then, within the loadedmetadata event, you may access the duration as below.
$(function() {
var $video = $('#video_container').find('video');
$video.on("loadedmetadata", function() {
$('#duration').text($video[0].duration);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="video_container">
<video poster="http://media.w3.org/2010/05/sintel/poster.png" preload="metadata" controls="" width="400">
<source type="video/mp4" src="http://media.w3.org/2010/05/sintel/trailer.mp4" id="mp4"></source>
<source type="video/webm" src="http://media.w3.org/2010/05/sintel/trailer.webm" id="webm"></source>
<source type="video/ogg" src="http://media.w3.org/2010/05/sintel/trailer.ogv" id="ogv"></source>
<p>Your user agent does not support the HTML5 Video element.</p>
</video>
</div>
<div>Total duration : <span id="duration"></span></div>
you need a listener to get the duration of a video
var videoTime = 0;
var currentvideo = document.getElementById('video');
currentvideo.addEventListener('play', function() {
videoTime= currentvideo.duration;
console.info(videoTime) // get the duration
});

Categories

Resources