How to make a loading image when loading HTML5 video? - html

As it takes time for the video player to load the mp4 video, does HTML5 support playing a "loading" logo when loading the video ?
Since my asp.net apps is a mobile page, it needs the user to click on the video to play the video (android, iphone not support autoplay). So, I cannot make a "loading" logo as poster, otherwise, the user will be confused about it. I want to display a loading logo when user click play button on iPad.
thanks
Joe

It took me a way too long to actually figure out how to do this, but I'm going to share it here because I FINALLY found a way! Which is ridiculous when you think about it, because loading is something that all videos have to do. You'd think they would have taken this into account when creating the html5 video standard.
My original theory that I thought should have worked (but wouldn't) was this
Add loading bg image to video when loading via js and css
Remove when ready to play
Simple, right? The problem was that I couldn't get the background image to show when the source elements were set, or the video.src attribute was set. The final stroke of genius/luck was to find out (through experimentation) that the background-image will not disappear if the poster is set to something. I'm using a fake poster image, but I imagine it would work as well with a transparent 1x1 image (but why worry about having another image). So this makes this probably a kind of hack, but it works and I don't have to add extra markup to my code, which means it will work across all my projects using html5 video.
HTML
<video controls="" poster="data:image/gif,AAAA">
<source src="yourvid.mp4"
</video>
CSS (loading class applied to video with JS)
video.loading {
background: black url(/images/loader.gif) center center no-repeat;
}
JS
$('#video_id').on('loadstart', function (event) {
$(this).addClass('loading');
});
$('#video_id').on('canplay', function (event) {
$(this).removeClass('loading');
$(this).attr('poster', '');
});
This works perfectly for me but only tested in chrome and safari on mac. Let me know if anyone finds bugs and or improvements!

Also a simple solution to add a preloader image while loading the video:
HTML:
<video class="bg_vid" autoplay loop poster="images/FFFFFF-0.png">
the poster is a transparent image 1px.
CSS:
video {
background-image: url(images/preload_30x30.gif);
background-repeat: no-repeat;
background-size: 30px 30px;
background-position: center;
}

Use the tag id poster
<video controls="controls" poster="/IMG_LOCATION/IMAGENAME">
More info can be found http://www.w3schools.com/html5/att_video_poster.asp

You could probably do it with JavaScript by creating an image overlay with an animated "loading" gif which you only display when the video is loading and is not ready to play.
You'd have to write JavaScript to link up with the Media API for detecting when the video is ready to play and so forth though (so you could hide the image again), but it should be possible.

My solution was to add the following inside of the window.fbAsyncInit = function():
var finished_rendering = function() {
var el = document.querySelector('div#loading_msg');
el.style.display="none";
}
FB.Event.subscribe('xfbml.render', finished_rendering);
Found: https://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/v2.12

Personally I think the most elegant way to do this is by using some code like this,
<video src="myVideo.fileExtension" onplaying="hideControls(this)" onwaiting="showControls(this)" preload="auto" poster="myAnimatedWebpOrGifThatSaysVideoIsNotYetReady.fileExtension">No video support?</video>
<script type="text/javascript">
//We hide the video control buttons and the playhead when the video is playing (and enjoyed by the viewer)
function hideControls(event){ event.controls=false; }
//If the video has to pause and wait for data from the server we let controls be seen if the user hovers or taps on the video. As a bonus this also makes the built-in loading animation of the browser appear e.g. the rotating circular shape and we give it a little delay (like 1 sec) because we don't want the controls to blink and the delayed show-up actually looks nicer.
function showControls(event){ setTimeout(function(){ event.controls=true; },1000); }
</script>
To make it even better you could use ontimeupdate instead of onplaying which would fire continuously.
As for the delay time actually not 1 but 4 seconds -to me- is the best.

Related

HTML5's <video> tag on mobile browsers is render blocking

We are using tag for acting as an animated GIF replacement on our website(ucraft.com).
On the top screen of the page there is a background image, on which we have text and a call to action button.
After that there is another block of content, where we have a video on the left and text on the right...
After that block there are 2 other blocks with the same scenario: tag and text.
On mobile(iOS and Chrome) the browser is waiting for the videos to autoplay, after which ONLY it shows the background image in the first(top) screen.
Thus Lighthouse is giving an issue that the rendering is not really well organized.
From the other hand, the UX on the website is bad, because the users don't really understand what to do, as the image is not being loaded(which is important) until the ALL videos of the page is loaded.
Due to this, Google's pagespeed gives us a grade of 30 for mobile, but 90 for desktop.
Please see the pagespeed result here: https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fwww.ucraft.com
Or you may also open the homepage on your device and see...
Here is the code we are using for the video:
<video class="lazy" width="100%" height="100%" webkit-playsinline="true" autoplay muted playsinline="true" data-status="loaded" loop>
<source data-src="https://storage.googleapis.com/ucraft.com/videos/domain-homepage.mp4">
<source data-src="https://storage.googleapis.com/ucraft.com/videos/domain-homepage.webm">
</video>
And this code, that we are putting into the to lazyload the video:
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function() {
var lazyVideos = [].slice.call(document.querySelectorAll("video.lazy"));
lazyVideos.forEach(function(video){
for (var source in video.children) {
var videoSource = video.children[source];
if (typeof videoSource.tagName === "string" && videoSource.tagName === "SOURCE") {
videoSource.src = videoSource.dataset.src;
}
}
video.load();
video.classList.remove("lazy");
});
});
</script>
Are we missing anything to tell browser to load everything, including the tag and to show the poster, before the video is ready to play?
Firstly, you should be using a background color, a background image, and then your video, in that order. Users shouldn't have to wait for an image nor a video to be able to see some text.
Next, stop lazy-loading your video! The browser already does a pretty good job of deferring video loads. It's not your responsibility to change that.
Finally, there is no poster on your video. Not sure if you intended to use one there or not, but since you mentioned it in your question, I thought I'd point it out.

