Cannot access video load progress in Javascript - javascript

I'm trying to make a video player with several features by js html and css, but when I came to trying to preload the video, I couldn't find a way to know how much of the video was downloaded, and I need to know this info so I can update a progress bar to tell how much data has been buffered.
Is there a way to find out how much a video has been buffered?
I tried accessing the video preload property in javascript to get how much it was preloaded . but it gave me the preload type of the video

You need to use: TimeRanges to know the length of loaded (buffered) video.
There will be more time ranges added if you seek into a new area that has not yet buffered. Either handle such situation or else code your UI to not respond if a user clicks outside the fill area (eg: only clicking within fill area will change currentTime of video).
Also read: Media buffering, seeking, and time ranges guide for more knowledge.
Below is some testable code as a starting point to expand:
<!DOCTYPE html>
<html>
<body>
<video id="myVid" width="320" height="240" controls>
<source src="your_file.mp4" type="video/mp4">
</video>
<br><br>
<div id="myProgress_BG" style="width: 320px; height: 30px; background-color: #808080">
<div id="myProgress_Bar" style=" width: 1%; height: 30px; background-color: #00A0E6" ></div>
</div>
</body>
<script>
let timeLoaded = 0; let timeTotal = 0;
//# access the "fill" (blue) bar
let prog_Bar = document.getElementById('myProgress_Bar');
//# get the max width for the "fill" (is same as BG width)
let prog_Max = document.getElementById('myProgress_BG').style.width;
prog_Max = parseInt(prog_Max);
//# set a listener for the "progress" event
let vid = document.getElementById('myVid');
vid.addEventListener('progress', (event) => { myProgressFunc() });
function myProgressFunc()
{
//# update times (duration and buffered)
if( timeTotal == 0 ) { timeTotal = vid.duration; }
timeLoaded = vid.buffered.end(0);
//# update width via CSS Styles (numbers need a +"px" to work)
prog_Bar.style.width = ( prog_Max / ( timeTotal / timeLoaded) ) +"px";
}
</script>
</html>

Related

How to scroll the transcrib of a video in real time in html5

I would like to create a javascript html5 script that allows to have
poster and play a youtube video with its transcript.
and in this script I'd like a button that captures the images from the video as soon as I press the button.
And that the transcript is written in the browser and as the video progresses.
the goal is that at the end of the video I'll have a full article of the video.
Example:
1) I put a youtube link in the script
2) I see in the html5 page the video
3) I press play on the video
4) the transcription how to write in the html page ok
5) at any time I can make a pose of the video to take a screenshot of the image.
the result must be the following.
I'm taking a screenshot so one frame of the video to start with.
I've got the text underneath.
screenshot image
transcribed text
screenshot image
transcribed text
screenshot image
transcribed text
screenshot image
transcribed text
until the end of the video
the screenshot captures it's me who makes them by pressing the button to capture the screenshot.
I managed to make a page that takes the screenshot with a button from a local mp4 video.
but what I can't do, and that's where I need your help:
1) is to play a youtube video in an html5 page with always the screen shot button
2) write in real time the transcription in a html5 page until the end of the video.
thank you for your help.
<script>
var videoId = 'video';
var scaleFactor = 0.5;
var snapshots = [] ;
/**
* Captures a image frame from the provided video element.
*
* #param {Video} video HTML5 video element from where the image frame will be captured.
* #param {Number} scaleFactor Factor to scale the canvas element that will be return. This is an optional parameter.
*
* #return {Canvas}
*/
function capture(video, scaleFactor) {
if (scaleFactor == null) {
scaleFactor = 1;
}
var w = video.videoWidth * scaleFactor;
var h = video.videoHeight * scaleFactor;
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, w, h);
innerHTML = "<br>";
return canvas ;
}
/**
* Invokes the <code>capture</code> function and attaches the canvas element to the DOM.
*/
function shoot() {
var video = document.getElementById(videoId);
var output = document.getElementById('output');
var canvas = capture(video, scaleFactor);
canvas.onclick = function() {
window.open(this.toDataURL(image/jpg));
};
snapshots.unshift(canvas);
output.innerHTML = '';
for (var i = 0; i < 10; i++) {
output.appendChild(snapshots[i]) ;
}
}
(function() {
var captureit = document.getElementById('cit');
captureit.click();
})();
</script>
<style>
.wrap {
border: solid 1px #ccc;
padding: 10px;
text-align: center;
}
#output {
display: inline-block;
top: 4px;
position: relative;
border: dotted 1px #ccc;
padding: 2px;
}
.button {
border: solid 2px #ccc;
}
</style>
<html>
<body>
<div class="wrap">
<video id="video" width="600" controls="true">
<source src = "http://127.0.0.1/divi.mp4" type = "video/mp4"></source>
<!-- FireFox 3.5 -->
<source src = "http://127.0.0.1/divi.mp4" type = "video/mp4"></source>
<!-- WebKit -->
Your browser does not support HTML5 video tag. Please download FireFox 3.5 or higher.
</video>
<br/>
<button id="cit" onclick="shoot()" class="button">Capture</button>
<br/>
<div id="output">
</div>
here are two scripts the first one has a button that captures the images of an MP4 video
and the second one that stupidly extracts all the images from a video automatically...
what I'm missing is:
1) put the link of any youtube video that is displayed in the html5 page
2) when I click on play I get the transcript which is written below the video automatically.
3) I want to do a pose to make a screen capture
4) continue transcription
5) image capture of the video etc...
text
image
text
image
until the end of the video
the goal of getting my full article.
I have a lot of tutorials on youtube and I would like to have them in documentation on my website.
create a complete article for each video
the best thing is to have a motion capture of the automatic image.
that is to say:
1) I click on the video
2) the script takes a first capture of the video
3) the transcription is written below the image captured in the html5 page
4) as soon as the image changes the script detects it and takes the print screen by itself without any button.
and so on until the end of the video without my intervention.
it creates a complete article on its own
just by putting my youtube link!!
It'll be the best of the best...
thank you for your support I'm sure that among you there are people who have websites and would like to have a script that can do articles alone...
3) as soon as

