HTML5 video height and width through javascript - javascript

I'm trying to fetch and print out width and height attributes from video with a simple javascript, but for some reason I'm not managing.
This is the javascript
video = document.getElementsByTagName("video")[1];
span1 = document.getElementById("dimensions");
span1.innerHTML = video.videoWidth + " x " + video.videoHeight;
and this is html5 code which it affects (this is the second video tag in html structure)
<figure>
<video controls>
<source src="video.webm" type="video/webm">
</video>
</figure>
<p>
Dimensions: <span id="dimensions"></span>
</p>
Thanks a lot, I'm a beginner so be light on me.

Your index, based on your markup, won't return you the element you want. The index is zero-based as node lists are array-like and start indexing at 0.
var video = document.getElementsByTagName("video")[0];
Edit: sorry, didn't see you said it was the second video tag. In that case, I'm not certain, because it works for me: http://jsfiddle.net/3wCYz/1/
One thing you might want to try is putting the code you use to get the width and height inside a handler on your video tag that listens for the loadedmetadata event:
video.addEventListener("loadedmetadata", dimensionFunction, false);
where dimensionFunction is a function that does what you're already doing to grab the dimensions.
What this does is make sure the metadata for the video has downloaded before you try to grab it.

Related

how to avoid changes on video height while changing its attributes

click on a button changes video poster and src attributes
after the click video height becomes 0 - a short period - but enough to produce an ugly effect on entire page
how to avoid this?
note - lorem.mp4 and ipsum.mp4 have the same resolution and dimensions
<video class='vtop' id='player' controls poster='lorem.jpg'>
<source src='lorem.mp4' type='video/mp4'>
</video>
js
var player = $('#player');
$('button').on('click', function(){
player.attr('poster', 'ipsum.jpg');
player.attr('src', 'ipsum.mp4');
player[0].play();
});
I tried your code and add a css file to it and give the video a fix height:
video {
height: 400px;
}
I think it is enough and I don't see any special effect when I click button.
The height is changed because your video player height depends on the video height. And when you change src video player height changes as well. What you need to do, is just specify height for your video tag.

How to capture thumbnails (frame) from video with HTML5 and Jquery?

I have a simple block in which I would like to capture a frame from video every 5 seconds and display them something like this below.
Here is a solution I have tried.
<video id="video" controls="controls">
<source src="http://www.w3schools.com/html/mov_bbb.mp4">
</source>
</video>
<div id="time-ruler"></div>
<canvas id="canvas" width="300" height="300"></canvas>
<div id="thumbnailContainer"></div>
Here is javascript
video.addEventListener('loadeddata', function() {
var duration = video.duration;
var i = 0;
var interval = setInterval(function() {
video.currentTime = i;
generateThumbnail(i);
i = i+5;
if (i > duration) clearInterval(interval);
}, 300);
});
function generateThumbnail(i) {
//generate thumbnail URL data
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, 220, 150);
var dataURL = canvas.toDataURL();
//create img
var img = document.createElement('img');
img.setAttribute('src', dataURL);
//append img in container div
document.getElementById('thumbnailContainer').appendChild(img);
}
Here is jsfiddle: live demo
Unfortunately, this is not working as expected.
What do I need to do to get what I want?
Check the following:
https://jsfiddle.net/psbqn9d0/1/
It won't create the view you shown in the picture, but will change the thumbnail every 5 second. I have also added few logging to help you understand the code.
Now, if you want to achieve what is shown in figure then this is possible:-
if you have loaded the video completely. Then create all the thumbnails and add them to the container.
you create the thumbnails on the server and send them to user (like done by most video sites (so we can see what is in the video without loading!))
OR you can create all the thumbnails without loading the whole video. I am not sure if this is the best way, but this will definitely work.
You should create another video tag with the same source link, and hide it using css. Then you will create a javascript function which will seek it to every 5th second programmatically and keep saving the thumbnails and adding them in your container. This way, your thumbnails will be generated for the whole video without loading the whole video.
I hope it clarifies your doubts!

which is more performant, <video> or <canvas> with video embed?

I am developing a page with a full width / full height intro video (100vw / 100vh), looks "full screen" until you scroll down.
Currently I am using HTML5 <video> to accomplish this, but I've noticed the page can get a little choppy, particularly while scrolling. The video is about 4mb.
Would I see an increase in performance if I were to replace the <video> with a <canvas>, and load the video frames directly through the canvas object instead? both elements are GPU accelerated so I'd figure it shouldn't make a difference, but I'm not sure.
No, all the cost of decoding a video frame is still there. Using a canvas would in addition to that add more cost, not less.
If the video is without sound you could temporary pause the video while scrolling, as well as pause it permanently when out of view:
var vt;
window.onscroll = function() {
video.pause(); // pause video
clearTimeout(vt); // clear timer
vt = setTimeout(function() { // create a new timer
var r = video.getBoudingClientRect(); // abs. bound
if (window.scrollY < r.height) video.play(); // assumes video is in top
}, 70); // 70ms
...
};
Another key, although not of very much difference, is to make sure the video code is easy to decode. You can achieve this by removing noise, use flat colors and large surfaces, good lighting conditions, low depth-of-field to blur background as well as lower contrast and avoid too many details in the main subject(s) (this will also produce smaller files).
var video = document.querySelector("video"),
vt;
window.onscroll = function() {
video.pause();
clearTimeout(vt);
vt = setTimeout(function() {
var r = video.getBoundingClientRect();
if (window.scrollY < r.height) video.play();
}, 70);
};
html, body {width:100%; height: 2000px}
video {
width:100%;
height:auto;
}
<video muted width="500" height="280" autoplay="true">
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4" type="video/mp4">
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.webm" type="video/webm">
<source src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.ogv" type="video/ogg">
</video>