Why is an HTML video tag displaying the video upside down only in Mozilla Firefox?

I have a page that displays multiple videos using html video tags. The code looks like the below snippet:
<video controls="controls" class="vw" name="Video" src="videos/ACS_Video_2b.mp4"></video>
The class is simply a class that dynamically sets the width, height, etc.
The video looks and plays very nicely in all browsers except for Firefox. All of the videos on the website using these tags are upside down in Firefox. I can't seem to find anything online about people having similar problems. In fact, when I go to other websites using identical video tags and video extensions, etc., the video displays perfectly on their site for me in Firefox.
Here is the website with the upside down videos for reference:
http://www.larrykrannich.com/video.html
The videos display upside down locally, on a local server, and hosted on a real server.
Any help would be greatly appreciated.
This is a firefox problem, I have seen that several people have complained over and over about this problem but all to no avail. it only happens when the video is recorded from mobile, firefox doesn't seem to use the camera details to encoded rotation that came along with the mobile video. for the main time you have to figure out a fix for yourself, you can use css transform to rotate the video tag, but one problem with that is that it will rotate the video control with it.
you can use videojs, then add the rotate plugin, you can just google it. it will help rotate for video.
you can do something like this
if ( isfirefox ) {
<video class="video-js vjs-default-skin" controls preload="auto" width="270" height="360" data-setup='{ "plugins": { "zoomoomrotate": { "rotate": "270", "zoom": "1.4" } } }'>
<source src="video-source" type="video/mp4">
</video>
}
also, there is a recent issue in chrome update that compress mobile video as well. still looking for a fix for it
It seems to have something to do with rotation metadata in the video files. The problem can be solved by transcoding and rotating the video. Similar post here
Most likely, you have recorded the video upside down, without realizing it - which can happen, e.g. when using a smartphone-camera.
There are video-players, that auto-correct for such things, which might be, why you didn't realize the video being upside-down.
There is a free Videoplayer called VLC, which you can correct this with by rotating the video.
Get it here and install it, if you don't already have it:
http://www.videolan.org/vlc/
Steps:
Open video in VLC media player
Pause the video, if it's too short to keep running, while you perform the other steps
In the upper menu, navigate as follows:
Tools
Video Effects
In the window, that just opened go to the Geometry-tab and do the following:
Check the box "Transform"
Select "Rotate by 180 degrees"
Your video should now look nice and right side up
To save your changes:
In the upper menu click, navigate as follows:
Media
Convert/Save
Choose, where you want to save the file.
Upload the rotated video in place of the upside-down one.
Now your video should be displayed correctly :)

HTML5 video. How to start only when clicking on a small static image?

