How do I include the Youtube Iframe API in Angular2? - javascript

I am using Angular-cli. I'd like to utilize the youtube iframe api within an Angular2 module. I couldn't get the youtube-iframe node package to work. And the more Angular2 specific packages don't seem to support the full api features.
Here's my work so far:
I have included the actual api in my assets folder. I have added the location as a script within my .angular-cli.json file.
This is what my AppComponent looks like:
export class AppComponent {
YT;
constructor(){
this.YT = window["YT"];
}
onYouTubeIframeAPIReady() {
console.log(this.YT);
var player;
player = new this.YT.Player('muteYouTubeVideoPlayer', {
videoId: 'KKYYAbGpw6A', // YouTube Video ID
width: 560, // Player width (in px)
height: 316, // Player height (in px)
playerVars: {
autoplay: 1, // Auto-play the video on load
controls: 0, // Show pause/play buttons in player
showinfo: 0, // Hide the video title
modestbranding: 0, // Hide the Youtube Logo
loop: 1, // Run the video in a loop
fs: 0, // Hide the full screen button
cc_load_policy: 0, // Hide closed captions
iv_load_policy: 0, // Hide the Video Annotations
autohide: 1 // Hide video controls when playing
},
events: {
onReady: function(e) {
e.target.mute();
}
}
});
}
ngAfterViewInit(){
this.onYouTubeIframeAPIReady();
}
It works when I have the devTools open in Chrome. But not when I have them closed. This is the error I get:
this.YT.Player is not a constructor
at AppComponent.webpackJsonp.328.AppComponent.onYouTubeIframeAPIReady
I guess the problem is using window["YT"]. Can anyone provide me with a step by step guide of doing this properly?

This should be a timing issue. For the onYouTubeIframeAPIReady, It is a youtube provided callback. So inside ngOninit() or ngAfterViewInit(), I would recommend you register it at the window level to let youtube API call it when everything is ready.
something like:
(<any>window).onYouTubeIframeAPIReady = ()=>{
console.log((<any>window).YT);
this.player = new (<any>window).YT.Player('muteYouTubeVideoPlayer', {
videoId: 'KKYYAbGpw6A', // YouTube Video ID
width: 560, // Player width (in px)
height: 316, // Player height (in px)
playerVars: {
autoplay: 1, // Auto-play the video on load
controls: 0, // Show pause/play buttons in player
showinfo: 0, // Hide the video title
modestbranding: 0, // Hide the Youtube Logo
loop: 1, // Run the video in a loop
fs: 0, // Hide the full screen button
cc_load_policy: 0, // Hide closed captions
iv_load_policy: 0, // Hide the Video Annotations
autohide: 1 // Hide video controls when playing
},
events: {
onReady: function(e) {
e.target.mute();
}
}
});
}

Related

Autoplay video in Mobile / Chrome

I want to play video and audio in autoplay mode, When both are ready to play. I'm using this code.
var player;
player = new YT.Player('YouTubeVideoPlayer', {
videoId: 'ID', // YouTube Video ID
width: 560, // Player width (in px)
height: 316,
start:0, // Player height (in px)
playerVars: {
autoplay: 1, // Auto-play the video on load
controls: 0, // Show pause/play buttons in player
showinfo: 0, // Show pause/play buttons in player
rel: 0, // Hide the video title
modestbranding: 0, // Hide the Youtube Logo
loop: 0, // Run the video in a loop
fs: 1, // Hide the full screen button
cc_load_policy: 0, // Hide closed captions
iv_load_policy: 3, // Hide the Video Annotations
autohide: 1 // Hide video controls when playing
},
events: {
onReady: function(e) {
e.target.setVolume(100);
}
}
});
}
This code is working fine in desktop browsers. But when I try it on mobile device it is not working.
I had already given up, until I found this page. It works on both Mobile and Chrome. The question is, how?
Page: https://neilpatel.com/br/master-class/?v=noredirect

custom youtube playlist with custom start and end time

