Audio continues after removing <video> element in Chrome - html

I am having issues with video support in Chrome. My web page must run in Chrome and I am using the following code to check periodically if the web page has to play a video or not... but the problem is that after I remove the element, I still hear the audio and when I recreate the eleemnt, the audio of the new video and the old overlaps.
function showVideo() {
var video = videodata;
var videobox = $('#videobox').first();
var videoplayer = $('#videoplayer').first();
if (video.Enabled) {
if ((videoplayer.length > 0 && videoplayer[0].currentSrc != video.Location) || videoplayer.length == 0) {
videobox.empty();
videobox.append('<video id="videoplayer" preload="auto" src="' + video.Location + '" width="100%" height="100%" autoplay="autoplay" loop="loop" />');
videobox.show();
}
} else {
videobox.hide();
videobox.empty(); // Clear any children.
}
}
How can I solve?
Thank you.

The following was the minimum I had to go to get this to work. I was actually experiencing a stall due to the buffering while spawning ajax requests when the user pressed the back button. Pausing the video in Chrome and the Android browser kept it buffering. The non-async ajax request would get stuck waiting for the buffering to finish, which it never would.
Binding this to the beforepagehide event fixed it.
$("#SOME_JQM_PAGE").live("pagebeforehide", function(event)
{
$("video").each(function ()
{
logger.debug("PAUSE VIDEO");
this.pause();
this.src = "";
});
});
This will clear every video tag on the page.

firsly try to create "video" tag empty in the html and create "source" tag into javascript code
<html>
.
.
<video id="main-video" autoplay=""></video>
.
.
</html>
<script>
$('#main-video').append('<source type="video/mp4" src="URL.mp4">');
</script>

In my case, I had to pause the video first before removing it otherwise the audio is still playing in the background. The reason I used pause is because there is no stop() function on html5 video element.
} else {
videobox.hide();
// you can add something like this
$("#videoplayer").pause();
videobox.empty(); // Clear any children.
}

