Embedded Youtube videos not playing in mobile iOS Safari - javascript

Recently we've found a bug that exists only in Safari on iPhone(s) however I cannot pinpoint the source of the issue. When pressing the play button the video appears to load but then closes immediately.
All answers I've found so far aren't recent and/or don't solve the problem. Testing in BrowserStack is giving me this error: Invalid CSS property declaration at: * from the www-embed-player-sprite-mode-vfl9mHoaB.css file served from Youtube.
I'm also open to optional ways of handling embedded videos to avoid this issue.
The code:
#set($showVideo = $request.getParameter("showVideo"))
#set($howItWorksID = $placeholder.getAttributeValueGroup().getAttributeValue('product_howitworks', $sesShoppingCart.getLocale()))
#set($embeddedURL = "https://www.youtube.com/embed/" + $howItWorksID + "?rel=0")
#set($hasVideoID = false)
#if( $howItWorksID && $howItWorksID != "" )
#set( $hasVideoID = true )
#end
<div id="howItWorksModal" class="modal-howItWorks modal fade">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<button type="button" class="close js-modalClose close--howItWorks" data-dismiss="modal">
<span aria-hidden="true">×</span>
<span class="sr-only">close</span>
</button>
<div>
<div class="prose howItWorks-embedVideoWrapper">
<div class="iframe-container">
<iframe id="howItWorks-ModalVersion" class="howItWorks js-howItWorks-iframe" width="100%" src="" frameborder="0" allowfullscreen preload></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
jQueryReady(function() {
var videoURL = "$embeddedURL";
// Load destination video and autoplay when modal opens
$("#howItWorksModal").on('shown.bs.modal', function(ev) {
ev.preventDefault();
$("#howItWorks-ModalVersion").attr("src", videoURL + "&autoplay=1");
console.log('clicked on');
});
// Kill video when modal is closed
$('#howItWorksModal').on('hidden.bs.modal', function (e) {
$('.js-howItWorks-iframe').each( function(){
$(this).attr('src', '');
});
});
// Kill mobile video if playing while window is resized
function mobileVideoSource(){
var mobileBlock = $('#BuyNow-mobileBlock'),
howToVid_mobile = $('#howItWorks-MobileVersion');
if (mobileBlock.is(":hidden")) {
// if mobile block is hidden remove it's source
howToVid_mobile.attr('src', '');
} else {
// if mobile block is displayed add a source
howToVid_mobile.attr('src', videoURL);
}
}
sdi.window.on('resize', mobileVideoSource);
})

mobileVideoSource() was being called and removing the src when the video was opening. I did not investigate into why this was happening, however I restructured the script to completely remove the iframe instead of the src and inject a new instance if (for whatever rare edge use case) the screen is resized back down to mobile and the user wants to watch the video again:
function mobileVideoSource() {
var mobileBlock = $('#BuyNow-mobileBlock'),
currentVid = $('#howItWorks-MobileVersion'),
videoContainer = $('.iframe-container')
new_iframe = $('<iframe id="howItWorks-MobileVersion" class="howItWorks" width="560" height="315" src="$embeddedURL" frameborder="0" allowfullscreen></iframe>');
if (mobileBlock.is(":hidden")) {
currentVid.remove();
} else {
videoContainer.append(new_iframe);
}
}

Related

Migrate to Bootstrap 5 - Video Modal

