Youtube video as background for specific section - css

I need to make a youtube video as a background for a specific section not the whole page.
So I need for section to be 390px height and 100% width.
Right now I am using this code but the problem is that the youtube iframe is 100% full width but the video itself is very small and with black sidebars.
here is the code:
<div class="video-wrapper">
<div id="player"></div>
</div>
<script>
// 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', {
height: '390',
width: '100%',
videoId: 'EhArkyWXpO0',
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>
I am using youtube API and Im setting 100% width in javascript.
I am pretty sure I have to use css to achieve this, but no success so far...
Here is the current output
My desired output would be the wideo without black sidebars
Thanks!

You need to adjust the width with javascript by settings width to the width of your window or the parent node.
Set the size of the parent node to 100% and try something like:
node = document.getElementById("player");
player = new YT.Player('player', {
height: node.parentNode.offsetWidth * 9 / 16,
width: node.parentNode.offsetWidth,
videoId: 'EhArkyWXpO0',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
)
If you want to adjust the size if the window is resized, you have to add a function to window.onresize:
window.onresize = function() {
var node = document.getElementById('player');
// fetch player; may a childnode of node[id="player"]
player.setAttribute("width", node.parentNode.offsetWidth);
};

Related

Add videos to Wordpress with autoplay and stop on scroll

I need to insert in my Wordpress page a video uploaded in Media Library. This video has to autoplay when is in browser view and has to stop on user scroll.
I tried to use tag with autoplay function and it's ok. Then I have add to my js folder (in theme folder) a file with some Javascript code in order to add stop on scroll function. I suspect that the code I have tried if fine only with YouTube link.
This is the code I have tried
//play when video is visible
var videos = document.getElementsByTagName("iframe"), fraction = 0.8;
function checkScroll() {
for(var i = 0; i < videos.length; i++) {
var video = videos[i];
var x = 0,
y = 0,
w = video.width,
h = video.height,
r, //right
b, //bottom
visibleX, visibleY, visible,
parent;
parent = video;
while (parent && parent !== document.body) {
x += parent.offsetLeft;
y += parent.offsetTop;
parent = parent.offsetParent;
}
r = x + parseInt(w);
b = y + parseInt(h);
visibleX = Math.max(0, Math.min(w, window.pageXOffset + window.innerWidth - x, r - window.pageXOffset));
visibleY = Math.max(0, Math.min(h, window.pageYOffset + window.innerHeight - y, b - window.pageYOffset));
visible = visibleX * visibleY / (w * h);
if (visible > fraction) {
playVideo();
} else {
pauseVideo();
}
}
};
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', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
};
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
window.addEventListener('scroll', checkScroll, false);
window.addEventListener('resize', checkScroll, false);
//check at least once so you don't have to wait for scrolling for the video to start
window.addEventListener('load', checkScroll, false);
};
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
//console.log("event played");
} else {
//console.log("event paused");
}
};
function stopVideo() {
player.stopVideo();
};
function playVideo() {
player.playVideo();
};
function pauseVideo() {
player.pauseVideo();
};
Using a Youtube link the script pause video on scroll but don't autoplay. I expect both autoplay and pause on scroll using a video from my Wordpress media library
var autoPlayVideo = document.getElementById("ocScreencapVideo");
autoPlayVideo.oncanplaythrough = function() {
autoPlayVideo.muted = true;
autoPlayVideo.play();
autoPlayVideo.pause();
autoPlayVideo.play();
}
<video id="ocScreencapVideo" autoplay="autoplay" muted="muted" loop="loop" playsinline="playsinline" preload="metadata" data-aos="fade-up">
<source src="https://www.youtube.com/watch?v=W6NZfCO5SIk">
Your browser does not support MP4 Format videos or HTML5 Video.
</video>
Add this custom script to your wordpress. You can use plugins like Simple Custom CSS and JS for adding custom snippets.
Here the function checkVisible is taken from another answer here.
jQuery(document).ready(function ($) {
//To check if element is visible
function checkVisible(elm) {
var rect = elm.getBoundingClientRect();
var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
}
//To play-pause self-hosted videos in elementor only when it's visible
$(window).scroll(function () {
$(".elementor-video").each(function (i, obj) {
if (checkVisible(obj)) {
obj.play();
} else
obj.pause();
});
});
});
Rather than using a custom script, you can go with this [plugin][1] provided by Wordpress library to save time and efforts.
Another solution is to use this javascript for autoplay video:
https://codepen.io/bloodcrow777/pen/QBVKKy
var autoPlayVideo = document.getElementById("ocScreencapVideo");
autoPlayVideo.oncanplaythrough = function() {
autoPlayVideo.muted = true;
autoPlayVideo.play();
autoPlayVideo.pause();
autoPlayVideo.play();
}
<video id="ocScreencapVideo" autoplay="autoplay" muted="muted" loop="loop" playsinline="playsinline" preload="metadata" data-aos="fade-up">
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4"
type="video/mp4">
Your browser does not support MP4 Format videos or HTML5 Video.
</video>

