For the first video, the user needs to click the iframe's "play"
button. But after that subsequent videos can be loaded and played
using loadVideoById. However, after playing 4 or 5 videos, the player
stalls in the "buffering" state (state 3). The only way I can set to
restart the video at that point is to click on the video area which
will cause the play button to appear.
<html>
<body>
<!-- 1. The <div> tag will contain the <iframe> (and video player)
-->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_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 onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'u1zgFlCw8Aw',
playerVars: {
'autoplay': 1,
'start': 0,
'controls': 0,
'rel': 0,
'modestbranding': 1,
'showinfo': 0,
'showsearch': 0,
'disablekb': 1
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange,
'onError': onError
}
});
}
// 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),
function onPlayerStateChange(event) {
var state = player && player.getPlayerState ?
player.getPlayerState() : -1;
console.log("onPlayerStateChange: state=" + state);
}
function onError(event) {
console.log("ERROR!");
}
> For the first video, the user needs to click the iframe's "play" > button. But after that subsequent videos can be loaded and played > using loadVideoById. However, after playing 4 or 5 videos, the player > stalls in the "buffering" state (state 3). The only way I can set to > restart the video at that point is to click on the video area which > will cause the play button to appear.
> <html> > <body> > <!-- 1. The <div> tag will contain the <iframe> (and video player) > --> > <div id="player"></div>
> <script> > // 2. This code loads the IFrame Player API code asynchronously. > var tag = document.createElement('script'); > tag.src = "http://www.youtube.com/player_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 onYouTubePlayerAPIReady() { > player = new YT.Player('player', { > height: '390', > width: '640', > videoId: 'u1zgFlCw8Aw', > playerVars: { > 'autoplay': 1, > 'start': 0, > 'controls': 0, > 'rel': 0, > 'modestbranding': 1, > 'showinfo': 0, > 'showsearch': 0, > 'disablekb': 1 > }, > events: { > 'onReady': onPlayerReady, > 'onStateChange': onPlayerStateChange, > 'onError': onError > } > }); > }
> // 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), > function onPlayerStateChange(event) { > var state = player && player.getPlayerState ? > player.getPlayerState() : -1; > console.log("onPlayerStateChange: state=" + state); > }
> function onError(event) { > console.log("ERROR!"); > }
> Thanks; I can reproduce that and have let the Players engineering
> team know. I'll update this thread with more info when I hear back.
> Cheers,
> -Jeff Posnick, YouTube API Team
> groups.google.com/group/youtube-api-gdata | apiblog.youtube.com |
> @YouTubeDev
> On Oct 20, 8:58 pm, Bruce <bruce.schwa...@gmail.com> wrote:
> > For the first video, the user needs to click the iframe's "play"
> > button. But after that subsequent videos can be loaded and played
> > using loadVideoById. However, after playing 4 or 5 videos, the player
> > stalls in the "buffering" state (state 3). The only way I can set to
> > restart the video at that point is to click on the video area which
> > will cause the play button to appear.
> > // 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),
> > function onPlayerStateChange(event) {
> > var state = player && player.getPlayerState ?
> > player.getPlayerState() : -1;
> > console.log("onPlayerStateChange: state=" + state);
> > }
On Tue, Nov 8, 2011 at 5:20 PM, Bruce <bruce.schwa...@gmail.com> wrote: > Any update on this?
> On Oct 24, 12:03 pm, Jeffrey Posnick <je...@google.com> wrote: > > Hello Bruce,
> > Thanks; I can reproduce that and have let the Players engineering > > team know. I'll update this thread with more info when I hear back.
> > Cheers, > > -Jeff Posnick, YouTube API Team > > groups.google.com/group/youtube-api-gdata | apiblog.youtube.com | > > @YouTubeDev
> > On Oct 20, 8:58 pm, Bruce <bruce.schwa...@gmail.com> wrote:
> > > For the first video, the user needs to click the iframe's "play" > > > button. But after that subsequent videos can be loaded and played > > > using loadVideoById. However, after playing 4 or 5 videos, the player > > > stalls in the "buffering" state (state 3). The only way I can set to > > > restart the video at that point is to click on the video area which > > > will cause the play button to appear.
> > > I've attached the code if you want to try it yourself... it is based > > > on the sample code athttp:// > code.google.com/apis/youtube/iframe_api_reference.html.
> > > <html> > > > <body> > > > <!-- 1. The <div> tag will contain the <iframe> (and video player) > > > --> > > > <div id="player"></div>
> > > <script> > > > // 2. This code loads the IFrame Player API code asynchronously. > > > var tag = document.createElement('script'); > > > tag.src = "http://www.youtube.com/player_api"; > > > var firstScriptTag = document.getElementsByTagName('script')[0]; > > > firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
> > > // 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), > > > function onPlayerStateChange(event) { > > > var state = player && player.getPlayerState ? > > > player.getPlayerState() : -1; > > > console.log("onPlayerStateChange: state=" + state); > > > }
> -- > You received this message because you are subscribed to the Google Groups > "YouTube APIs Developer Forum" group. > To post to this group, send email to youtube-api-gdata@googlegroups.com. > To unsubscribe from this group, send email to > youtube-api-gdata+unsubscribe@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/youtube-api-gdata?hl=en.
"This is an iOS bug which I think can be improved by not creating new
video tags on every playback...
"We have a limit right now arbitrarily set to 4. Until we figure out
the right way to hold onto good video tags, we'll have this problem no
matter what...this will probably take a while to get resolved."
Best Regards,
-jj
On Nov 9, 2:25 pm, Shannon -jj Behrens <jji...@google.com> wrote:
> > > On Oct 20, 8:58 pm, Bruce <bruce.schwa...@gmail.com> wrote:
> > > > For the first video, the user needs to click the iframe's "play"
> > > > button. But after that subsequent videos can be loaded and played
> > > > using loadVideoById. However, after playing 4 or 5 videos, the player
> > > > stalls in the "buffering" state (state 3). The only way I can set to
> > > > restart the video at that point is to click on the video area which
> > > > will cause the play button to appear.
> > > > I've attached the code if you want to try it yourself... it is based
> > > > on the sample code athttp://
> > code.google.com/apis/youtube/iframe_api_reference.html.
> > > > <html>
> > > > <body>
> > > > <!-- 1. The <div> tag will contain the <iframe> (and video player)
> > > > -->
> > > > <div id="player"></div>
> > > > <script>
> > > > // 2. This code loads the IFrame Player API code asynchronously.
> > > > var tag = document.createElement('script');
> > > > tag.src = "http://www.youtube.com/player_api";
> > > > var firstScriptTag = document.getElementsByTagName('script')[0];
> > > > firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
> > > > // 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),
> > > > function onPlayerStateChange(event) {
> > > > var state = player && player.getPlayerState ?
> > > > player.getPlayerState() : -1;
> > > > console.log("onPlayerStateChange: state=" + state);
> > > > }
> > --
> > You received this message because you are subscribed to the Google Groups
> > "YouTube APIs Developer Forum" group.
> > To post to this group, send email to youtube-api-gdata@googlegroups.com.
> > To unsubscribe from this group, send email to
> > youtube-api-gdata+unsubscribe@googlegroups.com.
> > For more options, visit this group at
> >http://groups.google.com/group/youtube-api-gdata?hl=en.
I've been bitten by this bug, too. It is rather frustrating because my site relies on the ability to move from video to video as a result of events that are fired or user clicks. If it wasn't for the restrictions on autoplay on the iPad, I would just destroy the player and reinitialize it for each video. The advantage to using the load and cue functions was that the viewer only had to explicitly click the video once to begin playback and then I could control it properly from there, even as I moved to different videos. However, in most cases they will be seeing more than 4 videos, so that arbitrary cap is very problematic.
As this has now been a known issue for about 9 months, are we getting any closer to a solution? My site is perhaps most useful when accessed from a tablet device, so not being able to support the iPad is clearly an issue for us.
On Thursday, October 20, 2011 8:58:30 PM UTC-4, Bruce wrote:
> For the first video, the user needs to click the iframe's "play" > button. But after that subsequent videos can be loaded and played > using loadVideoById. However, after playing 4 or 5 videos, the player > stalls in the "buffering" state (state 3). The only way I can set to > restart the video at that point is to click on the video area which > will cause the play button to appear.
> <html> > <body> > <!-- 1. The <div> tag will contain the <iframe> (and video player) > --> > <div id="player"></div>
> <script> > // 2. This code loads the IFrame Player API code asynchronously. > var tag = document.createElement('script'); > tag.src = "http://www.youtube.com/player_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 onYouTubePlayerAPIReady() { > player = new YT.Player('player', { > height: '390', > width: '640', > videoId: 'u1zgFlCw8Aw', > playerVars: { > 'autoplay': 1, > 'start': 0, > 'controls': 0, > 'rel': 0, > 'modestbranding': 1, > 'showinfo': 0, > 'showsearch': 0, > 'disablekb': 1 > }, > events: { > 'onReady': onPlayerReady, > 'onStateChange': onPlayerStateChange, > 'onError': onError > } > }); > }
> // 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), > function onPlayerStateChange(event) { > var state = player && player.getPlayerState ? > player.getPlayerState() : -1; > console.log("onPlayerStateChange: state=" + state); > }
> function onError(event) { > console.log("ERROR!"); > }
I should also add that this problem also appears to be present on Android 4.1. Additionally, this isn't limited to the cue and load functions for individual items, but for playlists as well. The HTML5 player does not appear to be able to handle playlists larger than 4 videos without becoming entirely unresponsive on iOS or Android. I have tried every possible workaround imaginable with no luck.
My apologies for the onslaught of posts here, but I had an opportunity to dig a bit deeper into exactly what is happening within the player code on these mobile devices, and I now more thoroughly understand the dilemma that is being faced. As I understand it, since the browser restricts any programmatic control from happening until the user explicitly clicks the video to start playback, and since it was apparently decided to be desirable to use a new video tag for each video loaded/cued in the player, the development team elected to create a tag pool once the user clicks to start the first video. It looks like these tags can be controlled programmatically without additional intervention because they were created in response to the initial click. Probably to find a good balance between performance and the functionality required in the majority of use cases, the pool size was fixed at 4, as was indicated earlier. When that pool is exhausted, new video tags are created on each subsequent cue or load. However, since these new tags were not created in response to the user's explicit click on the video, playback can't begin for them without intervention. Trying to initiate playback causes the buffering animation to appear, which obscures the big red play button, effectively rendering the player useless at that point.
I see two possible resolutions to this problem:
1.) Allow developers to override the default pool size when creating the player object - This could be a quick and easy way to at least get this player functional for those that need it. If we had a property like "poolsize" or the like, then we could simply select a value that is suitable for the size of our playlist or the expected usage patterns of the site. I was concerned about the performance implications of using much larger pool sizes, but it appears that I can create about 70 video tags per second on my Galaxy Nexus. Given that buffering is typically going to take longer than that, it doesn't seem that disruptive to the overall user experience. There are other resource utilization questions that come into play, too, but I didn't see anything to suggest that it would be a major drain to use something like 50 or even 100 tags in the pool. I could easily track where we are at in the pool so if it still eneded up getting exhausted, I could just destroy the player and create a new one. I'd do that now except that 4 videos is simply too small to be feasible for us.
2.) Do away with the pool altogether - I think this is essentially the long term solution suggested by the software engineer quoted earlier in the thread. Honestly, I couldn't determine what the reason was for introducing the pool in the first place. I tested with my own test page, and later with the player demo page, after modifying the player script to always return the first tag in the pool instead of working through the pool on each load/cue. I saw no fundamental difference in the way that approach worked relative to the default pool implementation, making me question why the pool was needed. Perhaps it was a workaround for some other issue of which I'm unaware, since the engineer talked about "holding on to good video tags." Obviously this would be the best ultimate resolution, since there aren't resource and performance concerns. It would also reduce some code complexity, too.
I don't know what the other implications to resolution 2 might be, which is why the first resolution could be a good way to at least eliminate a roadblock for us quickly while buying more time to implement and test a "poolless" approach.
On Friday, July 20, 2012 2:21:15 AM UTC-4, Ted Cannelongo wrote:
> I should also add that this problem also appears to be present on Android > 4.1. Additionally, this isn't limited to the cue and load functions for > individual items, but for playlists as well. The HTML5 player does not > appear to be able to handle playlists larger than 4 videos without becoming > entirely unresponsive on iOS or Android. I have tried every possible > workaround imaginable with no luck.
Interesting info. I detected this buffer in practice. I think it main purpose to show one advertising video before main video and one advertising video after. And to keep place for one more advertising video is in reserve. This allow to show advertising videos without modification of main video. But this is my opinion only, based on common-sense logic. And I used this buffer to show 4 movies in line using simple counter. After four videos was played I recreate video player and wait for user initiated start. This is slight annoying, but better then nothing.
понедельник, 23 июля 2012 г., 8:35:59 UTC+3 пользователь Ted Cannelongo написал:
> My apologies for the onslaught of posts here, but I had an opportunity to > dig a bit deeper into exactly what is happening within the player code on > these mobile devices, and I now more thoroughly understand the dilemma that > is being faced. As I understand it, since the browser restricts any > programmatic control from happening until the user explicitly clicks the > video to start playback, and since it was apparently decided to be > desirable to use a new video tag for each video loaded/cued in the player, > the development team elected to create a tag pool once the user clicks to > start the first video. It looks like these tags can be controlled > programmatically without additional intervention because they were created > in response to the initial click. Probably to find a good balance between > performance and the functionality required in the majority of use cases, > the pool size was fixed at 4, as was indicated earlier. When that pool is > exhausted, new video tags are created on each subsequent cue or load. > However, since these new tags were not created in response to the user's > explicit click on the video, playback can't begin for them without > intervention. Trying to initiate playback causes the buffering animation > to appear, which obscures the big red play button, effectively rendering > the player useless at that point.
> I see two possible resolutions to this problem:
> 1.) Allow developers to override the default pool size when creating the > player object - This could be a quick and easy way to at least get this > player functional for those that need it. If we had a property like > "poolsize" or the like, then we could simply select a value that is > suitable for the size of our playlist or the expected usage patterns of the > site. I was concerned about the performance implications of using much > larger pool sizes, but it appears that I can create about 70 video tags per > second on my Galaxy Nexus. Given that buffering is typically going to take > longer than that, it doesn't seem that disruptive to the overall user > experience. There are other resource utilization questions that come into > play, too, but I didn't see anything to suggest that it would be a major > drain to use something like 50 or even 100 tags in the pool. I could > easily track where we are at in the pool so if it still eneded up getting > exhausted, I could just destroy the player and create a new one. I'd do > that now except that 4 videos is simply too small to be feasible for us.
> 2.) Do away with the pool altogether - I think this is essentially the > long term solution suggested by the software engineer quoted earlier in the > thread. Honestly, I couldn't determine what the reason was for introducing > the pool in the first place. I tested with my own test page, and later > with the player demo page, after modifying the player script to always > return the first tag in the pool instead of working through the pool on > each load/cue. I saw no fundamental difference in the way that approach > worked relative to the default pool implementation, making me question why > the pool was needed. Perhaps it was a workaround for some other issue of > which I'm unaware, since the engineer talked about "holding on to good > video tags." Obviously this would be the best ultimate resolution, since > there aren't resource and performance concerns. It would also reduce some > code complexity, too.
> I don't know what the other implications to resolution 2 might be, which > is why the first resolution could be a good way to at least eliminate a > roadblock for us quickly while buying more time to implement and test a > "poolless" approach.
> On Friday, July 20, 2012 2:21:15 AM UTC-4, Ted Cannelongo wrote:
>> I should also add that this problem also appears to be present on Android >> 4.1. Additionally, this isn't limited to the cue and load functions for >> individual items, but for playlists as well. The HTML5 player does not >> appear to be able to handle playlists larger than 4 videos without becoming >> entirely unresponsive on iOS or Android. I have tried every possible >> workaround imaginable with no luck.
Just answering to this post to mention that I (dutch developer) ran into this problem as well...
I can see how this bug might seem insignificant, but actually it's a pretty big issue as it prevents me from building an attractive user experience. It's bad enough that apple prevents autoplay, but clicking on a 'play' button every 4 videos will simply be too annoying for most users.
Really a pity.
Gr. Kev
Op vrijdag 10 augustus 2012 17:00:08 UTC+2 schreef Jeffrey Posnick het volgende:
Never heard back on this, so I'm just following up again. It would be extremely helpful for us for there to be some movement on this issue. I previously provided two possible ways in which to modify the API so that those of us needing continuous play could get our applications working properly on devices requiring HTML5. A little more detail:
1.) The first resolution was to simply allow us to change the size of the video tag pool. In the present API source, when the user first initiated playback, one of the things that happens is the initialization of a pool of video tags via the call:
ql.fillPool(4);
What I'm requesting is that we be provided with a way to override the hardcoded 4 and pick something else. For example, I might instantiate the player like this:
player = new YT.Player('player', { height: '390', width: '640', poolsize: '40', events: { 'onReady': onPlayerReady, 'onError': onError, 'onStateChange': onPlayerStateChange }
});
The "poolsize" would then get used instead of the default of 4 when calling fillPool so that I can play 40 consecutive videos without stopping. This seems like it would be realtively easy to implement. Other than perhaps providing a warning to developers that excessive pool sizes could impact performace, it could be implemented with confidence that it wouldn't impact any existing API users, as their current code would still use the default of 4 tags. Given that we've been waiting on a fix for a year now, this is at least would provide some flexibility for developers so that we aren't limited by the "arbitrarily" selected cap.
2.) As I mentioned previously, the other option is to reuse an existing video tag rather than creating a new one. There's a function in the API right now that is as follows:
I changed the single line of code in that function to instead read:
return this.a[0];
After doing so, I could play as many videos consecutively as I wanted. Granted, this would entail testing across multiple platforms and OS versions to ensure that there aren't and side-effects from reusing the same video tag repeatedly, and I completely understand that would take time. I also understand that this isn't truly a single-line fix, since if this approach were found acceptable, it would be necessary to clean up the code to remove the portions related to the creation of the video tag pool. I just thought it might be helpful to show the code to better explain my point above.