I have a modal with video inside, written for Bootstrap 4. I want to migrate this to Bootstrap 5, where no jQuery is available. How may I do this? The problem is the JavaScript here:
<script>
// codepen.io/JacobLett/pen/xqpEYE
$(document).ready(function() {
var $videoSrc;
$('.video-btn').click(function() {
$videoSrc = $(this).data( "src" );
});
console.log($videoSrc);
// when the modal is opened autoplay it
$('#videoModal').on('shown.bs.modal', function (e) {
// set the video src to autoplay and not to show related video. Youtube related video is like a box of chocolates... you never know what you're gonna get
$("#video").attr('src',$videoSrc + "?autoplay=1&modestbranding=1&showinfo=0" );
})
// stop playing the youtube video when I close the modal
$('#videoModal').on('hide.bs.modal', function (e) {
// a poor man's stop video
$("#video").attr('src',$videoSrc);
})
});
</script>
The modal is using
<button type="button" class="video-btn" data-bs-toggle="modal" data-bs-target="#videoModal" data-bs-src="https://www.youtube.com/embed/EzDC8aAJln0" >
<img src="/img/video/dbschema-video.svg" class="img-fluid" alt="DbSchema Video Presentation">
</button>
<div class="modal fade" id="videoModal" tabindex="-1" role="dialog" aria-labelledby="dbschemaModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<div class="ratio ratio-16x9">
<iframe class="embed-responsive-item" src="" id="video" allowscriptaccess="always" allow="autoplay"></iframe>
</div>
</div>
</div>
</div>
</div>
See this.
So you can do something like below:
$(document).ready(function() {
var $videoSrc;
document.querySelector('.video-btn').addEventListener('click', function() {
$videoSrc = $(this).data( "src" );
});
console.log($videoSrc);
// when the modal is opened autoplay it
document.getElementById('videoModal').addEventListener('shown.bs.modal', function (e) {
// set the video src to autoplay and not to show related video. Youtube related video is like a box of chocolates... you never know what you're gonna get
$("#video").attr('src',$videoSrc + "?autoplay=1&modestbranding=1&showinfo=0" );
})
// stop playing the youtube video when I close the modal
document.getElementById('videoModal').addEventListener('hide.bs.modal', function (e) {
// a poor man's stop video
$("#video").attr('src',$videoSrc);
})
});
Also you should add -bs- to your data-attributes wherever you use bootstrap-5
For vanilla JS it would be something like this...
var videoBtn = document.querySelector('.video-btn')
var videoModal = document.getElementById('videoModal')
var video = document.getElementById('video')
var videoSrc
videoBtn.addEventListener('click',function(e){
videoSrc = videoBtn.getAttribute('data-bs-src')
})
videoModal.addEventListener('shown.bs.modal',(e)=>{
video.setAttribute('src', videoSrc + '?autoplay=1&modestbranding=1&showinfo=0')
})
videoModal.addEventListener('hide.bs.modal',(e)=>{
video.setAttribute('src', videoSrc)
})
Here's the working code

Video pop up autoplay, when pop up does not come up. i can still hear sound

I added this pop up to my site, and try add autoplay, but the problem is even the pop dont come up each time you refresh your website, you can still hear the sound.how can i stop the autoplay when pop up doesn't show?
I tried to solve problem by doing this but is still not working
<script>
$( document ).ajaxComplete(function() {
$("#popup_87 flex-video iframe").attr("src","https://www.youtube.com/embed/vYAVyEdBfEU?rel=0&autoplay=1;showinfo=0");
});
</script>
<!-- START POPUP CODE -->
<div id="popup_87" class="reveal-modal small" data-reveal aria-labelledby="popvideo" aria-hidden="true" role="dialog">
<div class="flex-video widescreen">
<iframe src="https://www.youtube.com/embed/vYAVyEdBfEU?rel=0&showinfo=0&autoplay=1" allowfullscreen="" frameborder="0" height="360" width="640"></iframe>
</div>
<a class="close-reveal-modal" aria-label="Close">×</a>
</div>
<div class="hide">
popvideo
</div>
</div>
/////
<script>
if (jQuery.cookie('popup{$popup['popup_id']}') === undefined)
{
var cookieCount = 1;
}
else
{
var cookieCount = jQuery.cookie('popup{$popup['popup_id']}');
}
var popCount = {$popup['popup_max_display_count']};
if (cookieCount <= popCount) {
setTimeout(function() {\$(".clickMe").trigger("click");}, 3000);
cookieCount++;
jQuery.cookie('popup{$popup['popup_id']}', cookieCount, { expires: {$popup['popup_clear_count_after']} });
}
</script>
Try
<script>
function LoadVideo() {
// If it's visible
if($("#popup_87").is(":visible"))
{
// Load the video and auto play
$("#popup_87 flex-video iframe").attr("src","http://www.youtube.com/embed/vYAVyEdBfEU?rel=0&autoplay=1;showinfo=0");
}
}
</script>
EDIT since more code was added, put the trigger when they click on the link to load the video into the pop-up, otherwise don't load the video in the iframe:
<!-- START POPUP CODE -->
<div id="popup_87" class="reveal-modal small" data-reveal aria-labelledby="popvideo" aria-hidden="true" role="dialog">
<div class="flex-video widescreen">
<!-- Removed the source -->
<iframe allowfullscreen="" frameborder="0" height="360" width="640"></iframe>
</div>
<a class="close-reveal-modal" aria-label="Close">×</a>
</div>
<div class="hide">
popvideo
</div>
I'm not sure if the following code works, but I just added LoadVideo to your script.
<script>
if (jQuery.cookie('popup{$popup['popup_id']}') === undefined)
{
var cookieCount = 1;
}
else
{
var cookieCount = jQuery.cookie('popup{$popup['popup_id']}');
}
var popCount = {$popup['popup_max_display_count']};
if (cookieCount <= popCount) {
LoadVideo();
setTimeout(function() {\$(".clickMe").trigger("click");}, 3000);
cookieCount++;
jQuery.cookie('popup{$popup['popup_id']}', cookieCount, { expires: {$popup['popup_clear_count_after']} });
}
</script>

YouTube as popup play on desktop version but not on mobile devices