Problems with Youtube Iframe Api to start playing video on Chrome

I have following starting setup:
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
Then in onPlayerReady handler I added event listener to button which is outside iframe:
function onPlayerReady(event) {
button.addEventListener('click', () => event.target.playVideo());
}
In onPlayerStateChange I'm just logging what is happening:
function onPlayerStateChange(event) {
console.log(event.data);
}
After hitting that button in Chrome (v.72.0.3626.119) there are 3 entries in console: -1 (UNSTARTED), 3 (BUFFERING), -1 (UNSTARTED). When I try to hit button again nothing happens.
This works perfectly in Firefox, IE giving in console: -1 (UNSTARTED), 3 (BUFFERING),1 (PLAYING) and simply video starts playing.
Do you have any idea how to solve it?
You have to add in the onPlayerReady function this line:
event.target.playVideo();
As is shown in the documentation:
Example:
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
I can't say for sure why, but, in Google Chrome, for autoplay the video, you need to set the value 1 to the mute parameter, otherwise, autoplay the video wont work.
Example:
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '360',
width: '640',
videoId: '<YOUR_VIDEO_ID>',
playerVars: {
'autoplay': 1,
'loop': 1,
'mute': 1 // N.B. here the mute settings.
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
You can check this jsfiddle for guide yourself how you can set custom controls for play/pause your embed video.
I have sent a key after load html, and it works for me.
KeyEvent k = new KeyEvent();
k.WindowsKeyCode = 0x0D;
k.FocusOnEditableField = true;
k.IsSystemKey = false;
k.Type = KeyEventType.Char;
webytb.GetBrowser().GetHost().SendKeyEvent(k);
From this answer, Google Chrome need the allow="autoplay" attribute on iframe to let JS controls the player or make auto play function work.
This is required if you manually use <iframe> instead of <div> tag.
Example:
Attention! Please note that it maybe not work if the result iframe of this site don't have allow="autoplay" attribute on iframe. Copy and paste HTML & JavaScript into your .html file is the best way to test that it is really working.
var player;
/**
* Load YouTube API JavaScript
*/
function loadYTAPIScript() {
console.log('loading YouTube script.');
let tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
/**
* On YouTube iframe API ready
*
* This function will be called automatically by YouTube.
*/
function onYouTubeIframeAPIReady() {
console.log('function `onYouTubeIframeAPIReady` was called.');
player = new YT.Player('player', {
events: {
'onError': onError,
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onError(event) {
console.error('YouTube API error!', event);
} // _onError
/**
* On player ready.
*
* This is callback function from `onReady` event in `onYouTubeIframeAPIReady()`.
*/
function onPlayerReady(e) {
console.log('function `onPlayerReady` was called from `onReady` event callback.', e);
listClickButtons();
}
/**
* On player state change.
*
* This is callback function from `onStateChange` event in `onYouTubeIframeAPIReady()`.
*/
function onPlayerStateChange(e) {
console.log('function `onPlayerStateChange` was called from `onStateChange` event callback.', e);
let state = e.target.getPlayerState();
let stateText = '';
if (state === -1) {
stateText = 'unstarted';
} else if (state === YT.PlayerState.ENDED) {
stateText = 'ended';
} else if (state === YT.PlayerState.PLAYING) {
stateText = 'playing';
} else if (state === YT.PlayerState.PAUSED) {
stateText = 'paused';
} else if (state === YT.PlayerState.BUFFERING) {
stateText = 'buffering';
} else if (state === YT.PlayerState.CUED) {
stateText = 'cued';
}
console.log('State text: ', stateText);
}
/**
* Listen on click buttons to controls the video.
*
* This method was called from `onPlayerReady()`.
*/
function listClickButtons() {
console.log('Listen click buttons.');
let isPlayed = false;
let playpauseBtn = document.getElementById('yt-playpause');
let stopBtn = document.getElementById('yt-stop');
playpauseBtn.addEventListener('click', (e) => {
e.preventDefault();
console.log('User click on play/pause button.');
if (isPlayed === false) {
player.playVideo();
isPlayed = true;
} else {
player.pauseVideo();
isPlayed = false;
}
});
stopBtn.addEventListener('click', (e) => {
e.preventDefault();
console.log('User click on stop button.');
player.stopVideo();
});
}
document.addEventListener('DOMContentLoaded', (e) => {
console.log('DOM ready.');
loadYTAPIScript();
});
<iframe id="player"
width="560" height="315"
src="https://www.youtube.com/embed/1L904pgYbOE?enablejsapi=1"
title="YouTube video player"
allow="autoplay"
allowfullscreen=""
></iframe>
<!--
The `iframe` URL (`src` attribute) must contain enablejsapi=1 query string to let JS API work.
The `iframe` must contain `allow="autoplay"` attribute to allow JS controls the player.
-->
<div class="yt-controllers">
<button id="yt-playpause" type="button">
Play/Pause
</button>
<button id="yt-stop" type="button">
Stop
</button>
</div>
See full code on jsfiddle.
Reference:
Iframe
Iframe allow features list
YouTube Iframe API

Hide youtube annotations

I'm a french designer (so, sorry for my english mistakes) and I'm trying to create an interactive video with different videos hosted on youtube.
These videos already use the youtube 'annotations' or 'cards', but I want to hide them to create my own solution.
Basically I just want to show two divs at a certain timecode of the video to allow user to click on one of them to go to a new url. This thing works.
My question is simple : how can I hide the existing annotations?
I've tried with css, but it doesn't seem to work…
I'm not a full-time developer, so if you know a simple solution, I would be happy to know it :)
Here is the code
<div id="player"></div>
<script>
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '360',
width: '640',
videoId: 'mVwQFmKc7mA',
playerVars: { 'autoplay': 1, 'controls': 1, 'rel': 0, 'showinfo': 0, 'iv_load_policy': 3 },
events: {'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange}
});
}
function onPlayerReady(event) {
event.target.playVideo();
}
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(displayNewDivs, 2000);*/
done = true;
}
}
function displayNewDivs() {
// HERE THE CODE TO SHOW NEW DIVS
}
</script>
Thank you very much!

youtube iframe api loadVideoById() error

I am adding youtube video to a companies website and would like them to display on non-flash devices. I have been playing with the youtube iframe API and updated one of their examples to allow a user to click on a link to change the video in the iframe. The edited code is:
<!DOCTYPE HTML>
<html>
<body>
<div id="player"></div>
<script>
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var done = false;
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'JW5meKfy3fY',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(evt) {
evt.target.playVideo();
}
function onPlayerStateChange(evt) {
if (evt.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
function loadVideo(videoID) {
if(player) { player.loadVideoById(videoID); }
}
</script>
Click me to change video
</body>
</html>
The only thing I added was:
function loadVideo(videoID) {
if(player) { player.loadVideoById(videoID); }
}
This works fine in Safari, Chrome and Firefox but does not work in IE7, 8 or 9. In IE7 and 8 it returns an error "Object does not support this property or method".
Is this an issue with the API or am I doing something wrong?
I had a similar problem, and it turned out that you shouldn't call any of the methods on the YT.Player object (including loadVideoById) as long as onPlayerReady hasn't been called.
Doing a check if(player) {...} isn't sufficient, the Player object will be created and some properties will already be available in out without the methods you need being available.
You will need to call the load video function from the onPlayerReady event.
For example, if you want to load a video when clicking a thumbnail do this (this would require jquery but it should get the point across):
function onPlayerReady(evt) {
evt.target.playVideo();
//declare the click even function you want
$('#thumbs a).click(function(){
//get a data-video-id attr from the <a data-video-id="XXXXXX">
var myvideo = $(this).attr('data-video-id');
//call your custom function
loadVideo(myvideo);
//prevent click propagation
return false;
});
}
This way you can be sure the player is loaded.
Preventing click propagation with return false after the call to player.loadVideoById in my click event handler did the trick for me.

Get Google Maps v3 to resize height of InfoWindow

When I click a marker and the InfoWindow appears, the height does not adjust if the length of the content is longer that the InfoWindow default height (90px).
I am using text-only, no images.
I have tried maxWidth.
I have checked for inherited CSS.
I have wrapped my content in a div
and applied my CSS to that, including
a height.
I have even tried forcing the
InfoWindow to resize with jQuery
using the domready event on the
InfoWindow.
I only have a few hairs left. Here is my JS:
var geocoder;
var map;
var marker;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(41.8801,-87.6272);
var myOptions = {
zoom: 13,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
function codeAddress(infotext,address) {
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
var image = '/path-to/mapMarker.png';
var infowindow = new google.maps.InfoWindow({ content: infotext, maxWidth: 200 });
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location,
icon: image
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
});
}
function checkZipcode(reqZip) {
if ( /[0-9]{5}/.test(reqZip) ) {
$.ajax({
url: 'data.aspx?zip=' + reqZip,
dataType: 'json',
success: function(results) {
$.each(results.products.product, function() {
var display = "<span id='bubble-marker'><strong>"+this.name+"</strong><br>"+
this.address+"<br>"+
this.city+", "+this.state+" "+this.zip+"<br>"+
this.phone+"</span>";
var address = this.address+","+
this.city+","+
this.state+","+
this.zip;
codeAddress(display,address);
});
},
error: function() { $('#information-bar').text('fail'); }
});
} else { $('#information-bar').text('Zip codes are five digit numbers.'); }
}
$('#check-zip').click(function() { $('#information-bar').text(''); checkZipcode($('#requested-zipcode').val()); });
initialize();
InfoText and Address come from an AJAX query of an XML file. Data is not the issue, as it always comes through correctly. codeAddress() is called after the data has been retrieved and formatted.
HTML in the file:
<div id="google_map"> <div id="map_canvas" style="width:279px; height:178px"></div> </div>
CSS for my InfoWindow content (no other CSS applies to the map):
#bubble-marker{ font-size:11px; line-height:15px; }
I finally found a working solution for the problem. Is not as flexible as I wished, but it's pretty good. Fundamentally the key point is: don't use a string as window content but instead a DOM node.
This is my code:
// this dom node will act as wrapper for our content
var wrapper = document.createElement("div");
// inject markup into the wrapper
wrapper.innerHTML = myMethodToGetMarkup();
// style containing overflow declarations
wrapper.className = "map-popup";
// fixed height only :P
wrapper.style.height = "60px";
// initialize the window using wrapper node
var popup = new google.maps.InfoWindow({content: wrapper});
// open the window
popup.open(map, instance);
the following is the CSS declaration:
div.map-popup {
overflow: auto;
overflow-x: hidden;
overflow-y: auto;
}
ps: "instance" refers to the current custom subclass of google.maps.OverlayView (which I'm extending)
Just wrap your content with a div and specify it's height: <div style="height:60px">...</div>, e.g.
myMarker.setContent('<div style="height:60px">' + txt + '</div>');
- In my case it was fairly enough.
Your map canvas is too small. Increase the width/height of your <div id="map_canvas"> element and you should see larger InfoWindows automatically.
That said, I had the same problem on a site I was building. I solved it by creating a cloned div containing the InfoWindow content, measuring that div's width and height, and then setting the InfoWindow content div to have that measured width and height. Here's my code ported into the middle of your codeAddress function (also note that I removed the maxWidth: 200 from your InfoWindow declaration):
function codeAddress(infotext,address) {
geocoder.geocode({ 'address': address }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter(results[0].geometry.location);
// Create temporary div off to the side, containing infotext:
var $cloneInfotext = $('<div>' + infotext + '</div>')
.css({marginLeft: '-9999px', position: 'absolute'})
.appendTo($('body'));
// Wrap infotext with a div that has an explicit width and height,
// found by measuring the temporary div:
infotext = '<div style="width: ' + $cloneInfotext.width() + 'px; ' +
'height: ' + $cloneInfotext.height() + 'px">' + infotext +
'</div>';
// Delete the temporary div:
$cloneInfotext.remove();
// Note no maxWidth defined here:
var infowindow = new google.maps.InfoWindow({ content: infotext });
var marker = new google.maps.Marker({
map: map,
position: results[0].geometry.location
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, marker);
});
}
});
}
Just wrap you InfoBox content with DIV with padding-bottom: 30px;
JS:
map_info_window = new google.maps.InfoWindow();
var $content = $('<div class="infobox">').html(content);
map_info_window.setContent($content.get(0));
map_info_window.open(map, marker);
CSS:
.infobox{
padding-bottom: 30px;
}
It is not really an answer (daveoncode's solution to create a DOM node and use it as content is right), but if you need to dynamically change the content once set (e.g. with jQuery) then you can force gmail to resize the infoWindow with:
infoWindowLinea.setContent(infoWindowLinea.getContent());

Resources