brandly / angular-youtube-embed

:tv: Embed a YouTube player with a simple directive

Home Page:http://brandly.github.io/angular-youtube-embed/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Use existing player on video change

Sivitas opened this issue · comments

You're currently destroying the player and calling createPlayer every time the video id (or url/play list) is being changed. I think YouTube just updated their API's to stop this as my site started breaking.

Not sure if there are other use cases that might break this, but my current work around is to modify your loadPlayer function to check if the player exists, and instead of creating a new one, use player.loadVideoById to update the id. There are similar calls for load by url and for playlists.

src: https://developers.google.com/youtube/iframe_api_reference#loadVideoById

Oh this does change the behavior of event 'youtube.player.ready' as it'll only trigger the first time the player loads as opposed to anytime a video changes

Upon further investigation, I believe what changed with the YouTube embed API is that they are now deleting the target div you attach the iframe to. So instead of adding the iframe as a child of the element, they're replacing the element with the iframe. That's why your current implementation breaks, because createPlayer can't find the id anymore.

Not sure if this was a mistake or done on purpose by Google

I thought I was going mad this morning after coming into my project and finding that transitions between videos was broken (but was working last night when I left work!).

Should I be updating with what you were talking about Sivitas in your first comment?

My scenario: My application runs through a schedule of videos throughout the day using the your module to play new videos one after the other. At the moment, even though I set the player ID and Params, the player does not update.

Edit: My temporary change is not great but your suggestion lets me continue working until the module is updated. Thanks Sivitas.

function loadPlayer () {
    if(scope.player) {
        var playerVars = ( playerVars ? playerVars : angular.copy(scope.playerVars) );
        playerVars.start = playerVars.start || scope.urlStartTime;
        if (scope.videoId) {
            scope.player.loadVideoById({
                videoId:scope.videoId, 
                startSeconds:playerVars.start
            });
        }
        else if(scope.playerVars.list) {
            scope.player.loadPlaylist({
                playlist:scope.playerVars.list, 
                startSeconds:playerVars.start
            });
        }
    }
    else if(scope.videoId || scope.playerVars.list) {
        scope.player = createPlayer();
    }
};

Same problem here.
Would be nice to have a fix.
Hope somebody is already on it. I'll spend some time around it during this weekend, as it's quite an essential thing for my site to work :)

Following @steveglachan suggestion, I've made this pull request that should fix the problem.
It's basically @steveglachan 's snippet with some tweaks that solved my case.
loadVideo checks if the player and the respective iframe are in scope, avoiding to create a new one.
@Sivitas yes, this will trigger ready event only when the video is recreated, so it will break something if you were expecting that event to be triggered each time video changes. I believe you're right in saying that YT is now replacing the whole element with an iframe, insteading of putting an iframe inside it.
Would be good to try with another approach, that could be using a wrapper inside the directive so that it doesn't get destroyed altogether with the iframe.

Experienced this problem as well, however had issues with the pull request above. The following simple fix worked without any other problems: #49

@rramdat-i That fix does appear to work, seems like the simplest way to go about it without breaking existing features.

I still don't like that it's deleting the entire player every time though, seems like an inefficient way to change videos when there are APIs available for it (at least now, I get that they might not have been available when this library was built)

Hello, everyone! Thanks for all the feedback. I'm slightly confused about the root of this problem, since a personal project of mine that uses this repo seems to still be working just fine.

Also, it sounds like removing the player.d check is fixing it for people, but it looks like that check fixed some issues a while back, so I'm hesitant to remove it. Maybe the player behaves differently now, and those are now longer issues. Maybe @speed-of-light or @Kareem3d can provide some insight.

@rramdat-i what happened when you tried the code from #48? What issues did you have?

Thanks again for all the help! I'll try to get to the bottom of this.

commented

I have this problem too. Everything worked fine last week, but yesterday changing videos using the video-id attribute started throwing errors like

$scope.yt_player.pauseVideo is not a function

hey! in case you didn't see #52, as of v1.0.2, things should be working again. changes in the underlying YouTube library broke functionality. relying on the player.d check wasn't a good idea, since that's a minified variable within some code that i don't have any control over

i'm leaving this issue open since it sounds more efficient to use the same player, but i haven't gotten around to implementing this yet. thanks again for all the feedback 🌟

As far as I recall, I added that check because player.d was the method
that YT library was internally calling on player destroy().
Now that the player isn't getting destroyed anymore at every video change,
it makes definitely sense to remove it - they have probably removed .d
method from the lib altogether.

On 7 May 2015 at 11:18, Matthew Brandly notifications@github.com wrote:

hey! in case you didn't see #52
#52, as of v1.0.2,
things should be working again. changes in the underlying YouTube library
broke functionality. relying on the player.d check wasn't a good idea,
since that's a minified variable within some code that i don't have any
control over

i'm leaving this issue open since it sounds more efficient to use the same
player, but i haven't gotten around to implementing this yet. thanks again
for all the feedback [image: 🌟]

Reply to this email directly or view it on GitHub
#46 (comment)
.