I'd like to be able to click on a small thumbnail image and have a video start playing in the full size. This is similar to one using a small image that one clicks on to show the full image.
I am using this code for the video
<video src="my_movie.ogg" controls>
Your browser does not support the <code>video</code> element.
</video>
Is there a way to set this, similar to youtube, where the there is a small image and clicking on it starts the full size movie, and similar to http://www.reddit.com/r/videos/ ?
If I do
<video src="my_movie.ogg" controls width=100px height=100px>
</video>
Then the movie stays too small to see when clicking on it. It would be nice if there are an initial width and run time width to use. But there is not.
Is it possible to also open the movie in a separate pop-up window instead of a new html page? This way the original web page remains in view?
ps. it will be really nice, if the first frame of the movie is displayed as the small image to click on to run the movie, so that I do not have a to make a thumbnail image of each movie to use as the image.
The reason I want to do this, is that the space I have on the page is small and I wanted to put few movies in one row of a table, hence need the sizes to be small initially.
To Chris:
I've used your updated code. This is what happens: Using IE and Chrome, when I click on the images, nothing happens. However, when right-clicking, I see now a menu that has "PLAY" on it. When selecting this, the movie does play. But it only plays in the small size, not the large size.
When I tried my own .ogv file, converted to HTML video from mp4 using online service, the same thing happens. When I click on the image, nothing happens. When I right-click, and select PLAY, it plays. But still using the small size.
Here is the code I used. Which is your code, I just changed the name of the movie to use mine in this one so I can try firefox.
It seems HTML5 video is still not ready for prime time? How to make it work like with u-tube? Click on small image, opens the large size movie in separate window (it will be nice to have a pop-up window for this) but first it has to work in the same web page, which it does not so far.
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<script>
window.onload = function() {
var videos = document.querySelectorAll(".thumbnail");
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener('click', clickHandler, false);
};
function clickHandler(el) {
var mainVideo = document.getElementById("mainVideo");
mainVideo.src = el.srcElement.currentSrc;
}
</script>
<video id="mainVideo" autoplay></video><br/>
<video class="thumbnail" width=150 height=150>
<source src="movie.ogv">
</video>
</body>
</html>
You can go about this many different ways. However, I focused on one part of your question, which was that you thought it might be nice to NOT have to make thumbnail images of each movie.
In order to get that, you have to rely on the HTML5 video tag grabbing the first frame for you. I actually don't recommend you go this route overall, but I wanted to show you how you can accomplish it.
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<script>
window.onload = function() {
var videos = document.querySelectorAll(".thumbnail");
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener('click', clickHandler, false);
};
function clickHandler(el) {
var mainVideo = document.getElementById("mainVideo");
mainVideo.src = el.srcElement.currentSrc;
}
</script>
<video id="mainVideo" width=320 height=240 autoplay></video><br/>
<video class="thumbnail" width=100 height=100>
<source src="http://html5demos.com/assets/dizzy.mp4" type="video/mp4">
</video>
<video class="thumbnail" width=100 height=100>
<source src="http://techslides.com/demos/sample-videos/small.mp4" type="video/mp4">
</video>
</body>
</html>
You can also test it out here: http://jsfiddle.net/E4uDB/
(FYI: these are mp4s so IE and Chrome work, Firefox does not)
There is work to do with this approach. For one thing, you are asking the page to load videos just to make thumbnails. This is pretty bad as the user has to download the videos just to get a feature you can accomplish server side (at processing time).
You then load the video on the fly into a waiting "main window" which might cause another download, not to mention that this sample does nothing to make sure the video is loaded (which you can do, but I think this sample demonstrated enough of the point) to avoid bad user experience.
I don't recommend this because the better approach is to create image thumbnails in some kind of processing task and link up their image click events to load and play the desired video. You get the gist of how you can direct the video element to load and play a new source from my sample, but it certainly isn't trying to be production ready code.
I would strongly consider developing a server side processing task to create image thumbnails, so you can build a better player and one that doesn't make the browser download ALL of the videos just to make image thumbnails.
Another sample: http://cellbycell.com/files/quickwebsamples/Videothumbnails/videochooser.html
Click on an image and it will open and play the desired video in a new browser window.
The trick to this is that the chooser wires a click event to the images, then it uses the id of the images to pass in a query string variable to the player page. That page picks up the query string and plays the video of your choice. View source on both pages, but some highlights are:
The chooser page:
<script>
window.onload = function() {
var videos = document.querySelectorAll(".thumbnail");
for (var i = 0; i < videos.length; i++) {
videos[i].addEventListener('click', clickHandler, false);
};
}
function clickHandler(el) {
window.open("http://cellbycell.com/files/QuickWebSamples/VideoThumbnails/VideoPlayer.html?Video=" + el.target.id);
}
</script>
Select your video<br/>
<img id="Tool" class="thumbnail" src="http://cellbycell.com/files/QuickWebSamples/VideoThumbnails/Tool.png">
<img id = "Cat" class="thumbnail" src="http://cellbycell.com/files/QuickWebSamples/VideoThumbnails/Cat.png">
The target player page:
<script>
window.onload = function() {
var videoPlayer = document.getElementById("videoPlayer");
var videoId = queryObj()["Video"];
switch(videoId)
{
case "Tool":
videoPlayer.src="http://techslides.com/demos/sample-videos/small.mp4";
break;
case "Cat":
videoPlayer.src="http://html5demos.com/assets/dizzy.mp4";
break;
}
}
function queryObj() {
var result = {}, keyValuePairs = location.search.slice(1).split('&');
keyValuePairs.forEach(function(keyValuePair) {
keyValuePair = keyValuePair.split('=');
result[keyValuePair[0]] = keyValuePair[1] || '';
});
return result;
}
</script>
Enjoy your video!<br/>
<video id="videoPlayer" autoplay controls></video>
No matter what you decide to do, you have some work ahead of you. I strongly suggest you look for some of the JavaScript video player libraries out there as well. I think it's good to stand on the shoulders of those who've been working at it already.
Start with html5 poster attribute to see if it solves your purpose. Else if you want to expand the video inline, change it's CSS. If you want to expand and play in a popup, try some video popup libs like VLightBox