I am using below script to play YouTube video as a bootstrap Modal, It play video on desktop version but same fails to play on mobile devices such as iphone and iPad.
YouTubeLoader.js
// Load & insert into DOM Youtube iframe_api
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
/* Create Player */
var player;
function onYouTubeIframeAPIReady() {
console.log('Api Loaded');
}
$(".youtubeVideoLoader").each(function() {
// Set the BG image from the youtube ID
$(this).css('background-image', 'url(//i.ytimg.com/vi/' + this.id + '/hqdefault.jpg)');
// Click the video div
$(document).delegate('#' + this.id, 'click', function() {
// Vemos le id del video
console.log(this.id);
// Create new instance of player
player = new YT.Player('videoModalContainer', {
videoId: this.id,
events: {
'onReady': OpenModal,
'onStateChange': console.log('Changed')
}
});
// Show Modal
function OpenModal() {
$("#youtubeModal").modal({backdrop: "static"});
// Set Highres
player.setPlaybackQuality('highres');
// Play Video
player.playVideo();
};
});// /click
}); // /each video
// Add a Lisener to Modal CLose Button
$('#CloseModalButton').click(function(){
console.log('Stop Preset');
player.destroy();
});
HTML
<div id="3WCMCeS7Na4" class="youtubeVideoLoader">
</div>
<!-- Modal Template -->
<div class="modal fade" id="youtubeModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-footer">
<button id="CloseModalButton" type="button" class="btn btn-default" data-dismiss="modal">X</button>
</div>
<div class="modal-content">
<div class="modal-body">
<div id="videoModalContainer">
</div>
</div>
I have tried it with other video and i face the same issue as i initially thought it might be one video which is not playing due to privileges
Issue was resolved removing following two lines of code.
//player.setPlaybackQuality('highres');
//player.playVideo();
It was not playing on mobile devices as Youtube has stopped the AutoPlay functionality of video. Not sure why it worked on desktop version...

How i can stop Youtube running Video in popup that i have popup?