Responsive background images

Currently I'm working on building a solution for having responsive background images set via JavaScript. I am using Picturefill to create cross-browser support.
What do I need? There is an element on my page which needs a pretty little background photo. On the page there is a picture element which loads conditionally images. However I specified one default image source if the browser doesn't have proper picture element support.
With MooTools I check what photo is supposed to show up on domready, on window resize I check my image 'src' again to replace my current picture if needed (with a bigger or smaller one).
In FireFox the picture element replaces the image 'src' in the DOM, it works perfect!
Chrome (and IE) don't replace the image 'src' so my photo will always have the default photo dimensions according to MooTools. However, when you hover over the image 'src' via the Chrome developer tools it does show the correct image source for that media query.
I can get in way too many details but trust me I really need to do it like mentioned above, who want to help me with this? :)
<script>
var Placeholder = $('Placeholder');
var CoverImage = $('MyCover').getElement('img').src;
Placeholder.setStyle('background-image', 'url(' + CoverImage + ')');
var $timer = null;
window.addEvent('resize', function(){
var ResponsiveImage = function(){
var $ResponsiveImage = $('MyCover').getElement('img').src;
$('Placeholder').setStyle('background-image', 'url(' + $ResponsiveImage + ')');
};
clearTimeout($timer);
$timer = ResponsiveImage.delay(250, this);
});
</script>
<picture>
<source media="all and (max-width: 30em)" srcset="1.jpg">
<source media="all and (min-width: 30.063em) and (max-width: 48em)" srcset="2.jpg">
<source media="all and (min-width: 48.063em) and (max-width: 80em)" srcset="3.jpg">
<source media="all and (min-width: 80.063em)" srcset="4.jpg">
<img src="2.jpg">
</picture>
Thanks for the possible solutions, I am very grateful!
Cheers,
Stefan
Perhaps I don't understand exactly what you are trying to do, but instead of trying to use the script to control the dimensions why not use the CSS property background-size: cover; instead? That is what I always use for responsive background images not that it is widely supported by browsers.
You should really look at http://foundation.zurb.com/docs/components/interchange.html.
Maybe you can get the script and adapt it to your case?
First of all your markup:
In picture land you don't need to use min-width and max-width. The first source, that matches is the media query is used:
<picture><source media="(max-width: 30em)" srcset="1.jpg">
<source media="(max-width: 48em)" srcset="2.jpg">
<source media="(max-width: 80em)" srcset="3.jpg">
<source srcset="4.jpg">
<img src="2.jpg"></picture>
Now, what you need is actually the property currentSrc, but be aware it needs to be handled different than the src property, because it is updated, after the image is loaded (so don't use resize, use load).
Fortunately there is already a simple lazySizes plugin called bgset, that does exactly what you need. Here you find a demo and here you find the documentation. Of course you can also check out the source code and build your own.
In case you want to use the plugin your markup changes to something like this:
<div class="lazyload" data-bgset="1.jpg [(max-width: 30em)] | 2.jpg [(max-width: 48em)] | 3.jpg [(max-width: 80em)] | 4.jpg"></div>
I am using the currentSrc property to get the updated image source and it works like a charm! Thanks everyone for the help!

Start video at vertical scroll point, then play in reverse

I'm trying to achieve something with html5 video and haven't been able to find an answer elsewhere. Is it possible? Any help is much appreciated.
Here's the html:
<video autoplay="autoplay" poster="http://dummyimage.com/320x240/ffffff/fff">
<source src="videos/ship.mp4" type="video/mp4" />
</video>
I want to:
- on page load, display the video paused on the first frame (use poster?)
- at vertical scroll of X pixels, play the video once through (alternatively, inject it onto the page at X scroll?)
- then, when I scroll back beyond the X pixels value play the video again in reverse once through (does this work aMediaElement.playbackRate = -1; ?)
sadly the simplest solution playbackRate = -1 doesn't seem to be implemented anywhere yet.
you could fake it with some code like below to jump the currentTime back at whatever rate you need but from playing around it doesn't look very smooth.
my suggestion would be - if practical - to actually encode a a reversed version of the video if being able to play it backwards is the goal and then swap the source or toggle the visible <video> tag
Oh, and as usual... any video you're planning to stream on the web make sure you optimize and get the moov atom in the right place (see sample ffmpeg)
<script>
var intervalRewind = 0;
var v = document.getElementById("v")
function rewind() {
intervalRewind = setInterval(
function(){
v.playbackRate = 1.0;
if(v.currentTime == 0){
clearInterval(intervalRewind);
v.pause();
} else {
v.currentTime += -.1;
}
},30);
}
</script>
...
<video id="v" onclick="clearInterval(intervalRewind)" width="320" height="240" controls="controls">
<source type="video/mp4" src="video-fs.mp4" />
</video>
<button onclick="rewind()">Rewind</button>

Categories

Resources