I am currently building a Custom Receiver for our planned Chromecast app.
I need to display YouTube videos on the TV, alongside other photos and info that our app includes.
However, whenever a YouTube iframe embed is played on screen, after a few minutes (min 2, max 15) the Chromecast completely freezes up (including the Dev Tools debugger), and eventually just resets itself.
The issue can be reproduced every time, on multiple Chromecasts, on various videos, using this super simple test page:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Youtube Test</title>
</head>
<body>
<iframe width="1280" height="720" src="//www.youtube.com/embed/YE7VzlLtp-4?autoplay=1" allowfullscreen></iframe>
</body>
</html>
Has anyone encountered a similar issue, or a solution to this?
The included timeline [1] shows that the iframe stops fetching frames via AJAX and shortly after the whole thing crashes.
[1] Recorded dev tools timeline: https://drive.google.com/file/d/0B_bgLIi2Uw5WcDBHSlpwVlJ5eFE/edit?usp=sharing
I am using this code and it is working.
...
<div id="player" style="text-align: center"></div>
<script type="text/javascript">
var vid = ...;
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 player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
playerVars: {
videoId: vid,
'enablejsapi': 1,
'autoplay': 1,
'rel': 0,
'showinfo': 0,
'controls': 0,
'egm': 0,
'showsearch': 0
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
'onError': onError
}
});
}
</script>
...
You can check the the iframe api reference here: https://developers.google.com/youtube/iframe_api_reference
Regards.
Related
So for some time now I am trying to make a proper shuffle script, using the youtube api, in order to play my youtube playlist.
I've found a lot of examples, but none of them seem to be working very well. Some do shuffle the list but not the first song being played, and some do the precise opposite.
What I would like is to shuffle the full playlist and then start playing. So the first played song should be random and the next one played should be random/shuffled as well.
Ive found the script below to shuffle the playlist. However the first song played is not shuffled. Can someone help me out with this?
Thanks a million!
<html>
<body>
<div id="player"></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.
function onYouTubeIframeAPIReady() {
var player = new YT.Player("player", {
height: '390',
width: '640',
events: {
'onReady': function (event) {
event.target.cuePlaylist({list: "PLFgquLnL59anYA8FwzqNFMp3KMcbKwMaT"});
event.target.playVideo();
setTimeout(function() {
event.target.setShuffle({'shufflePlaylist' : true});
}, 1000);
}
}
});
}
</script>
</body>
</html>
This worked for me!
<html>
<body>
<div id="player"></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.
function onYouTubeIframeAPIReady() {
var numPl = Math.floor((Math.random() * 50) + 1);
var player = new YT.Player("player", {
height: '390',
width: '640',
playerVars: {
listType:'playlist',
list:'PLFgquLnL59anYA8FwzqNFMp3KMcbKwMaT',
index: numPl,
autoplay: 1,
},
events: {
'onReady': function (event) {
//event.target.cuePlaylist({list: "PLFgquLnL59anYA8FwzqNFMp3KMcbKwMaT"});
//event.target.playVideo();
setTimeout(function() {
event.target.setShuffle({'shufflePlaylist' : true});
}, 1000);
}
}
});
}
</script>
</body>
</html>
This works using youtube api. and users youtube created play list . shuffles the play list into new order every time page is refreshes
Load YT-player API.
Load YT-playlist user playlist id "**.youtube.com/playlist?list=PLo16_*******"
To Shuffle playlist use > player.setShuffle(true);
To Start YT-player at video 1 in shuffled playlist use > player.playVideoAt(0)
working demo Responsive shuffled YouTube Playlist on Google sites
code jsfiddle.net
<!DOCTYPE html>
<html>
<!-- Responsive YouTube shuffled playlist player -->
<head>
<base target="_top">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag.
style = replaces size in the player script makes it responsive -->
<div style=" top: 0; left: 0; width: 100%; height: 100%; position: absolute;"
id='player'>
</div>
</body>
<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', {
playerVars: {
autoplay: 0,
loop: 1,
controls: 1,
showinfo: 1,
frameborder: 1,
'listType': 'playlist',
'list': "PLo16_DLriHp4A8BvkJFZfO_4KDVv7yGgy", // your YouTube playlist id here
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
// first shuffle play list
player.setShuffle(true);
// Onload and on refresh shuffles the users YT playlist but always starts playing
// the first video in the original list at its new index position
//ie. video (1) = video( new shuffled pos ?)
// to get over this we can start the player at the new shuffled playlist
//video 1(index=0) this changes every time it's refreshed
player.playVideoAt(0)
}
// 5. The API calls this function when the player's state changes.
// option to to add bits
function onPlayerStateChange(event) {
const player = event.target;
}
</script>
</html>
I'd like to create a website that allows users to upload video to a YouTube channel and also embeds those YouTube videos into my website. Is this possible using YouTube's API? How would I go about learning how to do this? I am familiar with HTML5/CSS3 and Python and am acquainted with Java and JavaScript. Any advice is very appreciated.
Did you try ?
YouTube API
YouTube API has python API that allow you to use YouTube at your site
Below is sample page using JavaScript to invoke the YouTube Player to play video embedded in a web page. The sample shows how to play just one video and how to queue several videos and then play them. The sample plays a default video automatically when the page is loaded. When a video is finished playing, the default video is played.
<!doctype html>
<html lang="en">
<head>
<title>Play YouTube Videos</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<script type="text/javascript">
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 player;
var videosQueuedCount;
function onYouTubePlayerAPIReady() {
videosQueuedCount = 1;
var vars = {
autoplay: 1,
enablejsapi: 1,
controls: 1
}
player = new YT.Player('ytplayer', {
height: '390',
width: '640',
playerVars: vars,
videoId:'HL6ZL9q3UJ8',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
function onPlayerReady(evt) {
}
function playVideo(VID) {
window.top.scrollTo(0,200);
videosQueuedCount = 1;
player.loadVideoById(VID);
}
function queueVideo(queuedCount,VID) {
window.top.scrollTo(0,200);
videosQueuedCount = queuedCount;
player.loadPlaylist(VID);
player.playVideo();
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
videosQueuedCount -= 1;
if (videosQueuedCount < 1) {
videosQueuedCount = 1;
playVideo('HL6ZL9q3UJ8');
}
}
}
</script>
<div id="ytplayer"></div>
<p><b>10/22/2015</b> East Lyme, CT Issues and Answers (28:26)<br>
Information<br>Teri Smith of Smith's Acres and Niantic Main Street<br>
</p>
<p><b>10/21/2015 East Lyme, CT Board of Selectmen Meeting</b><br>
Regular Meeting<br>
Part 1 (28:50)
Part 2 (29:25)
Part 3 (29:17)
Part 4 (01:53)
All
</p>
</body>
</html>
I hope this helps!
I have been trying to play two videos (not necessarily simultaneously) on a Chromecast app. Once of them is embedded via the Youtube API and the other is a standard HTML5 video loaded via the tag.
It turns out that the Youtube video simply won't be played back on Chromecast if I also have a standard tag in my HTML5 page. But if I remove that video tag, then the Youtube video will play back nicely.
Any advice is highly appreciated!
Only one active video stream is supported on Chromecast.
I ran into this same problem.
The key elements to solve it are, unload the cast player and don't let a video tag linger in the DOM with a SRC attribute set when you attempt to play Youtube.
As for YouTube, dont let the IFRAME that contains their video player linger in the DOM either when attempting to use the HTML5 video tag.
You'll need to tear down the previous player before attempting to trigger playback through the opposing mechanism.
Here is my sample receiver I used to troubleshoot and solve the problem. This is a working example.
<html>
<head>
<title></title>
<style type="text/css">
body {
background-color: #000;
overflow: hidden;
}
</style>
</head>
<body>
<script type="text/javascript" src="//code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/receiver/2.0.0/cast_receiver.js"></script>
<script type="text/javascript" src="//www.gstatic.com/cast/sdk/libs/mediaplayer/1.0.0/media_player.js"></script>
<video id="chromecast" style="width: 50%; height: 50%;"></video>
<script>
var ytCode = 'sSwLhYhYgI0'
var hlsUrl = 'http://host.com/playlist.m3u8'
</script>
<!-- Chromecast -->
<script type="text/javascript">
var castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
var messageBus = castReceiverManager.getCastMessageBus('urn:x-cast:tv.domain');
cast.receiver.logger.setLevelValue(cast.receiver.LoggerLevel.DEBUG);
cast.player.api.setLoggerLevel(cast.player.api.LoggerLevel.DEBUG);
castReceiverManager.onReady = function() {
console.info('[castReceiverManager.onReady]');
castReceiverManager.setApplicationState('Ready');
};
castReceiverManager.onSenderConnected = function(sender) {
console.info('[castReceiverManager.onSenderConnected]', sender.userAgent);
};
messageBus.onMessage = function(event) {
var message = JSON.parse(event.data);
console.info('[messageBus.onMessage]', message);
};
// Normal
castReceiverManager.start({
maxInactivity: 8,
statusText: 'Ready to play',
dialData: undefined
});
window.playDirect = function(id) {
// Tear down any YT player
$('#youtube').remove();
if(!id) id = 'chromecast';
var mediaElement = document.getElementById(id);
window.host = new cast.player.api.Host({'mediaElement':mediaElement, 'url':hlsUrl});
window.host.onError = function(errorCode) {
console.log('ERROR ' + errorCode);
};
var protocol = cast.player.api.CreateHlsStreamingProtocol(window.host);
window.CCplayer = new cast.player.api.Player(window.host);
window.CCplayer.load(protocol, 25);
setTimeout(function() {
mediaElement.play();
}, 1000);
};
</script>
<!-- Youtube -->
<script>
window.onYouTubeIframeAPIReady = function() {
console.log('Initialized Youtube');
};
var playYT = function() {
// Tear down any direct player
if(window.CCplayer) {
window.CCplayer.unload();
}
$('video').attr('src', '');
// Inject div tag that will be converted to iframe with player
$('body').append('<div id="youtube" style="width: 50%; height: 50%;"></div>');
window.YTPlayer = new YT.Player(
'youtube',
{
height: '100%',
width: '100%',
playerVars: {
'autoplay': 0,
'controls': 0,
'cc_load_policy': 0,
'fs': 0,
'iv_load_policy': 0,
'modestbranding': 0,
'rel': 0,
'showinfo': 0,
'enablejsapi': 1
},
events: {
'onReady': function() {
var params = { videoId: ytCode, startSeconds: 170 };
window.YTPlayer.cueVideoById(params);
window.YTPlayer.playVideo();
},
'onError': function(err) {
console.log('YT Error ' + err);
}
}
});
};
var iframeScript = document.createElement('script');
iframeScript.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(iframeScript, firstScriptTag);
</script>
</body>
</html>
Test:
Load up the sample receiver above, and alternate the following inside the chrome debug console:
playDirect()
or
playYT()
I am trying to play youtube video in my window 8.1 app, with the following code.
var videoPlayer = document.getElementById("videoPlayer");
var content = '<iframe width="480" height="270" src="http://www.youtube.com/embed/XGSy3_Czz8k?rel=0" frameborder="0" allowfullscreen></iframe>';
WinJS.Utilities.setInnerHTMLUnsafe(videoPlayer, content);
where the videoplayer is name of div where video player appears, but I am not able to play the video.
I have also tried using sample code from
https://developers.google.com/youtube/iframe_api_reference#Examples
but it didn't work as well. So please can anyone help me with this.
Thanks in advance
I managed to get this scenario to work for me, but I had to jump through some hoops to make it work.
First, in order to load the external script they need to communicate with the iframe, I had to sandbox the player in its own outer iframe that could run in the web context:
<div class="playerContainer">
<iframe class="playerFrame" src="ms-appx-web:///pages/video/iframe.html" style="visibility: hidden" scrolling="no"></iframe>
</div>
Then I had to edit my APPXMANIFEST to include the YouTube domain as a ContentURI rule:
https://*.youtube.com
My iframe.html was pretty simple:
<!DOCTYPE html>
<html>
<head>
<title>Video Player Iframe</title>
<link href="/pages/video/iframe.css" rel="stylesheet" />
<script src="/pages/video/iframe.js"></script>
</head>
<body>
<iframe id="player"
src="https://www.youtube.com/embed/?enablejsapi=1"
frameborder="0"
style="visibility: hidden"></iframe>
</body>
</html>
Then inside of iframe.js I borrowed heavily from https://developers.google.com/youtube/iframe_api_reference#Examples
(function () {
"use strict";
window.addEventListener('message', function (e) {
if (e.data.op === 'load') {
loadVideo(e.data.args)
} else if (e.data.op === 'resize') {
resize(e.data.args);
} else if (e.data.op === 'destroy') {
destroy();
}
});
var player;
var videoId;
function loadVideo(args) {
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 playerEl = document.getElementById('player');
playerEl.height = window.innerHeight;
playerEl.width = window.innerWidth;
videoId = args.videoId;
window.onYouTubeIframeAPIReady = function onYouTubeIframeAPIReady() {
playerEl.style.visibility = 'visible';
player = new YT.Player('player', {
events: {
'onReady': onPlayerReady
}
});
}
}
function resize(args) {
player && player.setSize(window.innerWidth, window.innerHeight);
}
function destroy() {
player && player.destroy();
player = null;
}
function onPlayerReady(event) {
event.target.loadVideoById(videoId);
}
})();
As you can see from the above, I am using iframe's postMessage to tell the wrapping iframe to load the videoId that I want:
iframe.addEventListener("load", function () {
iframe.style.visibility = 'visible';
if (iframe.contentWindow) {
iframe.contentWindow.postMessage({ op: "load", args: { videoId: video.id} }, "*");
}
});
Hope that helps some. The YouTube IFrame API is pretty finicky and didn't work right for me when loaded any other way.
I do have following code where i want to play youtube video when button is clicked.
I have iframe code for youtube.
<script>
var player = document.getElementById("myplayer");
//Create a simple function and check if player exists
function play() {
if(player) {
player.playVideo();
}
}
</script>
<iframe id="myplayer" width="500" height="500" src="http://www.youtube-nocookie.com/embed/C-VoyCDUvr0?rel=0&wmode=Opaque&enablejsapi=1" frameborder="0" allowfullscreen></iframe>
Play Youtube Video
But it does not play when i click on button / link
I put script code in head part of html and iframe and anchor link in body part of html.
Am i missing anything?
Here I gave the example of two players:
<!DOCTYPE html>
<html>
<body>
<div id="divPlayer1"></div>
<div id="divPlayer2"></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 player1;
var player2;
function onYouTubeIframeAPIReady() {
player1 = new YT.Player('divPlayer1', {
height: '390',
width: '640',
videoId: 'iZYIsJ9i5yE',});
player2 = new YT.Player('divPlayer2', {
height: '390',
width: '640',
videoId: 'J7rKAKipj8s',});
}
function play1() {
player1.playVideo();
}
function play2() {
player2.playVideo();
}
</script>
Play Youtube Video1
Play Youtube Video2
</body>
</html>
There probably is no iframe#myplayer yet when your script is run. Move the definition of player inside the function like this:
function play() {
var player = document.getElementById("myplayer"); // Moved here
if(player) {
player.playVideo();
}
}
That should work.
Edit: That latter link seems to suggest you do this instead:
var player; // Might not be necessary
function onYouTubePlayerReady(playerId) {
player = document.getElementById("myplayer");
}
function play() {
if(player) {
player.playVideo();
}
}
<script>
function toggleVideo(state) {
var iframe = document.getElementById("myplayer").contentWindow;
func = state == 'hide' ? 'pauseVideo' : 'playVideo';
iframe.postMessage('{"event":"command","func":"' + func + '","args":""}', '*');
}
</script>
<script type="text/javascript" src="http://www.youtube.com/player_api"></script>
<!-- popup and contents -->
<iframe id="myplayer" width="500" height="315" src="http://www.youtube.com/embed/C-VoyCDUvr0?enablejsapi=1"
frameborder="0" allowfullscreen></iframe>
Play Youtube Video
This is the working code with one play. Should be altered only by videoId: 'iZYIsJ9i5yE' whity our videoId in youtube:
<!DOCTYPE html>
<html>
<body>
<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 player1;
function onYouTubeIframeAPIReady() {
player1 = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'iZYIsJ9i5yE',});
}
function play1() {
player1.playVideo();
}
</script>
Play Youtube Video
</body>
</html>
Use this iframe and change your youtube link. I hope it will work surely. It is working on my website.
<iframe src="https://www.youtube.com/embed/2XXzYCfBiAg" frameborder="0" gesture="media" allow="encrypted-media" allowfullscreen style="width:100%; height:445px; padding:0; left:25%"></iframe>