I am trying to make a custom youtube playlist based on the example here.
However, the youtube player gets "jammed" and skips videos (in my case the middle video is skipped). The code is supposed to iterate through the arrays below and play one video at a time with each video having separate start/end times.
How would one go about making this work properly. (note that the code below needs to be uploaded to a website to work. Apparently from a local computer, it does not work)
Here is the code I am using:
<html>
<body>
<div id="ytplayer"></div>
<script>// Load the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var i = 0;
var videoId_arr = ['O57DyNMRGY8','-Yh2QGJBd2U','M7lc1UVf-VE'];
var startSeconds_arr = [41,26,17];
var endSeconds_arr = [50,40,30];
// Replace the 'ytplayer' element with an <iframe> and
// YouTube player after the API code downloads.
var player;
var playerConfig = {
height: '360',
width: '640',
videoId: videoId_arr[i],
playerVars: {
autoplay: 1, // Auto-play the video on load
controls: 1, // Show pause/play buttons in player
showinfo: 1, // Hide the video title
modestbranding: 0, // Hide the Youtube Logo
fs: 1, // Hide the full screen button
cc_load_policy: 0, // Hide closed captions
iv_load_policy: 3, // Hide the Video Annotations
start: startSeconds_arr[i],
end: endSeconds_arr[i],
autohide: 0, // Hide video controls when playing
},
events: {
'onStateChange': onStateChange
}
};
function onYouTubePlayerAPIReady() {
player = new YT.Player('ytplayer', playerConfig);
}
function onStateChange(state) {
if (state.data === YT.PlayerState.ENDED) {
i++;
if(typeof videoId_arr[i] === 'undefined')
return;
player.loadVideoById({
videoId: videoId_arr[i],
startSeconds: startSeconds_arr[i],
endSeconds: endSeconds_arr[i]
});
}
}
</script>
</body>
</html>
I have tested your code and I figured out that the state is changing for some unknown reasons very quickly. The state has sometimes the value 0 which equals YT.PlayerState.ENDED although the video was not played.
You can see it by console logging state.data within the onStateChange function.
A small change fixed the problem:
function onStateChange(state) {
var _video_url = state.target.getVideoUrl();
var _video_id = _url.split('v=')[1];
var _current_index = videoId_arr.indexOf(_video_id) +1;
console.log('State: ', _video_id, _current_index, state );
// ensure that the video has been played
if (state.data === YT.PlayerState.ENDED && player.getCurrentTime() >= endSeconds_arr[i]) {
i++;
if(typeof videoId_arr[i] === 'undefined'){
i = 0; // rest the counter
return;
}
}
}
For the code to run properly you should disable browser plugins like Video Resumer or similar - since they can change the state of a youtube video or resumes the videos from where you stopped them last
fiddle: https://jsfiddle.net/_kdts/Lx91ehdw/
I it possible to loop the videos? I was trying by changing i=1
if(typeof videoId_arr[i] === 'undefined'){
i = 1; // rest the counter
return;
}

YouTube API: Multiple Embeds on the Same Page?

How can I embed different YouTube videos at different places on the page using YouTube API? (This means they can not share the same <div> "player".) They also start at different times based on different onclick events. My code works fine when only one video is on the page, but for the life of me I cannot figure out the code to let this all work with 2 or more!
At first I was trying to simply add multiple instances of the code where I wanted each one to be, but that wasn't working. I read that all the players need to be added to one <script>, so I tried this:
(Also, does it matter WHERE on the page the <script> is and where the <div>s are? Can the <script> write to a <div> no matter where they are on the page?)
Anyway, here's the code I'm using:
// inside other containers with with relative and absolute positioning
// that fadeIn and fadeOut using jQuery
<div id="video1"></div>
// inside other containers with with relative and absolute positioning
// that fadeIn and fadeOut using jQuery
<div id="video2"></div>
<script>
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player1;
var player2;
function onYouTubeIframeAPIReady() {
player1 = new YT.Player('video1',{
width: '320',
height: '216',
videoId: 'VIDEO_ID_1',
playerVars: {rel: 0, controls: 0, autohide: 1, disablekb: 1, enablejsapi: 1, modestbranding: 1, showinfo: 0 },
events: { 'onStateChange': onPlayerStateChange1 } });;
player2 = new YT.Player('video2',{
width: '320',
height: '216',
videoId: 'VIDEO_ID_2',
playerVars: {rel: 0, controls: 0, autohide: 1, disablekb: 1, enablejsapi: 1, modestbranding: 1, showinfo: 0 },
events: { 'onStateChange': onPlayerStateChange2 } });; }
function startVideo1() {
player1.playVideo();
$('#video_box_B1').delay(1000).fadeIn();
$("#video_box_B1").delay(20000).hide();
};
function onPlayerStateChange1(event) {
if(event.data === 2) {
$("#video_box_B1").hide();
}
}
function startVideo2() {
player2.playVideo();
$('#video_box_E5').delay(1000).fadeIn();
$("#video_box_E5").delay(20000).hide();
};
function onPlayerStateChange2(event) {
if(event.data === 2) {
$("#video_box_E5").hide();
}
}
</script>
// onclick triggers at various places on the page
<img src="image_1.jpg" onclick="startVideo1()" />
<img src="image_2.jpg" onclick="startVideo2()" />
Is there anyone who can tell what I'm doing wrong? BTW, those containers fading in and out works perfectly if I'm using a still image, text-only, or with only one video on the page, so it's not those fading containers causing this. It's got to be the YouTube script. Can anyone help?
Seems to be working in this jsbin:
http://jsbin.com/catuhimo/3/edit
What browser are you trying it out in? If you're using Safari bleeding edge Version 8.0 (10538.39.41) on Yosemite, jsfiddle and jsBin had some trouble rendering things. I tried out your code on Chrome latest and replaced the placeholders with actual video IDs and it worked.
Does that help? Am I missing the point of the your question? Based on what you asked, it seems to work ok for me.

