I have a HTML5 video element which is showing mp4 video in LoadingController(Ionic framework). My problem is that video is not immediately loaded after loader is shown, I can see the default thumbnail/poster of html5 video element for 0.2s and just after this is video shown. The problem occurs just on Android device, iOS devices are playing video instantly.
Loader initialization code:
var preloaderOptions: object ={
spinner: 'hide',
duration: 2500,
message: `
<div class="custom-spinner-container">
<div class="custom-spinner-box">
<video id="videoPlayer" autoplay muted loop playsinline webkit-playsinline preload="metadata">
<source src="./assets/videos/loader.mp4" type="video/mp4" />
</video>
<p>`+loaderMessages[Math.floor(Math.random()*loaderMessages.length)]+`</p>
</div>
</div>`,
cssClass: 'custom-loading'
};
this.preloaderController.create({...preloaderOptions}).then((preloader) => {
this.preloader = preloader;
preloader.present().then(el => {
let video = this.preloader.getElementsByTagName('video')[0];
video.autoplay= true;
video.playsInline = true;
video.muted = true;
video.loop = true;
video.preload="metadata";
video.webkitPlaysInline = true;
video.play();
});
});
I also tried to place poster image into video markup and typescript, but not helped to get rid of default thumbnail. Preload="auto" wasn't working too.
Thanks for help.
Ok, so I fixed it by adding white poster jpg picture, but the key is to show video just before calling play() method.
this.preloaderController.create({...preloaderOptions}).then((preloader) => {
this.preloader = preloader;
let video = this.preloader.getElementsByTagName('video')[0];
video.style.display = "none";
preloader.present().then(el => {
video.autoplay= true;
video.playsInline = true;
video.muted = true;
video.loop = true;
video.preload="auto";
video.poster = "./assets/images/loader_poster.jpg";
video.style.display = "inline-block";
video.webkitPlaysInline = true;
video.play();
});
});
Related
I am using jquery to load YouTube Video through iframe to reduce the initial page load time. Using this approach – only the video thumbnail is loaded along with the page and the actual player loads when the user hits the play button. But AutoPlay is not working on Android and Iphones though it is perfectly working on desktops using windows. When I googled this problem, it turns out "Chrome and Safari browsers on iPhone and Android only allow playback of HTML5 video when initiated by a user interaction. They block embedded media from automatic playback to prevent unsolicited downloads over cellular networks." I want to autoplay the video. Please help.
Here is my jquery
document.addEventListener("DOMContentLoaded",
function() {
var div, n,
v = document.getElementsByClassName("youtube-player");
for (n = 0; n < v.length; n++) {
div = document.createElement("div");
div.setAttribute("data-id", v[n].dataset.id);
div.innerHTML = YouTubeThumb(v[n].dataset.id);
div.onclick = YouTubeIframe;
v[n].appendChild(div);
}
});
function YouTubeThumb(id) {
var thumb = '<img src="https://i.ytimg.com/vi/ID/mqdefault.jpg">',
play = '<div class="play"></div>';
return thumb.replace("ID", id) + play;
}
function YouTubeIframe() {
var iframe = document.createElement("iframe");
var embed = "https://www.youtube.com/embed/ID?autoplay=1";
iframe.setAttribute("src", embed.replace("ID", this.dataset.id));
iframe.setAttribute("frameborder", "0");
iframe.setAttribute("allowfullscreen", "1");
this.parentNode.replaceChild(iframe, this);
}
and the HTML
<div class="youtube-player" data-id="YouTube_Video_ID"></div>
try this example:-
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
I am using the following code to play HTML5 videos
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script type="text/javascript" id="youtubeplayer">
</script>
<script>
document.getElementById('youtubeplayer').style.width=window.innerWidth;
document.getElementById('youtubeplayer').style.height=window.innerHeight;
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
//videoId: localStorage.getItem('videoid'),
videoId : "8UVNT4wvIGY",
width : Math.abs(window.innerWidth*0.99),
height : Math.abs(window.innerHeight*0.99),
allowFullScreen : true,
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
//setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
Basically I am embedding it in a HTML5 page.
It works very well on Desktop, but on a Android device (Google Nexus 10), it just shows the title of the video and the video doesn't load.
Fitvids plugin worked super well for me and played nicely within the bootstrap framework I was using.
From their github page:
<script src="path/to/jquery.min.js"></script>
<script src="path/to/jquery.fitvids.js"></script>
<script>
$(document).ready(function(){
// Target your .container, .wrapper, .post, etc.
$("#thing-with-videos").fitVids();
});
</script>
Boom done!
It is easy to create a custom play button for an embed YouTube video using their API, however it seems that the button cannot launch the video in mobile environment, especially Android. When you click it there, screen simply goes forever black with ever spinning loading animation.
<div id="wrapper">
<div id="video">
</div>
Play
</div>
<script>
var player, tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.onYouTubeIframeAPIReady = function() {
player = new YT.Player('video', {
height: '320',
width: '240',
videoId: '5oxIQe3XngY',
playerVars: {
modestbranding: 1,
controls: 0,
rel: 0
}
});
player.addEventListener('onReady', function(e) {
document.getElementById('play').onclick = function() {
player.playVideo();
};
});
player.addEventListener('onStateChange', function(e) {
if (e.data == 1) {
document.getElementById('play').style.display = 'none';
}
});
};
</script>
Here's the fiddle: http://jsfiddle.net/HArsN/
Any solution to that? Is it necessary to launch the video through bundled button only?
I made a html page ,and put an audio tag in it then I try to use my android browser to play some music .
But it doesn't work. Here is my code:
<audio id='simple-audio-player' src="http://m.html5/baidu.mp3" controls="controls" preload="metadata"></audio>
window.onload = function () {
var au = document.getElementById("simple-audio-player");
au.load();
if(au.networkState != au.NETWORK_NO_SOURCE){
alert('au.networkState != au.NETWORK_NO_SOURCE');
try{
au.play();
}catch(err){
alert(err);
}
}else{
alert('au.networkState == au.NETWORK_NO_SOURCE');
}
};
I think it would be something wrong with my IIS config ,but I not sure.
You can't play audio from the window load event, it has to happen in response to a user interaction.
Like this...
window.addEventListener('ontouchstart', onStart);
function onStart()
{
var audio = new Audio(); // --or-- document.getElementById('id-of-audio-tag');
audio.src = "test.mp3";
audio.play();
}
I am converting some HTML5 to work with Android. Android does not support the element, so the play method does not function.
I am using PhoneGap's media element, and that does play audio. What I want, is a way to find the first source of the audio tag, and then use that with media play, but this does not seem to work.
function playSound(whatToPlay) {
// removed since <audio does not work
// var snd = document.getElementById(whatToPlay);
// snd.play();
toPlaySrc = $("#"+whatToPlay+":first-child").eq(0).attr("src");
// next I will have to deal with /android_asset and my current partial path
myMedia = new Media("/android_asset/"+toPlaySrc, onSuccess,onError);
if (myMedia)
myMedia.play();
}
playSound("clockticking");
this is my audio element.
<audio id="clockticking" preload="auto" autobuffer onEnded="instructionFinsihed()">
<source src="../sound/tictoc.mp3" type="audio/mp3" />
<source src="../sound/tictoc.ogg" type="audio/ogg" />
</audio>
I have many existing audio elements, so a general solution would really be important, I can not, for instance just ad id tags to all the mp3 elements and solve it.
Okay, I'm working on some monkey patch code for the Android WebView, you can see the progress over on my corinthian github project. In the meantime what you'd want to do is setup a on deviceready listener:
document.addEventListener("deviceready", monkeypunch, true);
create an array to hold the media objects:
mediaObjs = [];
and in the monkeypunch method you would do:
function monkeypunch() {
var audioclips = document.getElementsByTagName("audio");
for (var i=0; i < audioclips.length; i++) {
// Create new Media object.
var audioSrc = audioclips[i].firstElementChild.src;
if (audioSrc.indexOf("file:///android_asset") == 0) {
audioSrc = audioSrc.substring(7);
}
mediaObjs[audioSrc] = new Media(audioSrc);
// Create the HTML
var newAudio = document.createElement('div');
var newImg = document.createElement('img');
newImg.setAttribute('src', 'images/play.png');
newAudio.appendChild(newImg);
// Set the onclick listener
newAudio.addEventListener("click", function() {
// figure out what image is displayed
if (newImg.src.indexOf("images/play.png", newImg.src.length - "images/play.png".length) !== -1) {
newImg.src = "images/pause.png";
mediaObjs[audioSrc].play();
} else {
newImg.src = "images/play.png";
mediaObjs[audioSrc].pause();
}
});
// replace the audio tag with out div
audioclips[i].parentNode.replaceChild(newAudio, audioclips[i]);
}
}
You can grab the play/pause images from my github project. I'm planning on adding more functionality when I have some more time.