HTML5 video play button not working in Firefox

When I click the play button, it just goes to the end of the timeline. But if you drag the ticker somewhere in the middle (or anywhere really) it plays the video. So why won't it play initially?
It works in every other browser other than firefox. Im using Firefox 17
I appreciate the help. Thanks.
heres the link
http://www.lonestarveincenter.com/
Sorry for the necromancy but I found the answer to this problem.
The reason why your onClick() event isn't working is because Firefox has it's own onCLick event added to each video element hence whenever you click the video the video starts playing then instantly stops.
function playPause() {
'Before this event is fired the FF onClick event is fired'
player = document.getElementById("PlayerID")
var playBtn = document.getElementById('<%= img.ClientID %>');
if (!player.paused) { 'Player is playing and will go through this code block'
playBtn.setAttribute('Style', 'display: block;');
player.pause();
}
else { 'Player is playing and will skip this code block'
playBtn.setAttribute('Style', 'display: none;');
player.play();
}
}
One very quick test of changing the <source>'s of your video to those on the HTML5 Video site by W3 School's http://www.w3schools.com/html/html5_video.asp shows the desired behaviour: click play and the video starts from the beginning.
I suggest you try re-encoding your video, and testing locally.
How are you encoding at the moment?
I was having the exact same issue. I was using WebM video, and it would play fine - after you picked a spot on the timeline. I converted to .ogv, put it as the first option in the HTML above WebM and mp4, and it is working great in Firefox, and all the other major browsers.

HTML5 Multiple Video Display - Hover Over to Play

Okay so I have followed a good tutorial regarding embedding videos via HTML5 video tag, which can be found here. Basically the idea is that on hover the video plays, on hover out it stops playing.
Well, I've been trying to include multiple videos on one page (all the same video, mind you) in hopes that I could create a sort of interactive multi-tiled board of sorts. In other words, you hover over each video, it creates varying images based on where in each video you end up, etc.
Whatever, the question I am asking is: based on this tutorial that I've followed, what is the best way to create multiple, tiled videos? I'll paste the code I've been working with. The problem I'm having is that if I create multiple javascript functions, it shows only the video of the last function I've created, rather than all videos.
I hope this makes sense. Here is the link to what I've been working on so far. NOTE: the video takes a while to load, so until then it will play the sound but no image.
Thanks in advance for any help!
Here is the solution I found:
The only warning I give you is to set the videos to preload="none" because if they all load it will be nightmare on your bandwidth. I had to switch mine and now I am looking for a solution to let people know a video is loading.
var vid = document.getElementsByTagName("video");
[].forEach.call(vid, function (item) {
item.addEventListener('mouseover', hoverVideo, false);
item.addEventListener('mouseout', hideVideo, false);
});
function hoverVideo(e)
{
this.play();
}
function hideVideo(e)
{
this.pause();
}
Here is where I got the answer: http://www.dreamincode.net/forums/topic/281583-video-plays-on-mouse-over-but-not-with-multiple-videos/
For anyone that's looking to achieve this using jQuery, here's a solution that I use for dynamically loaded content:
//play video on hover
$(document).on('mouseover', 'video', function() {
$(this).get(0).play();
});
//pause video on mouse leave
$(document).on('mouseleave', 'video', function() {
$(this).get(0).pause();
});
This can be used for a page with 1 - N videos, and only the hovered video will play at each time, while each will pause on the current frame on mouseleave.
Here's an example of it in action: http://jsfiddle.net/cc7w0pda/
Try this, it's easy to understand
<!DOCTYPE html>
<html>
<video id="vv" width="500" height="500" controls onmouseout="this.pause()" onmouseover="this.play()">
<source src="xx.mp4">
Your browser does not support this file
</video>
</html>