Youtube Javascript API - disable related videos

Right, this seems to be poorly documented or I can't see it in the documentation. I basically want no related videos (?rel=0) using the JavaScript API.
$players[$vidIdPlaceholderRef] = new YT.Player('player_' + $vidIdPlaceholderRef, {
height: '550',
width: '840',
videoId: $vidId
});
is what I have in place.
I have also tried:
$players[$vidIdPlaceholderRef] = new YT.Player('player_' + $vidIdPlaceholderRef, {
height: '550',
width: '840',
videoId: $vidId + '?rel=0',
rel : 0
});
with no luck. Does any one know of an option which can be added (tried rel : 0 with no luck )
"rel" is a player parameter, as specified here:
https://developers.google.com/youtube/player_parameters#rel
To add player parameters to iframe players, you need to specify the playerVars property of the second constructor argument (at the time of writing this is documented here, and on the IFrame API documentation page)
e.g.
new YT.Player('playerid', {
height: '550',
width: '840',
videoID: 'video_id',
playerVars: {rel: 0, showinfo: 0, ecver: 2}
});
The behavior of the rel player parameter has changed.
From documentation,
The behavior for the rel parameter is changing on or after September
25, 2018. The effect of the change is that you will not be able to
disable related videos. However, you will have the option of
specifying that the related videos shown in the player should be from
the same channel as the video that was just played
So, it's no longer possible to disable related videos. Instead playerVars: {rel:0} will change the behavior of the player and shows suggestion from specified channel.
You get related videos in two places: at the end of the video with the grid, and at the bottom of the video while paused. I've figured out a way to remove them at the end and make the ones at the bottom at least tolerable for most businesses.
1. Remove related videos at the end of a video
IFrame Player API: Events
To avoid showing related videos at the end of a video, I just stopped the video so it returned to showing the thumbnail and play button:
var player = new YT.Player('player', {
height: '390',
width: '640',
events: {
'onStateChange': function(event){
switch(event.data){
// Stop the video on ending so recommended videos don't pop up
case 0: // ended
player.stopVideo();
break;
case -1: // unstarted
case 1: // playing
case 2: // paused
case 3: // buffering
case 5: // video cued
default:
break;
}
}
}
});
You could also replace player.stopVideo(); with any other code you want to run.
2. Making related videos at the bottom of a video only show your videos
IFrame Player API: YouTube Embedded Players and Player Parameters
rel=0 no longer avoids showing any related videos; now, it will still show related videos, but at least they'll only be from your channel. This changed sometime around September 25, 2018 (documentation).
By setting playerVars in YT.Player, we can at least have related videos only show our channel's videos. The documentation isn't clear that you have to have playerVars set up as an object, but you can set it up like so:
var player = new YT.Player('player', {
...
playerVars:{
rel: 0
modestbranding: 1, // If you're trying to remove branding I figure this is helpful to mention as well; removes the YouTube logo from the bottom controls of the player
// color: 'white', // Can't have this and modestbranding active simultaneously (just a note in case you run into this)
},
...
});
2A. Potential way to remove related videos from bottom
I may look more into it if I have the time, but here's where an answer may lie:
We can easily access the iframe object but we can't do anything with it: IFrame Player API: Accessing and modifying DOM nodes. It appears that because we'd be editing an iframe from YouTube there are security concerns (regardless of what we'd actually be doing). Ideally I could just remove the "More videos" text with player.getIframe().contentWindow.document.querySelector('.ytp-pause-overlay.ytp-scroll-min').remove(), but when I run player.getIframe().contentWindow.document I get an error SecurityError: Permission denied to access property "document" on cross-origin object.
But playerVars also has an origin value that may let us access the iframe's object anyway:
var player = new YT.Player('player', {
...
playerVars:{
origin: 'https://mywebsite.com'
},
...
});
It's not working with localhost, but that may be a Chromium and Firefox thing. Perhaps this is a legitimate option on a live site; I'll update this post when/if I try that to let you know if I succeed.
The accepted solution was not working for me. What does work is:
1) Putting the iframe in html that includes the rel parameter
<iframe id="youtube-video" width="560" height="315"
src="https://www.youtube.com/embed/M7lc1UVf-VE?enablejsapi=1&rel=0&modestbranding=1"
frameborder="0" enablejsapi="1" allowfullscreen></iframe>
2) Using the javascript API to attach to that existing player
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('youtube-video', {
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(event) {
console.log("ready");
}
function onPlayerStateChange(event) {
console.log("state changed");
}
demo fiddle: http://jsfiddle.net/bf7zQ/195/
If you're using SWFObject, you simply need to do something like this:
function loadVideo() {
var params = { allowScriptAccess: "always" }
, atts = { id: "myvideo" }
;
//NOTE THE END OF THE BELOW LINE vvvvvv
swfobject.embedSWF("https://www.youtube.com/v/[video id here]?enablejsapi=1&playerapiid=myvideo&version=3&rel=0"
, "videoplaceholderid"
, "768", "432", "8", null, null, params, atts);
}
Just add rel=0 to the end of your url.
No need to code through the API,now its easily can be done by
You tube embed button -> Show more -> tickout the option 'Show suggested videos when the video finishes'
Here is a Quick solution:
setInterval(function(){
if($('iframe').length > 0){
$('iframe').each(function(){
if($(this).hasClass('gotYou')){
//do nothing
}else{
var getMySrc = $(this).attr('src');
var newSrc = getMySrc.split('?');
console.log(newSrc);
var freshURL = newSrc[0]+'?rel=0&'+newSrc[1];
console.log(freshURL);
$(this).addClass('gotYou');
$(this).attr('src', freshURL );
}
});
}
}, 1);
What it does it, it looks for the iframe in your document. If it finds iframe, it grabs the src of the iframe, finds the ? mark and then replaces ? by ?rel=0& . Here the goal is to out rel=0
new YT.Player('playerid', {
height: '550',
width: '840',
videoID: 'video_id',
playerVars: {rel: 0},
});

How to change video (and start playing immediately) in Flowplayer via Javascript?

It should change the video and start playing regardless of whether or not a video is currently loaded and playing.
Thanks.
See example below where api is your flowplayer instance and replaceclip is the one you want to start plating
var api = flashembed("player", {src:'FlowPlayerDark.swf'}, {config: ...}});
var replaceclip = {'url':'myvideo.mp4', 'autoplay':true};
<button onClick="api.playClip(replaceclip)">Play</button>
See my example in Github https://github.com/Teaonly/android-eye/blob/master/assets/droideye.js
var initAudioPlayer = function () {
// install flowplayer into container
// http://flash.flowplayer.org/
$f("player", "flowplayer-3.2.15.swf", {
plugins: {
controls: {
fullscreen: false,
height: 30,
autoHide: false,
play: false,
}
},
clip: {
autoPlay: false,
url: "stream/live.mp3",
}
});
audioPlayer = $f();
};
var newClip = {'url':'stream/live.mp3?id='+audioCount,'autoplay':true};
audioCount ++;
audioPlayer.play(newClip);
$f().play([{url:'yourmovie.flv'}]);
In this way you can change the video dynamically in Ajax.
You can check out the javascript api for the flowplayer here
Specifically, you'll probably want to check out the flowplayer objects 'Clip' and 'Player'

Categories

Resources