I am trying to create a Youtube player using a WebView instead of the Youtube API for android which I find very limiting.
I have tried using HTML and JavaScript to play the video on a iFrame as instructed by Google: https://developers.google.com/youtube/iframe_api_reference
Mainly using this HTML code and load it to the WebView:
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<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.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '360',
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();
}
</script>
</body>
</html>
I have therefore just started putting a regular iFrame and the video is actually loaded and showing with this kind of code:
webview.loadData("<body><iframe id=\"iframe\" src=" + url + " height=\"300\"\n" </iframe></body>", "text/html","utf-8");
The problem is that I can autoplay the video, as well as having absolutely no control over the player.
I have tried adding "autoplay=1" with all its possible variations to autoplay. And the first method using the proper div method and javascript as instructed by google results in having absolutely nothing showing, with these log messages:
W/VideoCapabilities: Unrecognized profile 2130706433 for video/avc
W/AudioCapabilities: Unsupported mime audio/alac
W/AudioCapabilities: Unsupported mime audio/dsd
W/VideoCapabilities: Unsupported mime video/divx
W/VideoCapabilities: Unsupported mime video/divx311
W/VideoCapabilities: Unsupported mime video/divx4
W/VideoCapabilities: Unsupported mime video/mp4v-esdp
I/VideoCapabilities: Unsupported profile 4 for video/mp4v-es
I still get these messages when using the iFrame alone, but the video loads and I can click on it and it plays as expected.
If anyone can shed any light on this problem I have, ideally how to control the video using the proper "Google" way, or at least help me autoplay it using the other method.
P.S: I have enabled JS, hardware acceleration, set chrome as the web browser, checked the permissions. As I have said, I get the video to play after physically clicking on it, but it's just user driven and I have no control over it programmatically.
Related
It is my first post, I hope I respected all the rules.
I am trying to publish on a page of my website a:
shuffle / muted / autoplay youtube playlist.
I used the method AS3, with SWFObject.
Everything worked fine with the following code, but since few weeks, the player doesn't detect my playlist and just play the first video.
In the code, the URL is :
https://www.youtube.com/v/HuIGf4IJzdM&list=PLo-QIlIZx6myBxEysxrWoE-f58-psKGji
But when I open the page of the page, it open the following link :
https://www.youtube.com/v/HuIGf4IJzdM&list=o-QIlIZx6myBxEysxrWoE-f58-psKGji
Here is the code wich, if I am not wrong, works fine precedently :
<script src="https://www.google.com/jsapi"></script>
<script src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js"></script>
<div id="ytapiplayer">You need Flash player 8+ and JavaScript enabled to view this video.</div>
<script type="text/javascript">
google.load("swfobject", "2.2");
function onYouTubePlayerReady(playerId) {
ytplayer = document.getElementById("myytplayer");
ytplayer.playVideo();
ytplayer.setShuffle(true);
ytplayer.mute();
}
var params = {allowScriptAccess: "always" , allowFullScreen : "true"};
var atts = { id: "myytplayer" };
swfobject.embedSWF("https://www.youtube.com/v/HuIGf4IJzdM&list=PLo-QIlIZx6myBxEysxrWoE-f58-psKGji&index=0&feature=plpp_play_all?enablejsapi=1&playerapiid=ytplayer&allowFullScreen=true&version=3&loop=1&autohide=1",
"ytapiplayer", "50%", "50%", "10", null, null, params, atts)
</script>
Thank you a lot if someone can help me to fin the solution to this problem !!
I finally found an alternative way to make it work with an iframe.
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: '100%',
width: '100%',
events: {
'onReady': onPlayerReady
}
});
}
function onPlayerReady(event) {
event.target.loadPlaylist({'listType': 'playlist',
'list': 'PLo-QIlIZx6myBxEysxrWoE-f58-psKGji',
'index': '0'
});
event.target.mute();
event.target.setLoop(true);
setTimeout( function() {
event.target.setShuffle(true);
}, 2000);
}
</script>
Thank you for the help :-)
...the player doesn't detect my playlist and just play the first video.
Youtube has moved on to the newer iFrame API and that one does allow playlists.
Try this example code below by pasting it here (click "See Result")
<!DOCTYPE html>
<html>
<body>
<iframe width="700" height="400"
src="https://www.youtube.com/embed/HuIGf4IJzdM?list=PLo-QIlIZx6myBxEysxrWoE-f58-psKGji">
</iframe>
</body>
</html>
See how it's within an <iframe> tag? Not SWF, not JS, just working with iFrame. You must add a similar tag to your website code (remove & replace your shown script code).
NOTES :
Also notice the iFrame url begins with
https://www.youtube.com/embed/ this gives you the HTML5 player
meaning it will work on mobile too. Site visitors using phones or
tablets can watch. This is the best working option for all your site
visitors.
If you really want Flash in the iFrame then change beginning to
https://www.youtube.com/v/ this gives you the SWF player which
means it will need the Flash Player plugin (not available on mobile).
People using phones or tablets to visit your site cannot watch
(they get a blank white box or some message like "Plugin not
available").
OK, this has been asked many times before – but Youtube seems to change things up every other day. I can't find a way to force a Youtube embed to start playing a HD source from the beginning. The switch to HD always happens after 5-10 seconds.
Methods that don't work (anymore):
Adding &hd=1 parameter to the iframe src
Adding &vd=hd720 or &vd=hd1080 parameters to the iframe src. Described here: Force youtube embed to start in 720p
Changing the iframe dimenstions to width="1280" heigh="720" in the html embed code and then using CSS to scale the iframe back down/up to the parent div. Described here: http://thenewcode.com/717/Force-Embedded-YouTube-Videos-To-Play-In-HD and here: How to force youtube to play HD videos
The only possible way would be using the Youtube JavaScript API, as described here:
http://biostall.com/the-100-guaranteed-method-to-get-youtube-iframe-embeds-playing-in-hd-by-default/
// 1. 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);
// 2. This function creates an <iframe> (and YouTube player) after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '1280',
width: '720',
videoId: 'E37YNMYlKvo',
events: {
'onReady': onPlayerReady
}
});
}
// 3. The API will call this function when the video player is ready.
function onPlayerReady(event) {
player.setPlaybackQuality('hd1080'); // Here we set the quality (yay!)
event.target.playVideo(); // Optional. Means video autoplays
}
<div id="player"></div>
But: I want to use a simple iframe embed since videos will be embeded through the wordpress oembed feature.
Is there any way to run the player.setPlaybackQuality('hd1080'); function for a simple iframe embed?
You can also set your playerVars
vq: 'hd1080',
144p: &vq=tiny
240p: &vq=small
360p: &vq=medium
480p: &vq=large
720p: &vq=hd720
1080p: &vq=hd1080
From what I understand, there seems to be a 'VQ' parameter that you can attach to the end of the embed iframe and set hd720 or hd1080 as the value. After some research it seems YouTube once offered the 'VQ' parameter, then took it away, and as of this writing is back again! In short, your embed should look something like this:
<iframe src="https://www.youtube.com/embed/VIDEO_ID_HERE?vq=hd1080" frameborder="0" allowfullscreen></iframe>
Here is an article related to this that I found during my research: Found Here
I've tested this briefly on a page and it seems to work (for now). Hope this helps!
Is there an "onload" of the video for an embeded youtube iframe?
I'd like to start my script only after the music video i have selected starts.
I have stuck an onload event onto the iframe the youtube video is delivered in, but that does not correspond to the loading (buffering has finished ready to play) of the actual video. It only corresponds to when the video player has been loaded in the page.
In other words, is there any way to detect with javascript when a youtube video starts playing?
Everything you're looking for can be found in the Youtube Iframe API reference.
I'll paste the relevant code here as well, but be aware that I only modified one line to trigger an alert onReady. The rest of the code comes from the aforementioned reference page.
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<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.
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) {
alert("Video Ready!");
event.target.playVideo(); // You can omit this to prevent the video starting as soon as it loads.
}
// 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>
I have copied the Youtube embedded player demo code Youtube embedded player demo code almost verbatim - the changes are inserting console.log so that I can see what is going on.
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<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.
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) {
console.log('onPlayerReady');
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) {
console.log('onPlayerStateChange');
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
function stopVideo() {
player.stopVideo();
}
</script>
</body>
</html>
This works as intended in Safari and Firefox, that is once the API loads the choosen video plays for six seconds and the console.log contains evidence that the events are firing. However in Internet Explorer the events onReady and onStateChange do not fire. The video will play if I manually click the play control in the player but I do not get the expected onStateChange events.
I checked the version of Flash on my machine and it is: 11.2.202.228 and the current available is 12.0.0.70. If I disable Flash in IE (manage add ons) the player works as expected: plays for 6 seconds and events fire.
I did not update Flash because while that might fix the issue on my machine my audience will be limited to those only that can do the same and if I updated I would not be able to find out if the issue was resolved by other means.
I have also tried to manually create the iframe myself as mentioned in the above Youtube documentation, this worked as expected in Firefox and Safari but not in IE.
There is a Youtube demo player this works perfectly in Firefox, the play, pause and stop controls via the API work and the events are clearly firing as the Events and Function Calls are written to the screen in the "Statistics" section. In contrast when I look at this in IE the play, pause and stop controls via the API do nothing. There is no output in the statistics section. The only way to play and pause is to use the buttons on the player. If I disable Flash then the player & API works perfectly.
If I try an iframe non API embed then the player works correctly, this leads me to believe that it is an issue arising from using the API.
I know some would say that all users should have the latest Flash, easier said than done. Many schools, companies and libraries lock down the options section in IE so the user would be able to turn off Flash for my site.
I wonder is there some way of turning off Flash when using the API?
I have searched around Stackoverflow and elsewhere and while I have found similar issues I have not found any fixes. I did find a somewhat similar promising lead but alas I had no joy. Also here and here and here and here and here.
I must point out that the issue is present when used on a local machine and on a website and even if I set the origin parameter.
I would appreciate suggestions and help. Thanks in advance.
I wonder is there some way of turning off Flash when using the API?
You could force the YouTube player to use its html5 player using the following option:
playerVars: {html5: 1}
Changing your code to:
// 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: '640',
videoId: 'M7lc1UVf-VE',
playerVars: {
html5: 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
I want to use the YT.Player code so that I can detect events. I have a CSV file with Youtube video ID's and a function that puts the ID's in an array and want to be able to dynamically change the ID when a user click an image. Essentially like this:
html
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
javascript
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "//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.
// NOTE: videoId is taken out and instead is placed as the generated IFRAME src from the postSelection function
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('player', {
height: '100%',
width: '100%',
videoId: '<<CALL TO FUNCTION OR VARIABLE HERE>>',
events: {
//'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
If you are familiar with this code then what happens is the #player DIV is replaced by an IFRAME. I can change the IFRAME source with this function:
function postSelection() {
$("#player").attr("src", _selected.attributes.url); //_selected.attributes.url comes from the CVS file
}
But this is very buggy and not cross browser friendly. If I use a standard IFRAME and not the YT Player API then everything works just fine. But I want to detect the end, and pause and so on so I have to use the API. My guess is that it is an issue with state and that persistence is lost some where in the creation of the IFRAME.
Regards.
This is very simple to do with the js api. When you want to load a new video just call player.loadVideoById(videoId); Details at https://developers.google.com/youtube/iframe_api_reference#loadVideoById
In case this is of help to anyone struggling as I did...
This player.loadVideoById(videoId) was only working for me when videoId was hardcoded e.g.
player.loadVideoById('sdfexxdfse')
When I tried to put that value into a variable directly or when storing in an array it wasn't working even though it contained the same information.
The video was coming up with incorrect parameter each time.
Adding it to a variable in this way
var x = new String(variabledatahere)
did the job.