try (based on SimpleCode's answer):
function showVideo() {
var video = videodata;
var videobox = $('#videobox').first();
var videoplayer = $('#videoplayer').first();
if (video.Enabled) {
if ((videoplayer.length > 0 && videoplayer[0].currentSrc != video.Location) || videoplayer.length == 0) {
videobox.empty();
videobox.append('<video id="videoplayer" preload="auto" src="' + video.Location + '" width="100%" height="100%" loop="loop" />');
videobox.show();
document.getElementById("videoplayer").play();
}
} else {
document.getElementById("videoplayer").pause();
videobox.hide();
videobox.empty(); // Clear any children.
}
}

Related

How to play an audio file in the background after clicking a link? (no embed)

Currently I am using following code to play some audio after a link is clicked:
Pronunciation of a word
For now if the user clicks on the link, a new page with an audio playing panel is loaded. After playing the audio, the user has to click GO BACK button of the browser to get back to the original content.
Is it possible to play the audio without being directed to a new page? When the user clicks on the link, the audio just plays in the background?
(Don't want to use embed because it's just a 1 second audio for a word's pronunciation as a minor explanation of an uncommon word).
Actually the href attribute is redirecting you to the new page, you can use e.prevenDefault() in the link click event handler to stop this redirection and create a dynamic audio element with this href as source and play it.
This is what you need:
function playItHere(e, link) {
var audio = document.createElement("audio");
var src = document.createElement("source");
src.src = link.href;
audio.appendChild(src);
audio.play();
e.preventDefault();
}
Pronunciation of a word
In html5, you can actually use the <audio> tag to get that done!
<audio src="/music/myaudio.ogg" autoplay> Sorry, your browser does not support the <audio> element. </audio>
SOURCE: Wired
If you use a tag be careful with href .
Code snippet fixed .
First you will need to make convert ogg to the mp3 and than use it for multi source .
Small browser detector (chrome/opera/safari - mp3 and mozilla - ogg . )
E("PLAYER").addEventListener("error", function(e) {
console.log("error: " + e.target.error)
});
function PLAYER_BACKGROUND(what) {
var SOURCE_PATH = E(what).getAttribute("whattoplay")
if (isChrome == true)
{
SOURCE_PATH = SOURCE_PATH.replace(".ogg" , ".mp3")
}
else {
SOURCE_PATH = SOURCE_PATH.replace( ".mp3" , ".ogg" )
}
E("PLAYER").src = SOURCE_PATH
E("PLAYER").play()
}
<script>
var E = function(id){return document.getElementById(id)};
var isChrome = /Chrome/.test(navigator.userAgent) || /Safari/.test(navigator.userAgent);
</script>
<a id="audio_1" onclick="PLAYER_BACKGROUND(this.id)" whattoplay="https://maximumroulette.com/framework/res/audio/laser7.ogg" href="javascript:void(0)">Pronunciation of a word</a>
<audio style="display:none" id="PLAYER" autoplay controls>
<source src="#" type="audio/ogg">
<source src="#" type="audio/mpeg">
Sorry, your browser does not support the element.
</audio>

Html video should stop at first frame

I have a .mp4 video in my html page. I applied autoplay to that video, it stops at ending frame. My concern here is this video should come back at first frame once the video playing done. Can anybody please suggest what should i do to do this. Thanks
If you just want the video to loop and start again you can use the 'loop' attribute:
<video controls loop>
<source src="yourVideo.mp4" type="video/mp4">
...
</video>
If you want to detect the end of the video and do something else, like restart the video you can use the end of video event in JavaScript:
$("#yourVideo").on("ended", function() {
//Add whatever you want to do when the video ends here
video.pause();
video.currentTime = 0;
video.play(); //You may not need this - experiment on different browsers
video.pause();
});
Must include js file I am using CDN
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type='text/javascript'>
$(document).ready(function () {
document.getElementById('Sample').addEventListener('ended',myHandler,false);
function myHandler(e) {
var video =document.getElementById('Sample');
video.currentTime = 0;
video.pause();
}
});
</script>
HTML
<video src="video.mp4" id="Sample" autoplay>
video not supported
</video>
By javascript and assuming that you know the framerate of your video:
function goFirstFrame () {
var video = document.getElementById('videoId');
var frameTime = 1/25; // If your video is 25fps
video.currentTime = 0 + frameTime;
video.pause();
}

HTML5 video fallback when all types unsupported

In the HTML5 spec, it suggests you put fallback material in the <video> tag for older browsers that do not support it.
<video width="400" controls>
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg">
Your browser does not support HTML5 video.
</video>
However, I cannot find anything for fallbacks when all source types are unsupported. For instance, my Chromium browser cannot play video/mp4, but it can play video/ogg. So I would expect this to render the fallback text.
<video width="400" controls>
<source src="mov_bbb.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
Instead, I just get a video player with nothing in it because it can't load the mp4 file.
Is there a way to have a fallback in HTML 5 video when there is no usable video source? I am aware that the fallback I was attempting is only for old browsers, but I still need a fallback for no available source.
Actually, when you try to load unsupported media types in <source> element, an error event will fire.
You could then listen to these events, and if none of the sources is recognized, trigger the fallback :
var sources = document.querySelectorAll('source');
var source_errors = 0;
for (var i = 0; i < sources.length; i++) {
sources[i].addEventListener('error', function(e) {
if (++source_errors >= sources.length)
fallBack();
});
}
function fallBack() {
document.body.removeChild(document.querySelector('video'));
document.body.appendChild(document.createTextNode('No video with supported media and MIME type found'));
}
<video controls>
<source src="foo.bar" type="video/foo" />
<source src="bar.foo" type="video/bar" />
</video>
It's mentioned in the specs a way to fallback.
"listen to the error event on the last source element and trigger fallback behavior"
<div>
<video width="400" controls>
<source src="mov_bbb.mp4" type="video/mp4">
<source src="mov_bbb.ogg" type="video/ogg"
onerror="parentNode.parentElement.innerText = 'Your browser does not support the video codec' ">
</video>
</div>
There's no HTML behaviour for this, so we'll have to add our own behaviour with JavaScript.
(function() {
"use strict";
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function setVideoFallback(lazyArea) {
var lowData = false;
if ("connection" in navigator) {
lowData = navigator.connection.saveData === true ||
navigator.connection.effectiveType === "slow-2g" ||
navigator.connection.effectiveType === "2g";
}
//DocumentFragments don't support getElementsByTagName
//oldIE doesn't support querySelectorAll
var lazyVideos = lazyArea.querySelectorAll ?
lazyArea.querySelectorAll("video") :
lazyArea.getElementsByTagName("video");
for (var i = lazyVideos.length; i--;) {
var lazyVideo = lazyVideos[i];
var cantPlay = true;
if (lazyVideo.canPlayType) {
//Loop through the various source elements, and check if
//the browser thinks it can play them
//This works better if we specify the codec along with
//the MIME type
var sources = lazyVideo.getElementsByTagName("source");
for (var i2 = sources.length; i2--;) {
if (lazyVideo.canPlayType(sources[i2].type)) {
cantPlay = false;
break;
}
}
}
//If on a low-data connection, remove the autoplay attribute
//(it's only polite)
if (lowData) {
lazyVideo.removeAttribute("autoplay");
lazyVideo.setAttribute("controls", "");
}
//If you can't play any of the available formats, skip straight to fallback content
if (cantPlay) {
//Extract the fallback and replace the video with it
var children = lazyVideo.childNodes;
for (var i3 = children.length; i3--;) {
var childNode = children[i3];
if (childNode.tagName !== "TRACK" && childNode.tagName !== "SOURCE") {
insertAfter(childNode, lazyVideo);
}
}
lazyVideo.parentNode.removeChild(lazyVideo);
}
}
}
/**
* Retrieve the elements from the 'lazy load' noscript tags and prepare them for display
*/
function setUp() {
//Get all the noscript tags on the page
var lazyLoadAreas = document.getElementsByTagName("noscript");
var supportsTemplates = typeof HTMLTemplateElement === "function";
for (var i = lazyLoadAreas.length; i--;) {
var noScriptTag = lazyLoadAreas[i];
//only process the ones marked for lazy loading
if (!noScriptTag.hasAttribute("data-lazy-load")) continue;
// The contents of a noscript tag are treated as text to JavaScript
var lazyAreaHtml = noScriptTag.textContent || noScriptTag.innerHTML;
// So we stick them in the innerHTML of a new div tag to 'load' them
var lazyArea;
if (supportsTemplates) {
//(if possible, templates are better as they won't start any network calls)
var lazyTemplate = document.createElement("template");
lazyTemplate.innerHTML = lazyAreaHtml;
lazyArea = lazyTemplate.content;
} else {
lazyArea = document.createElement("div");
lazyArea.innerHTML = lazyAreaHtml;
}
setVideoFallback(lazyArea);
noScriptTag.parentNode.replaceChild(lazyArea, noScriptTag);
}
}
//If the page has loaded already, run setup - if it hasn't, run as soon as it has.
if (document.readyState !== "loading") {
setUp();
} else {
document.addEventListener("DOMContentLoaded", setUp);
}
})();
<main>
<figure>
<!--[if !IE]><!-->
<noscript data-lazy-load>
<video height="338" width="600" autoplay loop muted>
<!--<source src="./Sample.mp4" type="video/mp4; codecs=avc1.42E01E,mp4a.40.2">-->
<source src="http://dl3.webmfiles.org/big-buck-bunny_trailer.webm" type="video/webm; codecs=vp8,vorbis">
<source src="https://upload.wikimedia.org/wikipedia/commons/0/07/Backgammon_example.ogv" type="video/ogg; codecs=theora,vorbis">
<!--<![endif]-->
<img src="https://media2.giphy.com/media/BfbUe877N4xsUhpcPc/giphy.gif?cid=790b76115cadcffa59306b73776453f3" height="360" width="480"/>
<!--[if !IE]><!-->
</video>
</noscript>
<!--<![endif]-->
<figcaption>
A bunny emerging from his den and stretching.
<!--[if !IE]><!-->
<noscript aria-hidden="true"><p>
Note: Without JavaScript, the above animation might not play. In that case, the animation can be directly accessed
here.
</p></noscript>
<!--<![endif]-->
</figcaption>
</figure>
</main>
Using the canPlayType function, we ask the browser if it thinks it can play any of the source types. If it doesn't, we pull out the fallback content.
We encase the video in noscript tags so that it won't start loading until we've run the script (unless scripting is disabled, which is the desired behaviour).
We also use IE conditional tags, because oldIE can't read the contents of noscript tags with script.
(Tested with Edge, Firefox, Chrome, and every compatibility mode IE has. The Webm shows in all browers bar IE, which shows the GIF in every compatibility mode.)
#Jaw.sh There's two fallback options that are commonly in use.
Fallback to Flash version of the video.
Fallback to a direct download of the video.
Today's browsers (Opera I'm not sure and not really concerned), are all capable of playing MP4 H.264. So you shouldn't worry too much about incompatibilities, unless most of your viewers live in China.

Hide Video Controls Until User Hover Over Video

i'm trying to hide the video controls on my video, until the user hover over the video, then the controls shows up. Any idea or advice? Thanks. And I've got more than one video.
HTML:
<div class="item spoon burger"><video width="300" height="auto" controls><source src="videos/sruthi.mp4" type="video/mp4"></video></div>
We can accomplish this through just a couple lines of jQuery, making use of .hover():
Working Example
$('#myvideo').hover(function toggleControls() {
if (video.hasAttribute("controls")) {
video.removeAttribute("controls")
} else {
video.setAttribute("controls", "controls")
}
})
Edit I mistakenly left the variable video in the code above. I changed it to this so that you won't have to manage variables that grab an ID.
$('#myvideo').hover(function toggleControls() {
if (this.hasAttribute("controls")) {
this.removeAttribute("controls")
} else {
this.setAttribute("controls", "controls")
}
})
HTML
<video width="300" height="auto" id="myvideo">
<source src="#" type="video/mp4" />
</video>
Update:
You mentioned that you have several videos. So you can use this same logic, and just add additional selectors into $( ). Here's an example:
$('#yourID1, #yourID2, #yourID3').hover(function toggleControls() { ...
Doing that will listen or wait until it detects that you're hovering over one of those IDs.
Updated fiddle
One issue with #EnigmaRM's answer is that if jQuery somehow misses a hover event, the controls can be toggled the "wrong" way - that is, they disappear on mouse enter and reappear on mouse leave.
Instead, we can ensure that the controls always appear and disappear correctly with event.type:
$("#myvideo").hover(function(event) {
if(event.type === "mouseenter") {
$(this).attr("controls", "");
} else if(event.type === "mouseleave") {
$(this).removeAttr("controls");
}
});
Untested, but I believe this would work. It uses JavaScript instead of CSS.
<div class="item spoon burger"><video id="videoElement" width="300" height="auto"><source src="videos/sruthi.mp4" type="video/mp4"></video></div>
<script type="text/javascript">
(function(window) {
function setupVideo()
{
var v = document.getElementById('videoElement');
v.addEventListener('mouseover', function() { this.controls = true; }, false);
v.addEventListener('mouseout', function() { this.controls = false; }, false);
}
window.addEventListener('load', setupVideo, false);
})(window);
</script>
<script>
function setupVideos() {
for (const video of document.querySelectorAll('video')) {
video.controls = false
video.addEventListener('mouseover', () => { video.controls = 'controls' })
video.addEventListener('mouseout', () => { video.controls = false })
}
}
window.addEventListener('load', setupVideos, false)
</script>
Using the code below, you don't need a separate javascript section (if that is a concern, which is the case sometimes). Just simply use onmouseover="this.play();this.setAttribute('controls','controls')" and onmouseout="this.load();this.removeAttribute('controls')"
If you don't want it to reset to a poster image, then you can get rid of the this.load.
<div class="img_placeholder">
<video width="350" height="250" loop preload="none" poster="../assets/icon-32.png" onmouseover="this.play();this.setAttribute('controls','controls')" onmouseout="this.load();this.removeAttribute('controls')">
<source src="../assets/bear.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>
</div>
A previous post explained how to do it this way HTML5 video - show/hide controls programmatically
<video id="myvideo">
<source src="path/to/movie.mp4" />
</video>
<p onclick="toggleControls();">Toggle</p>
<script>
var video = document.getElementById("myvideo");
function toggleControls() {
if (video.hasAttribute("controls")) {
video.removeAttribute("controls")
} else {
video.setAttribute("controls","controls")
}
}
</script>
Check if their solution works for you! Please +1 them if so!

HTML5 video onended event firing once

I am really stumped on this one.
I am trying to use the html5 video player and javascript in safari. I want to
1 play a greeting video
2 play a default looping video while the user makes a selection
3 play user selection
4 return to the default looping video.
1, 2, 3 work but 4 does not.
I call the greeting video from the body
<video id="videok" width=400 height=400 autoplay="autoplay" src="sacagreeting.mov" >
video not supported
</video>
I set my event listener up in the body
body onload="myAddListener()"
function myAddListener(){
var myVideo = document.getElementsByTagName('video')[0];
myVideo.addEventListener('ended',myNewSrc,false);
}
my function to play the looping default video is
function myNewSrc() {
myVideo = document.getElementsByTagName('video')[0];
myVideo.src="sacarest.mov";
myVideo.loop="loop";
myVideo.load();
myVideo.play();
}
I use an select element for the user to pick a video and the onchange event to call my video function
function myNewSrcii() {
myVideo = document.getElementById('videok');
myVideo.loop=""
myquest = document.getElementById('vidquest').value;
switch(myquest)
{
case "a":
myVideo.src="sacaa.mov";
break;
case "b":
myVideo.src="sacab.mov";
break;
case "c":
myVideo.src="sacac.mov";
break;
case "d":
myVideo.src="sacad.mov";
break;
case "e":
myVideo.src="sacae.mov";
break;
case "f":
myVideo.src="sacaf.mov";
}
myVideo.load();
myVideo.play();
}
I have tried dropping the looping attribute, setting the event listener again in the myNewSrcii function, using an onended event in the video tag and no luck. When I check the video event ended is true, the listener however never calls my default video function. Any help would be greatly apprectiated.
thanks
This is due to a strange bug in Safari's HTML5 video tag implementation. It can be reproduced on Safari for Windows as well. I've just found one workaround for this problem - just bind to loadedmetadata event and set the currentTime to some non-zero value. Here is an example:
<!doctype html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
</head>
<body>
<video id="video" width="500" height="400" controls autoplay></video>
<script>
var src = [
"http://content.adfox.ru/131007/adfox/205544/865991_11.mp4",
"http://all.rutube.ru/130627/gpmdigital/217059/805529_11.mp4"
];
var curSrc = 0;
$(function() {
$('#video').attr("src", src[curSrc % src.length]);
curSrc++;
var video = $('#video').get(0);
$('#video')
.on('loadedmetadata', function() {
video.currentTime=0.01;
video.play();
})
.on('ended', function() {
console.log('ended');
video.src = src[curSrc % src.length];
video.load();
curSrc++;
});
});
</script>
</body>
</html>
You can try this demo in this jsfiddle: http://jsfiddle.net/j2knz6sv/