Change HTML 5 autoplayed video source dynamically

On my website https://cravydev.netlify.com I'm trying to change the video dynamically when the different headlines are in viewport.
I'm using a div with HTML 5 autoplay and loop properties, but not able yet to change the video source and load again when the specific headline is on screen. Here are the details.
HTML
<div class="iphone-sticky"></div>
<div class="iphone-video">
<video autoplay loop muted poster="assets/img/poster.png" id="iphonevideo">
<source id="video1" src="assets/img/iphone-video.mp4" type="video/mp4">
<source id="video2" src="assets/img/iphone-video-1.mp4" type="video/mp4">
</video>
JS
//Detect is element is in viewport
$(window).on('resize scroll', function() {
var player = document.getElementById('iphonevideo2');
if ($('#headline2').isInViewport()) {
var source = document.getElementById('video1');
$(source).attr("src", "assets/img/iphone-video-1.mp4");
player.pause();
player.load();
} else if ($('#headline3').isInViewport()) {
var source = document.getElementById('video1');
$(source).attr("src", "assets/img/iphone-video.mp4");
player.pause();
player.load();
}
});
EDIT
I have been able to solve it thanks to Kley comment. Now the problem is that the js logic does not check constantly the viewport visibility of headlines, only once. Also, the video is played while scrolling and the poster image appears, making the whole experience a little bit weird.
Any suggestion to solve that?
Thanks!
Check the page, it's not the viewport ()
I could tell you that you are changing the src every time you scroll while it is visible, this is causing the video to restart. You must make a validation, if it has already been changed the src should not be changed again.
Note that # headline2 is not visible when # headline3 is a bit up.
you have to scroll down until the end of the page to enter this condition.
You could use another smaller element at the beginning of each #headline to do this validation.
you could use the first p of the #headline
For example:
$(window).on('resize scroll', function() {
var player = document.getElementById('iphonevideo2');
if ($('#headline2 p').eq(0).isInViewport()) {
var source = document.getElementById('video1');
var url = "assets/img/iphone-video-1.mp4";
var src = $(source).attr("src");
// validate if you already have the src
if(src==url) return; // if exists src leaves function
$(source).attr("src", url);
player.pause();
player.load();
} else if ($('#headline3 p').eq(0).isInViewport()) {
var source = document.getElementById('video1');
var src = $(source).attr("src");
var url = "assets/img/iphone-video.mp4";
// validate if you already have the src
if(src==url) return; // if exists src leaves function
$(source).attr("src", url);
player.pause();
player.load();
}
})

How to replace src= "name1" with src="name2"?

