Hi all

Im having a struggle here. I know very basic Jquery, and are reading up on on the YouTube API, but I cant seem to find how to do this. I downloaded a script for a custom YouTube player, and everything is good. I modified it to my needs.

The problem is, I want to make a callback when the video has ended but I dont know how to call it in. I want to write a script that redirects me to the next video when the current one has ended.

Heres the code for the custom player:

(function ($) {
    $.fn.customYtPlayer = function (options) {

        var youtubeAPI = "http://gdata.youtube.com/feeds/api/videos?v=2&alt=jsonc";
        var settings = {};

        // Default values
        options = $.extend({
            width: '100%',
            onPlay: null,
            onPause: null,
            onEnd: null,
            onUnstarted: null
        },
        options);

        // Format Timer (hh:mm:ss)
        function formatTime (second, hour, minute) {
            if (second > 3600) {
                var ore = Math.floor(second / 3600);
                if(ore < 10) ore = "0" + ore;
                var rest = Math.ceil(second % 3600);
                var format = formatTime (rest, ore);
            } else if (second > 60) {
                var minuti = Math.floor(second / 60);
                if(minuti < 10) minuti = "0" + minuti;
                var rest = Math.ceil(second % 60);
                var format = formatTime (rest, ore, minuti);
            } else if (second < 60) {
                if (!hour) hour = "00";
                if (!minute) minute = "00";
                if (!second) {
                    second = "00";
                } else {
                    second = Math.round(second);
                    if (second < 10) {
                        second = "0" + second;
                    }
                }
                var format = hour + ":" + minute + ":" + second;
            }
            return format;
        };

        // Video ID Extractor
        function youtubeIDextract (url) { 
            var youtube_id; 
            youtube_id = url.replace(/^[^v]+v.(.{11}).*/, "$1"); 
            return youtube_id; 
        }

        if (this.length > 0) {

            var lastDate;

            this.each(function (index, domElement) {

                // UNIQUE ID
                // is an unique identifier of video, ready for use as a function name
                var curDate = new Date().getTime();
                var uniqId = (lastDate === curDate) ? (curDate + 1000) : curDate;

                // SETTINGS
                settings[uniqId] = {};
                settings[uniqId].that = $(this);
                settings[uniqId].safeID = uniqId;

                // CHECK VIDEO URL AND EXTRACT VIDEO ID
                var href = $(this).attr("href");
                if (!href || !href.length) {
                    return false;
                } else {
                    if (href.match(/^http:\/\/(?:www\.)?youtube.com\/watch\?(?=.*v=\w+)(?:\S+)?$/)) {
                        videoID = youtubeIDextract(href);
                    } else {
                        return false;
                    }
                }

                // WIDTH
                var width = $(this).width();
                settings[uniqId].width = (!width || width <= 0) ? Math.round(options.width) : Math.round(width);

                // Fetch data about the video from YouTube's API
                $.get(youtubeAPI, {'q': videoID}, function (response) {

                    // If the video was not found, or embedding is not allowed;
                    if (!response.data.totalItems || response.data.items[0].accessControl.embed != "allowed" ) {
                        return false;
                    }

                    // data holds API info about the video:
                    var data = {};
                    data = response.data.items[0];

                    // VIDEO ID
                    settings[uniqId].videoID = data.id;

                    // ASPECT RATIO
                    settings[uniqId].ratio = 3 / 4;
                    if (data.aspectRatio == "widescreen") {
                        settings[uniqId].ratio = 9 / 16;
                    }

                    // HEIGHT
                    settings[uniqId].height = Math.round(settings[uniqId].width * settings[uniqId].ratio);

                    // REPLACE LINK TAG WITH A DIV
                    settings[uniqId].that.replaceWith("<div id=\"customYtPlayer_" + uniqId + "\"></div>");

                    // CONTAINER
                    var elements = {};
                    elements.container = $("#customYtPlayer_" + uniqId).addClass("flashContainer").css({
                        'width': "100%",
                        'height': "100%"
                    });

                    // INSERT FLASH PLAYER
                    elements.container.flash({
                        swf: "http://www.youtube.com/apiplayer?enablejsapi=1&version=3&autoplay=1&vq=1080",
                        id: "video_" + settings[uniqId].safeID,
                        height: '100%',
                        width: '100%',
                        allowScriptAccess: "always",
                        wmode: "transparent",
                        flashvars: {
                            "video_id" : settings[uniqId].videoID,
                            "playerapiid" : settings[uniqId].safeID
                        }
                    });

                    // THE FLASH PLAYER
                    // We use get, because we need the DOM element
                    // itself, and not a jquery object:
                    elements.player = elements.container.flash().get(0);

                    // PLAYER CONTROLLER
                    elements.control = $("<div class=\"flashControl\"></div>").appendTo(elements.container); // A Controller container div, inserted by the plugin
                    // PLAY/PAUSE ON CLICK EVENT
                    elements.play = $("<a href=\"#\" class=\"flashPlay\"></a>").appendTo(elements.control) // The control play/pause button
                    .click(function (e) {
                        if(!elements.container.hasClass("playing")){
                            elements.player.playVideo();
                        } else {
                            elements.player.pauseVideo();
                        }
                        return false;
                    });
                    elements.current = $("<div class=\"flashCurrent\"></div>").appendTo(elements.control); // Current elapsed time
                    elements.volume = $("<div class=\"flashVolume\"></div>").appendTo(elements.control); // The control sound volume
                    for (var i = 0; i < 10; i++) {
                        // VOLUME ON CLICK EVENT
                        $("<div rel=\"volume_" + i + "\" class=\"flashCursor\"></div>").appendTo(elements.volume) // The control sound volume cursor
                        .click(function (e) {
                            var index = $(this).attr("rel").replace("volume_", "");
                            if (index >= 0 && index < 10) {
                                $("div.flashCursor:lt(" + (index + 1) + ")", elements.control).addClass("selected");
                                $("div.flashCursor:gt(" + index + ")", elements.control).removeClass("selected");
                                volume = (Math.round(index) + 1) * 10;
                                if (volume < 0) volume = 0;
                                if (volume > 100) volume = 100;
                                elements.player.setVolume(volume);
                            }
                            return false;
                        });
                    }
                    $("<div class=\"flashClear\"></div>").appendTo(elements.volume)
                    // MUTE ON CLICK EVENT
                    elements.mute = $("<a href=\"#\" class=\"flashMute\"></a>").appendTo(elements.control) // The control sound mute
                    .click(function (e) {
                        if(elements.player.isMuted()){
                            elements.container.removeClass("muted");
                            elements.player.unMute();
                        } else {
                            elements.container.addClass("muted");
                            elements.player.mute();
                        }
                        return false;
                    });
                    elements.duration = $("<div class=\"flashDuration\"></div>").appendTo(elements.control); // Duration of the video
                    elements.progress = $("<div class=\"flashProgress\"></div>").appendTo(elements.control); // Progress bar
                    elements.elapsed = $("<div class=\"flashElapsed\"></div>").appendTo(elements.progress); // The light blue elapsed bar
                    $("<div class=\"flashClear\"></div>").appendTo(elements.control);

                    // START TIME AND DURATION
                    elements.current.html(formatTime(0));
                    elements.duration.html(formatTime(data.duration));

                    // PROGRESS BAR ON CLICK EVENT
                    elements.progress.click(function (e) {
                        // When a click occurs on the progress bar, seek to the
                        // appropriate moment of the video.
                        var ratio = (e.pageX - elements.progress.offset().left) / elements.progress.outerWidth();
                        elements.elapsed.width((ratio * 100) + "%");
                        elements.player.seekTo(Math.round(data.duration * ratio), true);
                        return false;
                    });

                    // CONTAINER ON HOVER EVENT (IE6 HACK)
//                  elements.container.hover(function (e) {
//                      elements.control.css({
//                          'display': 'block'
//                      });
//                  }, function (e) {
//                      elements.control.css({
//                          'display': 'none'
//                      });
//                  });

                    var interval = false;

                    // PLAYER EVENT LISTENER
                    // Creating a global event listening function for the video
                    // (required by YouTube's player API):
                    window["eventListener_" + settings[uniqId].safeID] = function (status) {
                        if (status == -1) {
                            // unstarted 
                            if(elements.player.isMuted()){
                                elements.container.addClass("muted");
                            } else {
                                elements.container.removeClass("muted");
                            }

                            var volume = elements.player.getVolume();
                            var index = Math.round(volume / 10);
                            $("div.flashCursor:lt(" + (index + 1) + ")", elements.control).addClass("selected");

                            // On Unstarted Event
                            if($.isFunction(options.onUnstarted)){
                                options.onUnstarted(elements.container);
                            }
                        }
                        else if (status == 0) {
                            // ended 
                            window.clearInterval(interval);
                            interval = false;
                            elements.current.html(formatTime(0));
                            elements.elapsed.width("0");
                            elements.container.removeClass("playing");

                            // On End Event
                            if($.isFunction(options.onEnd)){
                                options.onEnd(elements.container);
                            }
                        }
                        else if (status == 1) {
                            // playing 
                            elements.container.addClass("playing");

                            // Progress Bar updater
                            if (!interval) {
                                interval = window.setInterval(function () {
                                    elements.elapsed.width(((elements.player.getCurrentTime() / data.duration) * 100) + "%");
                                    elements.current.html(formatTime(elements.player.getCurrentTime()));
                                }, 1000);
                            }

                            // On Play Event
                            if($.isFunction(options.onPlay)){
                                options.onPlay(elements.container);
                            }
                        }
                        else if (status == 2) {
                            // paused 
                            window.clearInterval(interval);
                            interval = false;
                            elements.container.removeClass("playing");

                            // On Pause Event
                            if($.isFunction(options.onPause)){
                                options.onPause(elements.container);
                            }
                        }
                        else if (status == 3) {
                            // buffering 
                            // Actually not used
                        }
                        else if (status == 5) {
                            // video cued 
                            // Actually not used
                        }
                    }

                    // This global function is called when the player is loaded.
                    // It is shared by all the videos on the page:
                    if (!window.onYouTubePlayerReady) {             
                        window.onYouTubePlayerReady = function (playerID) {
                            document.getElementById("video_" + playerID).addEventListener("onStateChange", "eventListener_" + playerID);
                        }
                    }

                },"jsonp");

                lastDate = curDate;

            });
        }
    };
})(jQuery);

I was thinking something like this to test it out, but it alerts "done" on start.

    <script type="text/javascript">
        $(document).ready(function(){
            $('.youtube').customYtPlayer({ onEnd: alert('done') });
        });
    </script>

Anyone can help me?

Member Avatar for LastMitch

The problem is, I want to make a callback when the video has ended but I dont know how to call it in. I want to write a script that redirects me to the next video when the current one has ended.

@brianjoe

What code did you add on? You mention you modify it? Did it work before you modify it?

No I havent modified the actual javascript code, what I ment was that I modified it for my needs CSS wise and implementation wise on my site.

What I have done so far is styling the player and make it open in a popup. So my problem is when the current video ends I need to get the next ID from my database and then tell this script to play this video that has this ID.

I dont know if Im expressing myself well enough.

Click Here

A bad drawing in photoshop explaining how I want it.

Member Avatar for LastMitch

No I havent modified the actual javascript code, what I ment was that I modified it for my needs CSS wise and implementation wise on my site.

@brianjoe

Why did you post this in javascript section?

If the issue is with CSS and how it will appear on your website, why post that you have issue with the script itself?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.