6

I'am wondering if there's a way to display a .gif while the video is buffering.

I'am using the HTML5 Video Tag, within this is there a way to detect when a video is buffering, if not is there an alternative?

I've looked at:

How to detect when video is buffering?

However I don't think this would help me out.. as I have no clue what NetStream is or what actionscript-3 is.

html:

<div id="popup-box" class="popupInfo">

            <img src="button/loading.gif" id="loadingGif" />

            <video src="fragmenten/real_schade.mp4" controls="controls" preload="auto" id="video" onclick="this.play();">

                    Your browser doesn't support the video element.

            </video>

            <p class="buttons">
                <a href="http://www.reaal.nl/verzekering/autoverzekering/#routechecker" target="_blank" id="place_Holder" class="button btn1">Meer informatie</a>
                <a href="http://www.reaal.nl/verzekering/autoverzekering/#basisdekking"  target="_blank" id="place_Holder1" class="button licht hoverbtn2">Direct afsluiten</a>
            </p>

            <img src="button/sluit.png" class="close">

        </div>
Community
  • 1
  • 1
Gerwin
  • 1,572
  • 5
  • 23
  • 51
  • 1
    Try this post on SO: http://stackoverflow.com/questions/8230748/how-to-add-loader-image-to-html5-video there are HTML and JavaScript examples throughout. – Landern Nov 05 '14 at 14:51
  • 1
    You probably want to hook the `stalled` event, although it may vary from browser to browser. See [this answer](http://stackoverflow.com/a/26546060/102937) and [this excellent Fiddle](http://jsfiddle.net/jamie_505/9fxz4eup/2/). – Robert Harvey Nov 05 '14 at 14:56
  • @RobertHarvey The code however doesn't seem to work, it doesn't change the poster attribute to display the poster – Gerwin Nov 05 '14 at 15:06
  • 1
    It doesn't do what? Seems like it plays the video, and all the controls work. It's not a drop-in; you'll have to fiddle with it (pun intended). – Robert Harvey Nov 05 '14 at 15:09
  • I've changed the code accordingly to change the poster attribute to what I need it to display, but it only fires the even to display the video when the video source is being loaded in, not when buffering – Gerwin Nov 05 '14 at 15:10
  • 1
    afaik, the poster only get's displayed while the video is being downloaded and hasn't been started yet but not on buffering – Markai Nov 05 '14 at 15:20
  • This is correct, I can confirm this.. however I would like the poster to be displayed while buffering is there any way to do that? – Gerwin Nov 05 '14 at 15:23

2 Answers2

14

You can use the onwaiting event handler on the video element to show an image when the video starts buffering and the onplaying event handler when the video resumes (compare video element events)

video.onwaiting = function(){
    showPlaceholder(placeholder, this);
};
video.onplaying = function(){
    hidePlaceholder(placeholder, this);
};

I created a little fiddle where you can get an idea of how to do it (Note that i simulated the buffering after 1 second by code).

Markai
  • 2,098
  • 1
  • 10
  • 15
  • Thank you, it now shows the placeholder when the video is buffering, but the area around it collapses in on itself because the video dissapears.. I'll attempt to fix it, +1 for showing the placeholder, if I get it to work i'll accept your answer – Gerwin Nov 05 '14 at 16:02
  • 1
    You can use vid.style.opacity = "0"; instead of vid.style.display = "none"; and vid.style.opacity = "1"; instead of vid.style.display = "block"; Then the video keeps on allocating the space – Markai Nov 05 '14 at 16:05
  • it works perfectly, thank you sir! I shall accept your answer! – Gerwin Nov 05 '14 at 16:18
  • 1
    Happy to help :) I used a div with a background, so you can add a button for example if you want the user to do something like stopping the video or something similar while it is buffering – Markai Nov 05 '14 at 16:19
  • Cool, thank you, I have a question and was wondering if you could help out, there are 2 buttons in a frame that comes up when you click somewhere... when you make the video within the frame fullscreen there are black borders around the video for some reason... and the buttons are placed on top of the fullscreen for some reason, do you know why? – Gerwin Nov 06 '14 at 08:06
  • Hello, I've found the solution, if the z-index property is too high it places the buttons over the fullscreen, and I used padding instead of margin for the video, so it made a border around my video based off my screen, thank you though ^^ – Gerwin Nov 06 '14 at 10:34
  • Sir, in Firefox it shows the gif when you click, it makes the video go to opacity 0, this is expected, however it does this when you click on the video, in chrome is just keeps playing as it's supposed to – Gerwin Nov 07 '14 at 10:14
  • Hm, I couldn't refactor that problem, so I can just guess from here: You could try to add an eventhandler for the onclick event of the video that just prevents the default action and if you want some behaviour, adds that. – Markai Nov 07 '14 at 10:18
  • Do you have skype or something we can use to pm? I can send you the link for the website, so that you may take a look? – Gerwin Nov 07 '14 at 10:40
  • 1
    Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/64485/discussion-between-markai-and-gerwin). – Markai Nov 07 '14 at 11:10
  • The problem is that onwaiting gets fired only once during video play. – pratik nagariya Oct 03 '15 at 10:04
1

I know this thread is really old but i was struggling to do this and it took my a good few days to find out how to do this and make it all function correctly so i thought help out for future users who are struggling like i was.

I remade the fiddle above and made it function for more then 1 video and also added a css loader because it will make it faster instead of it having to download a gif. So it now works better and is expandable plus its easier to use. I also removed the delay that was in the previous Js Fiddle that was linked in the post above. All you need to do to expand it is just copy a section of the javascript and change the tags to be unique. Here is my js Jsfiddle

If you wish to use a Gif instead of a css loader do the following:

Change these lines:

<div id="placeholder_1" class="placeholder"><div class="loader">Loading...</div></div>

To this:

<div id="placeholder_1" class="placeholder"><img src="https://i.imgur.com/OirdkJp.gif"></div>

How it works is the Javascript checks if the video is buffering and if it is buffering the javascript will call the this html line <div id="placeholder_1" class="placeholder"> then that html line will call the css loader to display. I didnt make the loader, i got it from Here

To expand do the following:


Copy the code below and change all of these Tags to a unique name. Do the same thing to this line: <div id="placeholder_1" class="placeholder"> Also add a id to your video with the same number you made your js tag for instance: id="video_1"(basically change the 1 to another number) If you are having trouble then read the completed code at the bottom of this post for more help:

Tags:

video_1
placeholder_1

Code:

var video = document.getElementById("video_1");
var placeholder = document.getElementById("placeholder_1");
placeholder_1.style.top = video_1.offsetTop + "px";
placeholder_1.style.left = video_1.offsetLeft + "px";

video_1.onwaiting = function() {
  showPlaceholder(placeholder_1, this);
};
video_1.onplaying = function() {
  hidePlaceholder(placeholder_1, this);
};

function showPlaceholder(img, vid) {
  img.style.height = vid.scrollHeight + "px";
  img.style.width = vid.scrollWidth + "px";
  img.style.display = "block";
}

function hidePlaceholder(img, vid) {
  img.style.display = "none";
}

Here is the completed code:

//Video one.

var video = document.getElementById("video_1");
var placeholder = document.getElementById("placeholder_1");
placeholder_1.style.top = video_1.offsetTop + "px";
placeholder_1.style.left = video_1.offsetLeft + "px";

video_1.onwaiting = function() {
  showPlaceholder(placeholder_1, this);
};
video_1.onplaying = function() {
  hidePlaceholder(placeholder_1, this);
};

function showPlaceholder(img, vid) {
  img.style.height = vid.scrollHeight + "px";
  img.style.width = vid.scrollWidth + "px";
  img.style.display = "block";
}

function hidePlaceholder(img, vid) {
  img.style.display = "none";
}


//Video two.

var video = document.getElementById("video_2");
var placeholder = document.getElementById("placeholder_2");
placeholder_2.style.top = video_2.offsetTop + "px";
placeholder_2.style.left = video_2.offsetLeft + "px";