everybody!
i have an idea, but I don't know how to implement it.
how to make sure that when you press ctrl + shift + i also on the f12 key changed a certain part of the html code?
for example: SRC="video.MP4 "on SRC=" error.MP4
Thanks!
update -9.24.18
you need to make it so that the user was difficult to copy the link from scr="video.mp4"
-Aison
Here's one way you could do this:
<video id="someVideo" src="somfile.mp4" />
<script>
function KeyPress(e)
{
var evtobj = window.event ? event : e;
// 73 = i
if (evtobj.keyCode == 73 && evtobj.ctrlKey && evtobj.shiftKey)
{
document.getElementById('someVideo').src = "error.mp4";
}
}
// On keypress, activate our function
document.onkeydown = KeyPress;
</script>
However, as I mentioned in the comments this will in no way prevent users from downloading your mp4 file.
Users can still:
Right click, inspect element
Hit f12
Have the 'inspect element' open before visiting your website
Save your webpage
Save just the video from your webpage
Disable JS / override your JS.
Access your webpage without the use of a webbrowser (GET/save your webpage)
There are other ways as well, that's just off the top of my head.
Edit following comments:
You could instead use an html5 <canvas>.
This will hide the source. However, it will cause the video to no longer work if the user has JS disabled.
Example (you'll have to either add your own play button, or change the script to start the video automatically):
<!-- You can hide this element anywhere in your hmtl. It will not be visbile (via CSS) -->
<!-- note: I used `muted="muted"` because otherwise you will get an error when starting the video without a user action -->
<video id="someVideo" muted="muted" controls>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type="video/mp4">
</video>
<!-- canvas will display the video -->
<canvas id="myCanvas"></canvas>
<script>
document.addEventListener('DOMContentLoaded', function()
{
var hiddenVideo = document.getElementById('someVideo');
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var cw = Math.floor(canvas.clientWidth);
var ch = Math.floor(canvas.clientHeight);
canvas.width = cw;
canvas.height = ch;
hiddenVideo.addEventListener('play', function(){
draw(this,context,cw,ch);
},false);
hiddenVideo.onloadstart = function(){
this.play();
};
},false);
function draw(v,c,w,h)
{
if(v.paused || v.ended)
return false;
c.drawImage(v,0,0,w,h);
setTimeout(draw,20,v,c,w,h);
}
</script>
<style>
#someVideo
{
display: none;
width: 200px;
height: 200px;
}
#myCanvas
{
width: 200px;
height: 200px;
}
</style>
Since you're giving the mp4 file to the user, you cannot prevent the user from having the mp4 file.

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.

Background Videos HTML5

I want to create a background with differents videos, when the user refresh the page change to other video.
Now i have this, maybe with javascript i can do it but i don't know how.
<video loop="loop" preload="auto" muted="" autoplay="" poster="/templates/smartone/images/video/fondo.jpg" id="bgvid">
<source src="/templates/smartone/images/video/fondo1.mp4" type="video/mp4">
<source src="/templates/smartone/images/video/fondo1.webm" type="video/webm">
</video>
As #zmehboob said, you will have to make a list of videos to pick one randomly.
For this purpose, I'm using an object that contains the different available types for creating source elements, then I pick a random one for src before iterating through its extensions for sourceelements.
Here is some code (Vanilla):
// first create the list with extensions as parameters
var videoList = {
'http://media.w3.org/2010/05/sintel/trailer': ['mp4', 'ogv'],
'http://media.w3.org/2010/05/bunny/movie': ['mp4', 'ogv']
};
function create_BG_Video() {
//create the video element and its source
var el = document.createElement('video');
var source = document.createElement('source');
// here is the magic that takes a random key in videoList object
var k = randomKey(videoList);
//iterate through each extension to make a new source type
for (m in videoList[k]) {
source.src = k + '.' + videoList[k][m];
var type;
//as ogg video may be with a '.ogv' extension, we have to watch for it
(videoList[k][m] == 'ogv') ? type = 'ogg': type = videoList[k][m];
source.type = "video/" + type;
el.appendChild(source);
}
el.className = 'bg_video';
el.width = window.innerWidth;
el.height = window.innerHeight;
el.setAttribute('autoplay', 'true');
//Set it as the first element in our body
document.body.insertBefore(el, document.body.childNodes[0]);
}
// if it is the only used instance, it could be placed at start of the function
var randomKey = function(obj) {
// Get all the keys in obj (here videoList)
var k = Object.keys(obj)
// Here '<< 0' is equivalent to Math.floor()
return k[k.length * Math.random() << 0];
};
window.onload = create_BG_Video;
html,
body {
margin: 0;
width: 100%;
height: 100%;
}
.bg_video {
height: 100%;
width: 100%;
margin: 0;
top: 0;
position: fixed;
z-index: -999;
background: #000;
}
#content {
margin-top: 15%;
color: #FFF;
}
<div id='content'>
<p>Well, the way they make shows is, they make one show. That show's called a pilot. Then they show that show to the people who make shows, and on the strength of that one show they decide if they're going to make more shows. Some pilots get picked and become
television programs. Some don't, become nothing. She starred in one of the ones that became nothing.</p>
<img src="http://lorempixel.com/300/200" />
</div>
So basically you'll want to run the function at pageload (wrap it in document.ready).
You will want a srcsList array which will hold all your video sources (don't include the file extension).
You want to select a random number limited by the number of sources you have.
Finally you will update the src for your mp4 and webm sources so they reference the new random src.
var srcsList = ["/templates/smartone/images/video/fondo1", "/templates/smartone/images/video/fondo2", "/templates/smartone/images/video/fondo3"];
var randomInt = Math.floor(Math.random() * srcsList.length);
var randomSrc = srcsList[randomInt];
$('[type="video/mp4"]').attr('src', randomSrc + '.mp4');
$('[type="video/webm"]').attr('src', randomSrc + '.webm');

Categories

Resources