I have created popup window with the div tag when user click to watch specified video:
<div class="popup" >
<h2 class="popup_header center">Tutorial - 2</h2>
<p class="popup_sub_header center"> Tutorial Label </p>
<div class="popup_video_container">
<div class="video_frame pop_mode" id="popUpVideoWindow">
<iframe width="640" height="320" src="https://www.youtube.com/embed/link" frameborder="0" allowfullscreen="" hspace="0" vspace="0"></iframe>
</div>
<div class="tutorial_description">
</div>
</div>
<a class="close" href="#close"></a>
</div>
Now when i close this window video does not going to stop, continuing buffering and playing with other stuffs.
I have gone through other questions and found afterClose, on('hidden') method to work on class and idlike this one:
$('.popUpVideoWindow').on('hidden',function(){
$iframe = $(this)find("iframe");
$iframe.attr("src", $iframe.attr("src"));
console.log("Link set:" , $iframe.attr("src"));
});
and
$("#video_frame").bind('afterClose', function(){{
$iframe = $(this)find("iframe");
$iframe.attr("src", $iframe.attr("src"));
console.log("Link set:" , $iframe.attr("src"));
});
but it doesnt going to help me what i want. I want to stop playing the video when i close that popup div.
var figure = $(".video");
var vid = figure.find("video");
[].forEach.call(figure, function (item,index) {
item.addEventListener('mouseover', hoverVideo.bind(item,index), false);
item.addEventListener('mouseout', hideVideo.bind(item,index), false);
});
function hoverVideo(index, e) {
vid[index].play();
}
function hideVideo(index, e) {
vid[index].pause();
}
Check this example with this JSFiddle
Make necessary changes.
check it please..regds

Play mp4 video via javascript

I have a responsive site that contains html5 video. I have some javascript that checks if the size of the video elements are below a certain threshold. If so, it removes the controls, places a video play button overlay image on top of the video element then adds a click event to the container holding the video element. When the container is clicked on, it copies the video into a modal dialog box and plays the video.
Here's the quandary:
The webm version has no problems whatsoever.
The mp4 version of the modal view has no problems in Safari.
If the mp4 plays in place (i.e. is large enough to not need a modal window) it plays fine.
The mp4 version of the modal view won't play in Chrome or IE.
However, it will work in Chrome or IE if I have their built-in DOM
inspectors open (e.g. IE's F12 tools).
This can be seen here.
Here's the HTML:
<div class="video modal-trigger col-lg-4 col-md-4 col-sm-4">
<canvas></canvas>
<video preload="auto" controls="controls" poster="img/why-autologel-poster.png">
<source src="media/why-autologel.m4v" type='video/mp4'>
<source src="media/why-autologel.webm" type='video/webm'>
</video>
</div>
<div class="col-lg-8 col-md-8 col-sm-7">
<h2 class="modal-heading">
Why AutoloGel?
</h2>
<p class="modal-copy">
See what AutoloGel offers to your patients.
</p>
</div>
<!-- Modal Window -->
<div class="modal fade" id="modal-window" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel"></h4>
</div>
<div class="modal-body">
<div class="media"></div>
<div class="copy"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Here's the javascript:
$(document).ready(function() {
// Play very small videos in modal box
if ( $(window).width() > 750 ) {
var modalvideo = document.getElementsByTagName('video');
// Hide controls for very small videos
for (var i = 0; i < modalvideo.length; i++) {
if ( $(modalvideo[i]).width() < 470 ) {
$(modalvideo[i]).removeAttr('controls');
if ( $('html').hasClass('IE-9') ) {
$(modalvideo[i]).after('<img class="poster-overlay" src="img/poster-overlay-ie9.png" alt="play video">');
} else {
$(modalvideo[i]).after('<img class="poster-overlay" src="img/poster-overlay.png" alt="play video">');
}
}
}
// Add click event to video container that brings up video in a modal window
$('.modal-trigger').on("click", function() {
if ( $(this).width() < 470 ) {
// Get video, title and any copy text
var media = $(this).html();
var title = $(this).next().children('.modal-heading').text();
var copy = $(this).next().children('.modal-copy').text();
// Insert video, title and copy text into modal window
$('.modal-title').html(title);
$('.modal-body > .media').html(media);
$('.modal-body > .copy').text(copy);
$('#modal-window .poster-overlay').remove('');
$('#modal-window').modal('show');
// Autoplay video after modal window has rendered
$('#modal-window').on('shown.bs.modal', function() {
modalvideo[modalvideo.length - 1].setAttribute('controls', 'controls');
modalvideo[modalvideo.length - 1].play();
});
// Stop play video when modal window is closed
$('#modal-window').on('hide.bs.modal', function() {
modalvideo[modalvideo.length - 1].pause();
});
}
});
}
});
Thanks for your help!
Figured it out.
The problem was in two parts. For Chrome, there’s some quirk with its cache and copied DOM elements. I figured it was working when the developer tools were open because the cache is disabled. Simply applying a random GET variable at the end of the src attribute for the copied video element to flag it as a different file than the one cached solved the problem.
With IE it was (is) a little different. HubSpot uses Amazon S3 as its CDN and when I looked at the header for the video file its content type was set as application/octet-stream which Internet Explorer doesn’t support. AWS allows this to be set when the file is uploaded but HubSpot is doing this behind the scenes with no user ability to set this that I’m aware of. They're working on a fix.
The solution that ended up working:
$(document).ready(function() {
// Play very small videos in modal box
if ( $(window).width() > 750 ) {
var allvideos = $('video');
// Hide controls for very small videos
for (var i = 0; i < allvideos.length; i++) {
if ( $(allvideos[i]).width() < 470 ) {
$(allvideos[i]).removeAttr('controls');
if ( $('html').hasClass('IE-9') ) {
$(allvideos[i]).after('<img class="poster-overlay" src="img/poster-overlay.png" alt="play video">');
} else {
$(allvideos[i]).after('<img class="poster-overlay" src="img/poster-overlay.png" alt="play video">');
}
}
}
// Add click event to video container that brings up video in a modal window
$('.modal-trigger').on('click', function() {
if ( $(this).width() < 470 ) {
// Get video/img, title and any copy text
var media = $(this).html();
var title = $(this).next().children('.modal-heading').text();
var copy = $(this).next().children('.modal-copy').text();
if (! title.length) { title = '<br>'; }
// Insert video, title and copy text into modal window
var modalsrc = [];
var modaltype = [];
$(media).children('source').each(function() {
modalsrc.push( $(this).attr('src') );
modaltype.push( $(this).attr('type') );
});
$('.modal-title').html(title);
$('.modal-body > .media').html(media);
$('.modal-body > .copy').text(copy);
$('#modal-window .poster-overlay').remove('');
// Assign a random version to video src to bypass cache
var modalsources = $('#modal-window source');
var nocachesrc = '';
for (var i = 0; i < modalsources.length; i++) {
nocachesrc = modalsrc[i] + '?rnd=' + Math.random()*Math.random();
modalsources[i].setAttribute('src', nocachesrc);
modalsources[i].setAttribute('type', modaltype[i]);
}
var modalvideo = $('#modal-window video');
modalvideo[0].setAttribute('controls', 'controls');
// Reveal modal window and play video
$('#modal-window').modal('show');
$('#modal-window').on('shown.bs.modal', function() {
modalvideo[0].play();
});
// Stop playing video when modal window is closed
$('#modal-window').on('hide.bs.modal', function() {
modalvideo[0].pause();
});
}
});
}
});
Remove the semicolon from the type attribute of the source nodes, should be: type="video/mp4", other browsers are probably just being forgiving of this.

Categories

Resources