video_2.onwaiting = function() {
  showPlaceholder(placeholder_2, this);
};
video_2.onplaying = function() {
  hidePlaceholder(placeholder_2, this);
};

function showPlaceholder(img, vid) {
  img.style.height = vid.scrollHeight + "px";
  img.style.width = vid.scrollWidth + "px";
  img.style.display = "block";
}

function hidePlaceholder(img, vid) {
  img.style.display = "none";
}

//Video three,

var video = document.getElementById("video_3");
var placeholder = document.getElementById("placeholder_3");
placeholder_3.style.top = video_3.offsetTop + "px";
placeholder_3.style.left = video_3.offsetLeft + "px";

video_3.onwaiting = function() {
  showPlaceholder(placeholder_3, this);
};
video_3.onplaying = function() {
  hidePlaceholder(placeholder_3, this);
};

function showPlaceholder(img, vid) {
  img.style.height = vid.scrollHeight + "px";
  img.style.width = vid.scrollWidth + "px";
  img.style.display = "block";
}

function hidePlaceholder(img, vid) {
  img.style.display = "none";
}

//Video four.

var video = document.getElementById("video_4");
var placeholder = document.getElementById("placeholder_4");
placeholder_4.style.top = video_4.offsetTop + "px";
placeholder_4.style.left = video_4.offsetLeft + "px";

video_4.onwaiting = function() {
  showPlaceholder(placeholder_4, this);
};
video_4.onplaying = function() {
  hidePlaceholder(placeholder_4, this);
};

function showPlaceholder(img, vid) {
  img.style.height = vid.scrollHeight + "px";
  img.style.width = vid.scrollWidth + "px";
  img.style.display = "block";
}

function hidePlaceholder(img, vid) {
  img.style.display = "none";
}
.placeholder {
  display: none;
  position: absolute;
  background-size: cover;
  text-align: center;
  float: left;
  z-index: 300000;
}

.loader,
.loader:before,
.loader:after {
  background: #ff8000;
  -webkit-animation: load1 1s infinite ease-in-out;
  animation: load1 1s infinite ease-in-out;
  width: 1em;
  height: 4em;
}

.loader {
  color: #ff8000;
  text-indent: -9999em;
  margin: 88px auto;
  position: relative;
  font-size: 11px;
  -webkit-transform: translateZ(0);
  -ms-transform: translateZ(0);
  transform: translateZ(0);
  -webkit-animation-delay: -0.16s;
  animation-delay: -0.16s;
}

.loader:before,
.loader:after {
  position: absolute;
  top: 0;
  content: '';
}

.loader:before {
  left: -1.5em;
  -webkit-animation-delay: -0.32s;
  animation-delay: -0.32s;
}

.loader:after {
  left: 1.5em;
}

@-webkit-keyframes load1 {
  0%,
  80%,
  100% {
    box-shadow: 0 0;
    height: 4em;
  }
  40% {
    box-shadow: 0 -2em;
    height: 5em;
  }
}

@keyframes load1 {
  0%,
  80%,
  100% {
    box-shadow: 0 0;
    height: 4em;
  }
  40% {
    box-shadow: 0 -2em;
    height: 5em;
  }
}
<video id="video_1" controls preload="none">
  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" />
</video>

<div id="placeholder_1" class="placeholder">
  <div class="loader">Loading...</div>
</div>

<video id="video_2" controls preload="none">
  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" />
</video>

<div id="placeholder_2" class="placeholder">
  <div class="loader">Loading...</div>
</div>

<video id="video_3" controls preload="none">
  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" />
</video>

<div id="placeholder_3" class="placeholder">
  <div class="loader">Loading...</div>
</div>

<video id="video_4" controls preload="none">
  <source src="http://www.w3schools.com/html/mov_bbb.mp4" type="video/mp4" />
</video>

<div id="placeholder_4" class="placeholder">
  <div class="loader">Loading...</div>
</div>