Background Videos HTML5 - javascript

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');

Related

Cannot access video load progress in 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>

Javascript attributes not changing after once they have changed already

I have a webpage where I display streaming videos (WebRTC Conference) dynamically and for that I also have to set there video element size dynamically depending on number of videos.
I realized that my javascript code only changes the size of video elements only once (when I apply it for the first time). Or may be I am doing something wrong. Because it works fine if I hardcode number of videos (only html and js; no webrtc) and js has to set their size in one go (at once).. my webrtc code is in a way that in beginning its always one video, as it loops through (when new video comes in) then my code not able to handle the size of all elements.
My code:
// I have to reuse this code everytime I have to change size (properties) of all video tags in the document
function layout() {
for(var i=0;i<videoIds.length;i++){ // I've tried with ids
var localView = document.getElementById(videoIds[i]);
localView.setAttribute('position', 'relative');
localView.setAttribute('height', '50vh');
localView.setAttribute('width', '50vw');
localView.setAttribute('object-fit', 'cover');
}
var localView = document.getElementsByClassName('class'); // I've tried with class name
for(var i=0;i<localView.length;i++){
localView.setAttribute('position', 'relative');
localView.setAttribute('height', '50vh');
localView.setAttribute('width', '50vw');
localView.setAttribute('object-fit', 'cover');
}
var localView = document.getElementsByTagName('video'); // I've tried with tag name
for(var i=0;i<localView.length;i++){
localView.setAttribute('position', 'relative');
localView.setAttribute('height', '50vh');
localView.setAttribute('width', '50vw');
localView.setAttribute('object-fit', 'cover');
}
}
Am I missing anything here? please help.
Is it possible that my code is not getting completed by the time code is re-called again, or some how code is skipped. Example:
const initSelfStream = (id) => {
(async () => {
try {
await navigator.mediaDevices.getUserMedia(
{
//video: { facingMode: selectedCamera },
video: video_constraints,
audio: true
}).then(stream => {
const video = document.createElement("video");
loadAndShowVideoView(video, stream, localId);
});
} catch (err) {
console.log('(async () =>: ' + err);
}
})();
}
initSelfStream(id);
// Some Code
pc.ontrack(e){
const video = document.createElement("video");
loadAndShowVideoView(video, e.tracks[0], remoteId);
}
const loadAndShowVideoView = (video, stream, id) => {
if(totalUsers.length == 1){
console.log('Currently ' + totalUsers.length + ' User Are Connected.');
video.classList.add('video-inset', 'background-black');
video.setAttribute("id", id);
video.style.position = "absolute"
video.srcObject = stream;
video.style.height = 100+"vh"
video.style.width = 100+"vw"
video.muted = true;
video.style.objectFit = "cover"
appendVideo(video, stream);
} else if(totalUsers.length == 2){
// I add new video with desirable height & width
// Then call and run original function on the top with element number & condition
layout('8 videos', "size should be 25vh, 25vw");
}
}
const appendVideo = (video, stream) => {
container.append(video);
video.play()
}
Html is very simple. One div in body that contain videos:
<body>
<div class="views-container background-black" id="container"></div>
</body>
Try to combine all style attributes. Instead of:
video.style.position = "absolute"
video.style.height = 100+"vh"
video.style.width = 100+"vw"
video.style.objectFit = "cover"
You can:
video.setAttribute('style', 'position: absolute; height: 100vh; width: 100vw; object-fit: cover;);
And since you already uses css classes, you don't have to repeat it over on your conditions and just:
video { position: absolute; top: 0; left: 0; obejct-fit: cover; }
Now you can change width and height with setAttribute.

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

How to generate video thumbnails and preview them while hovering on the progress bar?

I want to generate video thumbnail and preview it while hovering on the progress bar like YouTube video:
I've tried to test with videojs-thumbnails but failed. The README file doesn't contain enough information to fix it.
I've also tried to search on Google with keyword: video thumbnail progress bar. There are some related questions on SO but I can't find the solution for this case.
I found a javascript library videojs which contains event hovering on progress bar:
videojs('video').ready(function () {
$(document).on('mousemove', '.vjs-progress-control', function() {
// How can I generate video thumbnails and preview them here?
});
});
Currently (Dec. 2019), there are not so much javascript (both free version and paid version) library which supports adding thumbnail while hovering on video progress bar.
But you can follow on the road of videojs. They've already supported adding tooltip while hovering on video progress bar. Everything else you can do is Generating video thumbnails and adding them into the control bar for previewing.
In this example, we will explain about how to generate video thumbnail from <input type="file" />. Athough we can use video source with a directly link, in testing period, we have some problem with Tainted canvases may not be exported because of using canvas.toDataURL()
After videojs completes initializing, you can clone a new video from the source and append it to the body. Just to play and catch loadeddata event:
videojs('video').ready(function () {
var that = this;
var videoSource = this.player_.children_[0];
var video = $(videoSource).clone().css('display', 'none').appendTo('body')[0];
video.addEventListener('loadeddata', async function() {
// asynchronous code...
});
video.play();
});
Like YouTube video thumbnail, we will generate thumbnail file as an image. This image has a size:
(horizontalItemCount*thumbnailWidth)x(verticalItemCount*thumbnailHeight) = (5*158)x(5*90)
So 790x450 is the size of the image which contains 25 sub-thumbnails (YouTube uses 158 as the width and 90 as the height of the thumbnail). Like this:
Then, we will take video snapshot based on video duration. In this example, we generate thumbnail per second (each second has a thumbnail).
Because generating video thumbnail needs a long time based on video duration and quality, so we can make a default thumbnail with a dark theme for waiting.
.vjs-control-bar .vjs-thumbnail {
position: absolute;
width: 158px;
height: 90px;
top: -100px;
background-color: #000;
display: none;
}
After getting video duration:
var duration = parseInt(that.duration());
we need to parse it to an int before using in the loop because the value may be 14.036.
Everything else is: Setting the currentTime value of the new video and converting the video to canvas.
Because 1 canvas element can contains maximum 25 thumbnails by default, we have to add 25 thumbnails to the canvas one-by-one (from left to right, from top to bottom). Then we store it in an array.
If there is still another thumbnail, we create another canvas and repeat the action
var thumbnails = [];
var thumbnailWidth = 158;
var thumbnailHeight = 90;
var horizontalItemCount = 5;
var verticalItemCount = 5;
var init = function () {
videojs('video').ready(function() {
var that = this;
var videoSource = this.player_.children_[0];
var video = $(videoSource).clone().css('display', 'none').appendTo('body')[0];
// videojs element
var root = $(videoSource).closest('.video-js');
// control bar element
var controlBar = root.find('.vjs-control-bar');
// thumbnail element
controlBar.append('<div class="vjs-thumbnail"></div>');
//
controlBar.on('mousemove', '.vjs-progress-control', function() {
// getting time
var time = $(this).find('.vjs-mouse-display .vjs-time-tooltip').text();
//
var temp = null;
// format: 09
if (/^\d+$/.test(time)) {
// re-format to: 0:0:09
time = '0:0:' + time;
}
// format: 1:09
else if (/^\d+:\d+$/.test(time)) {
// re-format to: 0:1:09
time = '0:' + time;
}
//
temp = time.split(':');
// calculating to get seconds
time = (+temp[0]) * 60 * 60 + (+temp[1]) * 60 + (+temp[2]);
//
for (var item of thumbnails) {
//
var data = item.sec.find(x => x.index === time);
// thumbnail found
if (data) {
// getting mouse position based on "vjs-mouse-display" element
var position = controlBar.find('.vjs-mouse-display').position();
// updating thumbnail css
controlBar.find('.vjs-thumbnail').css({
'background-image': 'url(' + item.data + ')',
'background-position-x': data.backgroundPositionX,
'background-position-y': data.backgroundPositionY,
'left': position.left + 10,
'display': 'block'
});
// exit
return;
}
}
});
// mouse leaving the control bar
controlBar.on('mouseout', '.vjs-progress-control', function() {
// hidding thumbnail
controlBar.find('.vjs-thumbnail').css('display', 'none');
});
video.addEventListener('loadeddata', async function() {
//
video.pause();
//
var count = 1;
//
var id = 1;
//
var x = 0, y = 0;
//
var array = [];
//
var duration = parseInt(that.duration());
//
for (var i = 1; i <= duration; i++) {
array.push(i);
}
//
var canvas;
//
var i, j;
for (i = 0, j = array.length; i < j; i += horizontalItemCount) {
//
for (var startIndex of array.slice(i, i + horizontalItemCount)) {
//
var backgroundPositionX = x * thumbnailWidth;
//
var backgroundPositionY = y * thumbnailHeight;
//
var item = thumbnails.find(x => x.id === id);
if (!item) {
//
//
canvas = document.createElement('canvas');
//
canvas.width = thumbnailWidth * horizontalItemCount;
canvas.height = thumbnailHeight * verticalItemCount;
//
thumbnails.push({
id: id,
canvas: canvas,
sec: [{
index: startIndex,
backgroundPositionX: -backgroundPositionX,
backgroundPositionY: -backgroundPositionY
}]
});
} else {
//
//
canvas = item.canvas;
//
item.sec.push({
index: startIndex,
backgroundPositionX: -backgroundPositionX,
backgroundPositionY: -backgroundPositionY
});
}
//
var context = canvas.getContext('2d');
//
video.currentTime = startIndex;
//
await new Promise(function(resolve) {
var event = function() {
//
context.drawImage(video, backgroundPositionX, backgroundPositionY,
thumbnailWidth, thumbnailHeight);
//
x++;
// removing duplicate events
video.removeEventListener('canplay', event);
//
resolve();
};
//
video.addEventListener('canplay', event);
});
// 1 thumbnail is generated completely
count++;
}
// reset x coordinate
x = 0;
// increase y coordinate
y++;
// checking for overflow
if (count > horizontalItemCount * verticalItemCount) {
//
count = 1;
//
x = 0;
//
y = 0;
//
id++;
}
}
// looping through thumbnail list to update thumbnail
thumbnails.forEach(function(item) {
// converting canvas to blob to get short url
item.canvas.toBlob(blob => item.data = URL.createObjectURL(blob), 'image/jpeg');
// deleting unused property
delete item.canvas;
});
console.log('done...');
});
// playing video to hit "loadeddata" event
video.play();
});
};
$('[type=file]').on('change', function() {
var file = this.files[0];
$('video source').prop('src', URL.createObjectURL(file));
init();
});
.vjs-control-bar .vjs-thumbnail {
position: absolute;
width: 158px;
height: 90px;
top: -100px;
background-color: #000;
display: none;
}
<link rel="stylesheet" href="https://vjs.zencdn.net/7.5.5/video-js.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://vjs.zencdn.net/7.5.5/video.js"></script>
<input type="file" accept=".mp4" />
<video id="video" class="video-js vjs-default-skin" width="500" height="250" controls>
<source src="" type='video/mp4'>
</video>
Fiddle
I struggled with this exact issue, about a year ago. Based on the thread here: How to generate video preview thumbnails for use in VideoJS? I finally concluded to go with offline generation of thumbnails, as it's much easier than trying to extract them on-the-fly.
I did a technical discussion/explanation of that struggle here: http://weasel.firmfriends.us/GeeksHomePages/subj-video-and-audio.html#implementing-video-thumbnails
My prototype example is here: https://weasel.firmfriends.us/Private3-BB/
EDIT:Also, I couldn't solve how to bind to the existing seekBar in video-js, so I added my own dedicated slider to view the thumbnails. That decision was mostly based on the need to use 'hover'/'onMouseOver' if one wants to use video-js's seekbar, and those gestures don't translate well to touch-screens (mobile devices).
EDIT: I've now solved the issue of how to bind the existing seekBar, so
I've added that logic to my prototype example mentioned above.
Cheers. Hope this helps.
For anyone whom is looking for an Angular solution. I have published a npm package for you to create a thumbnail snapshot when video progress bar is on hover.
npm: ngx-thumbnail-video
You can install it by
npm i ngx-thumbnail-video
and include it into your module:
import { NgxThumbnailVideoModule } from 'ngx-thumbnail-video';
#NgModule({
imports: [NgxThumbnailVideoModule]
})
And use it in this way:
<ngx-thumbnail-video url="assets/video.mp4" [options]="options"></ngx-thumbnail-video>
What it looks like:

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.

Categories

Resources