Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncaught TypeError: this.pluginApi.setSrc is not a function #1759

Closed
scotepi opened this issue Jun 15, 2016 · 7 comments
Closed

Uncaught TypeError: this.pluginApi.setSrc is not a function #1759

scotepi opened this issue Jun 15, 2016 · 7 comments

Comments

@scotepi
Copy link

scotepi commented Jun 15, 2016

When changing the src of a YouTube video with player.setSrc() there is an error that it is not a function.

    <script src="/Libs/mediaelementjs/build/jquery.js"></script>
    <script src="/Libs/mediaelementjs/build/mediaelement-and-player.min.js"></script>
    <link rel="stylesheet" href="/Libs/mediaelementjs/build/mediaelementplayer.css" />
<video width="640" height="360" id="player" preload="none">
    <source id="playerSource" type="video/youtube" src="//www.youtube.com/watch?v=KbUsKWbOqUU" />
</video>

<a onclick="play('9YhTOUu06EY')" href="javascript:void(0);">Test</a>

<script type="text/javascript">
var player = false;
jQuery(document).ready(function($) {
    player = new MediaElementPlayer('#player', {
    });
});

function play(vid) {
    var src = '//www.youtube.com/watch?v='+vid;

    console.log('play', src);
    player.pause();
    player.setSrc(src);
    player.load();
    player.play();
}
</script>
@ghost
Copy link

ghost commented Aug 5, 2016

i got the same probleme today with some diging i answered myself
you can find it here
answer

@rafa8626
Copy link
Contributor

@scotepi Is this still an issue?

@dazweeja
Copy link

This is still an issue in 2.22.0. It occurs at line 754 of mediaelement-and-player.js when pluginType is 'youtube':

this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(url));

This fails because 'this.pluginApi' is a YT.Player which doesn't have a setSrc method. It will need to be replaced with some code like this to work:

if (this.pluginType == 'youtube') {
  var videoId;
  // youtu.be url from share button
  if (url.lastIndexOf("youtu.be") != -1) {
    videoId = url.substr(url.lastIndexOf('/')+1);
    if (videoId.indexOf('?') != -1) {
      videoId = videoId.substr(0, videoId.indexOf('?'));
    }
  }
  else {
    // https://www.youtube.com/watch?v=
    var videoIdMatch = url.match( /[?&]v=([^&#]+)|&|#|$/ );
    if ( videoIdMatch ) {
      videoId = videoIdMatch[1];
    }
  }
  this.pluginApi.loadVideoById(videoId);
}
else {
  this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(url));
}

Or alternatively delete the exisiting player and create a new one. There'll be a similar issue at line 760.

@rafa8626
Copy link
Contributor

Thanks for your comments. I'll check the code above with YouTube and native player to make sure everything is fine and I'll add it to the core method. Thanks!

@dazweeja
Copy link

dazweeja commented Aug 24, 2016

I've been playing around some more with this and one issue is that loadVideoById from the YouTube API will autoplay regardless of the current state of the player. This seems undesirable. I implemented an event-based solution to this and then struck another issue where removeEventListener does not seem to be functional on the YouTube API. Anyway, I do have a working solution which autoplays the video if the current video is playing, or loads the video in a paused state if it's not:

if (this.pluginType == 'youtube') {
    var videoId;
    // youtu.be url from share button
    if (url.lastIndexOf("youtu.be") != -1) {
        videoId = url.substr(url.lastIndexOf('/')+1);
        if (videoId.indexOf('?') != -1) {
            videoId = videoId.substr(0, videoId.indexOf('?'));
        }
    }
    else {
        // https://www.youtube.com/watch?v=
        var videoIdMatch = url.match( /[?&]v=([^&#]+)|&|#|$/ );
        if ( videoIdMatch ) {
            videoId = videoIdMatch[1];
        }
    }
    /* removeEventListener not working on YouTube API - see https://code.google.com/p/gdata-issues/issues/detail?id=6700 */
    function addRemovableEventListener (player, eventName, callback) {
        var callbackName = 'youtubeCallbackFunction' + Math.random().toString(36).substr(2, 7);
        window[callbackName] = callback;
        player.addEventListener(eventName, callbackName);

        return function () {
            window[callbackName] = function () {}; // make the callback inactive
        };
    }
    function onCustomStateChange(e) {
        if (e.data == 1) {
            removeThisListener();
            e.target.pauseVideo();
            e.target.seekTo(0);
        }
    }
    if (this.pluginApi.getPlayerState() != 1) {
        var removeThisListener = addRemovableEventListener(this.pluginApi, 'onStateChange', onCustomStateChange);
    }
    this.pluginApi.loadVideoById(videoId);
}
else {
    this.pluginApi.setSrc(mejs.Utility.absolutizeUrl(url));
}

@rafa8626
Copy link
Contributor

@dazweeja I created a PR based on your comments; please test it and let me know if it works for you

@rafa8626
Copy link
Contributor

rafa8626 commented Sep 1, 2016

Closing issue since fix has been merged

@rafa8626 rafa8626 closed this as completed Sep 1, 2016
@rafa8626 rafa8626 removed the Bug label Sep 1, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants