Russian English
jQuery Plugins & Javascript Functions
PHP Classes & Functions
HTML && CSS Frameworks

jQuery Media-Player

Public: 12.12.2015

Download jQuery Media Player last version

jQuery Media-Player — play video and audio files.

Version Changes

1.0.0 - .

jquery.player.js
/*!
 jQuery Media Player 1.0.0
 https://skidanov.ru/dev/jquery-plugins/media-player/
 https://github.com/skidanovdima/jquery-media-player
 */

;(function($){

    $.fn.MediaPlayer = function(config, callbacks) {

        var container = $(this);
        var player = $('<div></div>');
        container.replaceWith(player);

        var defaultConfig = {
            type: 'audio/mp3',
            name: 'Unknown',
            volumeOn: true,
            volume: 1,
            animationSpeedCenteringAfterFullScreen: 100,
            animationSpeedControls: 0,
            timeOutHideControls: 3000,
            size: 'lg',
            classes: {
                main: 'media-player',
                skin: 'default',
                audio: 'audio',
                video: 'video',
                timelineSkin: 'media-player',
                volumelineSkin: 'volume-line',
                name: 'name',
                author: 'author',
                timerAll: 'all',
                timerSeparator: 'separator',
                timerCurrent: 'current',
                timeline: 'timeline',

                container_1: 'container-1',
                cell_1x1: 'cell-1x1',
                container_2: 'container-2',
                cell_2x1: 'cell-2x1',
                cell_2x2: 'cell-2x2',
                cell_2x3: 'cell-2x3',
                cell_2x4: 'cell-2x4',
                container_3: 'container-3',
                cell_3x1: 'cell-3x1',
                cell_3x2: 'cell-3x2',
                cell_3x3: 'cell-3x3',
                cell_3x4: 'cell-3x4',

                controls: 'controls',
                controlsLarge: 'large',
                controlsSmall: 'small',
                playing: 'playing',
                playingPlay: 'play',
                playingPause: 'pause',
                playingRepeat: 'repeat',
                volume: 'volume',
                volumeOff: 'off',
                volumeHalf: 'half',
                volumeFull: 'full',
                volumeline: 'volumeline',
                screen: 'screen',
                max: 'max',
                min: 'min',
                fullScreen: 'full-screen',
                overflowHidden: 'overflow-hidden'
            }
        };
        player.config = $.extend(true, {}, defaultConfig, config);

        var defaultCallbacks = {
            events: function (player) {
            }
        };
        player.callbacks = $.extend(true, {}, defaultCallbacks, callbacks);

        player.addClass(player.config.classes.main).addClass(player.config.classes.skin);
        if (player.config.type.indexOf('audio') > -1) {
            player.addClass(player.config.classes.audio);
        } else if (player.config.type.indexOf('video') > -1) {
            player.addClass(player.config.classes.video);
        }

        if ($.cookie('player.config.volume') && $.cookie('player.config.volume').length > 0) {
            player.config.volume = $.parseJSON($.cookie('player.config.volume'));
        }
        if ($.cookie('player.config.volumeOn') && $.cookie('player.config.volumeOn').length > 0) {
            player.config.volumeOn =  $.parseJSON($.cookie('player.config.volumeOn'));
        }

        $.fn.MediaPlayer.create(player);
        $.fn.MediaPlayer.events(player);

        return player;
    };

    $.fn.MediaPlayer.create = function (player) {

        // Additional components
        player.components = {}; // Components
        player.components.controls = $('<div></div>').addClass(player.config.classes.controls).addClass(player.config.classes.controlsLarge);
        player.components.name = $('<div></div>').addClass(player.config.classes.name);
        player.components.author = $('<div></div>').addClass(player.config.classes.author);
        player.components.all = $('<div></div>').addClass(player.config.classes.timerAll);
        player.components.separator = $('<div> / </div>').addClass(player.config.classes.timerSeparator);
        player.components.current = $('<div></div>').addClass(player.config.classes.timerCurrent);
        player.components.timeline = $('<div></div>').addClass(player.config.classes.timeline);

        if (player.config.type.indexOf('audio') > -1) {
            player.components.media = $('<audio></audio>');
        } else if (player.config.type.indexOf('video') > -1) {
            player.components.media = $('<video></video>');
        }
        player.components.media.attr('type', player.config.type);

        player.components.container_1 = $('<div></div>').addClass(player.config.classes.container_1);
        player.components.cell_1x1 = $('<div></div>').addClass(player.config.classes.cell_1x1);

        player.components.container_2 = $('<div></div>').addClass(player.config.classes.container_2);
        player.components.cell_2x1 = $('<div></div>').addClass(player.config.classes.cell_2x1);
        player.components.cell_2x2 = $('<div></div>').addClass(player.config.classes.cell_2x2);
        player.components.cell_2x3 = $('<div></div>').addClass(player.config.classes.cell_2x3);
        player.components.cell_2x4 = $('<div></div>').addClass(player.config.classes.cell_2x4);

        player.components.container_3 = $('<div></div>').addClass(player.config.classes.container_3);
        player.components.cell_3x1 = $('<div></div>').addClass(player.config.classes.cell_3x1);
        player.components.cell_3x2 = $('<div></div>').addClass(player.config.classes.cell_3x2);
        player.components.cell_3x3 = $('<div></div>').addClass(player.config.classes.cell_3x3);
        player.components.cell_3x4 = $('<div></div>').addClass(player.config.classes.cell_3x4);

        player.components.playing = $('<div></div>').addClass(player.config.classes.playing);
        player.components.volume = $('<div></div>').addClass(player.config.classes.volume);
        player.components.volumeline = $('<div></div>').addClass(player.config.classes.volumeline);

        player.components.screen = $('<div></div>').addClass(player.config.classes.screen).addClass(player.config.classes.max);

        // Setup components
        player.components.media.attr('src', player.config.file);
        player.components.name.html(player.config.name);

        if (player.config.author) {
            player.components.author.html(player.config.author);
        }

        player.components.playing.addClass(player.config.classes.playingPlay);
        if (player.config.volume == 0 || !player.config.volumeOn) {
            player.components.volume.addClass(player.config.classes.volumeOff);
        } else if (player.config.volume < 0.5) {
            player.components.volume.addClass(player.config.classes.volumeHalf);
        } else {
            player.components.volume.addClass(player.config.classes.volumeFull);
        }
        if (player.config.volumeOn) {
            player.components.media[0].volume = player.config.volume;
        } else {
            player.components.media[0].volume = 0;
        }

        if($.fn.Slider) {
            player.components.timeline = player.components.timeline.Slider({
                line: {
                    min: 0,
                    max: 299,
                    step: 1
                },
                DefaultValue:  0,
                classes: {skin: player.config.classes.timelineSkin},
                partsOn: false,
                titlesOn: false,
                loadedOn: true
            }, {
                afterChangeValue: function(slider, user) {
                    if (user) {
                        player.components.media['0'].currentTime = player.components.media['0'].duration / player.components.timeline.config.parts.length * slider.value;
                        if ( player.components.playing.hasClass(player.config.classes.playingRepeat) ) {
                            player.components.playing.removeClass(player.config.classes.playingRepeat);
                            player.components.playing.addClass(player.config.classes.playingPlay);
                        }
                    }
                }
            });

            player.components.volumeline = player.components.volumeline.Slider({
                line: {
                    min: 0,
                    max: 100,
                    step: 1
                },
                DefaultValue:  player.config.volumeOn ? player.config.volume * 100 : 0,
                classes: {"skin": player.config.classes.volumelineSkin},
                onParts: false,
                onTitles: false
            }, {
                afterChangeValue: function(slider, user) {
                    if (user) {
                        player.config.volume = (1 / 100 * slider.value);
                        player.components.media[0].volume = player.config.volume;
                        if (player.config.volume == 0) {
                            player.config.volumeOn = false;
                            player.components.volume.removeClass(player.config.classes.volumeFull);
                            player.components.volume.removeClass(player.config.classes.volumeHalf);
                            player.components.volume.addClass(player.config.classes.volumeOff);
                        } else if (player.config.volume < 0.5) {
                            player.config.volumeOn = true;
                            player.components.volume.removeClass(player.config.classes.volumeFull);
                            player.components.volume.addClass(player.config.classes.volumeHalf);
                            player.components.volume.removeClass(player.config.classes.volumeOff);
                        } else {
                            player.config.volumeOn = true;
                            player.components.volume.addClass(player.config.classes.volumeFull);
                            player.components.volume.removeClass(player.config.classes.volumeHalf);
                            player.components.volume.removeClass(player.config.classes.volumeOff);
                        }
                        $.cookie('player.config.volume', player.config.volume);
                        $.cookie('player.config.volumeOn', player.config.volumeOn);
                    }
                }
            });
        }

        // Create Player
        player
            .append(player.components.media)
            .append(player.components.controls
                .append(player.components.container_1
                    .append(player.components.cell_1x1)
                )
                .append(player.components.container_2
                    .append(player.components.cell_2x1)
                    .append(player.components.cell_2x2)
                    .append(player.components.cell_2x3)
                    .append(player.components.cell_2x4)
                )
                .append(player.components.container_3
                    .append(player.components.cell_3x1)
                    .append(player.components.cell_3x2)
                    .append(player.components.cell_3x3)
                    .append(player.components.cell_3x4)
                )
            );
    };


    $.fn.MediaPlayer.events = function (player) {

        function createControls (player, size, important) {
            if (important || size != player.config.size) {
                player.config.size = size;
                if (size == 'lg' ) {
                    player.components.controls.removeClass(player.config.classes.controlsSmall);
                    player.components.controls.addClass(player.config.classes.controlsLarge);
                    player.components.cell_1x1
                        .append(player.components.name)
                        .append(player.components.author);
                    player.components.cell_2x2
                        .append(player.components.timeline);
                    player.components.cell_3x1
                        .append(player.components.playing)
                        .append(player.components.volume)
                    player.components.cell_3x2
                        .append(player.components.volumeline);
                    player.components.cell_3x3
                        .append(player.components.current)
                        .append(player.components.separator)
                        .append(player.components.all);
                    player.components.cell_3x4
                        .append(player.components.screen);
                } else if (size == 'sm') {
                    player.components.controls.removeClass(player.config.classes.controlsLarge);
                    player.components.controls.addClass(player.config.classes.controlsSmall);
                    player.components.cell_1x1
                        .append(player.components.name)
                        .append(player.components.author);
                    player.components.cell_2x1
                        .append(player.components.current);
                    player.components.cell_2x2
                        .append(player.components.timeline);
                    player.components.cell_2x3
                        .append(player.components.all);
                    player.components.cell_2x4
                        .append(player.components.screen);
                }
                if (player.config.type.indexOf('video') > -1) {
                    player.components.controls.css('marginTop', -player.components.controls.outerHeight());
                }
            }
        }

        function setControlsSize(important) {
            if (player.config.type.indexOf('video') > -1) {
                if (player.components.media.innerWidth() > 500) {
                    createControls(player, 'lg', important);
                } else {
                    createControls(player, 'sm', important);
                }
            } else {
                createControls(player, 'lg', important);
            }
        }

        function toggleScreen() {
            if ( player.hasClass(player.config.classes.fullScreen) ) {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                } else if (document.mozCancelFullScreen) {
                    document.mozCancelFullScreen();
                } else if (document.webkitCancelFullScreen) {
                    document.webkitCancelFullScreen();
                } else if (document.msExitFullscreen) {
                    document.msExitFullscreen();
                } else {
                    console.log("Fullscreen API is not supported");
                }
            } else {
                if (player[0].requestFullscreen) {
                    player[0].requestFullscreen();
                } else if (player[0].msRequestFullscreen) {
                    player[0].msRequestFullscreen();
                } else if (player[0].mozRequestFullScreen) {
                    player[0].mozRequestFullScreen();
                } else if (player[0].webkitRequestFullscreen) {
                    player[0].webkitRequestFullscreen();
                } else {
                    console.log("Fullscreen API is not supported");
                }
            }
        }

        function toggleMedia() {
            if ( player.components.playing.hasClass(player.config.classes.playingPlay) ) {
                player.components.playing.removeClass(player.config.classes.playingPlay);
                player.components.playing.addClass(player.config.classes.playingPause);
                player.components.media[0].play();
            } else if ( player.components.playing.hasClass(player.config.classes.playingPause) ) {
                player.components.playing.removeClass(player.config.classes.playingPause);
                player.components.playing.addClass(player.config.classes.playingPlay);
                player.components.media[0].pause();
            } else if ( player.components.playing.hasClass(player.config.classes.playingRepeat) ) {
                player.components.playing.removeClass(player.config.classes.playingRepeat);
                player.components.playing.addClass(player.config.classes.playingPause);
                player.components.media[0].currentTime = 0;
                player.components.media[0].play();
            }
        }

        function durationFormat(duration) {
            duration = Math.round(duration);
            var hours = Math.floor(duration / (60 * 60));
            var divisor_for_minutes = duration % (60 * 60);
            var minutes = Math.floor(divisor_for_minutes / 60);
            var divisor_for_seconds = divisor_for_minutes % 60;
            var seconds = Math.ceil(divisor_for_seconds);
            var timer = '';
            if (hours > 0) {
                if (hours.toString().length == 1) {
                    hours = '0'+hours;
                }
                timer += hours+':';
            }
            if (minutes.toString().length == 1) {
                minutes = '0'+minutes;
            }
            timer += minutes+':';
            if (seconds.toString().length == 1) {
                seconds = '0'+seconds;
            }
            timer += seconds;
            return timer;
        }

        function loadedMetaData() {
            player.components.current.html( durationFormat(player.components.media['0'].currentTime) );
            player.components.all.html( durationFormat(player.components.media[0].duration) );
            if (player.config.type.indexOf('video') > -1) {
                $( window ).resize(function() {
                    setControlsSize();
                });
            }
            setTimeout(
                function () {
                    setControlsSize(true);
                }, 100);
        }

        if (player.config.type.indexOf('video') > -1) {
            $(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', function () {
                if (player.hasClass(player.config.classes.fullScreen) ) {
                    player.removeClass(player.config.classes.fullScreen);
                    player.components.screen.removeClass(player.config.classes.min).addClass(player.config.classes.max);
                    player.components.media.Centering({animationSpeed: player.config.animationSpeedCenteringAfterFullScreen});
                } else {
                    player.addClass(player.config.classes.fullScreen);
                    player.components.screen.removeClass(player.config.classes.max).addClass(player.config.classes.min);
                }
            });
            player.components.screen.on('click', function () {
                toggleScreen();
            });
            $(function(){
                var DELAY = 250, clicks = 0, timer = null;
                player.components.media.on('click', function(e){
                    clicks++;
                    if(clicks === 1) {
                        timer = setTimeout(function() {
                            toggleMedia();
                            clicks = 0;
                        }, DELAY);
                    } else {
                        clearTimeout(timer);
                        toggleScreen();
                        clicks = 0;
                    }
                })
                    .on("dblclick", function(e){
                        e.preventDefault();
                    });
            });
            player.components.controls.hover(function() {
                $(this).addClass('hovered');
            }, function() {
                $(this).removeClass('hovered');
            });
            var mouseNotMove;
            function startNotMove() {
                mouseNotMove = setTimeout(function () {
                    if (!player.components.controls.hasClass('hovered')) {
                        if ( player.components.playing.hasClass(player.config.classes.playingPause) ) {
                            player.components.controls.hide(player.config.animationSpeedControls);
                        }
                    }
                    startNotMove();
                }, player.config.timeOutHideControls);
            }
            startNotMove();
            player.on('mousemove', function() {
                clearTimeout(mouseNotMove);
                player.components.controls.show(player.config.animationSpeedControls);
                startNotMove();
            });
        }

        function runControlEvents() {
            player.components.playing.on('click', function () {
                toggleMedia();
            });
            player.components.volume.on('click', function () {
                if ( $(this).hasClass(player.config.classes.volumeFull) || $(this).hasClass(player.config.classes.volumeHalf)) {
                    player.components.media[0].volume = 0;
                    player.config.volumeOn = false;
                    if ($.fn.Slider) $.fn.Slider.toCount(player.components.volumeline, player.components.media[0].volume);
                    $(this).removeClass(player.config.classes.volumeFull);
                    $(this).removeClass(player.config.classes.volumeHalf);
                    $(this).addClass(player.config.classes.volumeOff);
                } else if ( $(this).hasClass(player.config.classes.volumeOff) ) {
                    if (player.config.volume == 0) {player.config.volume = 0.5;}
                    player.components.media[0].volume = player.config.volume;
                    player.config.volumeOn = true;
                    if ($.fn.Slider) $.fn.Slider.toCount(player.components.volumeline, player.config.volume * (player.components.volumeline.config.parts.length - 1));
                    $(this).removeClass(player.config.classes.volumeOff);
                    if (player.config.volume <= 0.5) {
                        $(this).addClass(player.config.classes.volumeHalf);
                    } else {
                        $(this).addClass(player.config.classes.volumeFull);
                    }
                }
                $.cookie('player.config.volume', player.config.volume);
                $.cookie('player.config.volumeOn', player.config.volumeOn);
            });
        }

        runControlEvents();

        player.components.media[0].onended = function() {
            player.components.playing.removeClass(player.config.classes.playingPause);
            player.components.playing.addClass(player.config.classes.playingRepeat);
        };

        if (player.components.media[0].addEventListener) {
            player.components.media[0].addEventListener('loadedmetadata', loadedMetaData);
        } else {
            player.components.media[0].attachEvent("loadedmetadata", loadedMetaData);
        }

        player.components.media[0].ontimeupdate = function() {
            player.components.current.html(durationFormat(player.components.media[0].currentTime));
            if ($.fn.Slider) {
                $.fn.Slider.toCount(player.components.timeline, player.components.media[0].currentTime / (player.components.media[0].duration / player.components.timeline.config.parts.length));
                $.fn.Slider.toCount (player.components.timeline, player.components.timeline.config.parts.length / (player.components.media[0].duration / player.components.media[0].buffered.end(player.components.media[0].buffered.length - 1)), 'loaded');
            }
        };

        player.callbacks.events(player);
    };

}(jQuery));

Examples

<script src="http://en.skidanov.ru/sources/jquery-plugins/jquery.media-player/jquery.media-player.min.js"></script>
<link rel="stylesheet" href="http://en.skidanov.ru/sources/jquery-plugins/jquery.media-player/css/default.min.css">
<div class="slider default"></div>
example.js
;(function($) {

    $('.example1').MediaPlayer({
        name: 'You Might Die Trying',
        author: 'Dave Matthews Band',
        file: '/media/dave_matthews_band_-_you_might_die_trying.mp3',
        type: 'audio/mp3'
    });

    $('.example2').MediaPlayer({
        name: 'Who Is Chief Surgeon',
        author: 'MASH',
        file: '/media/mash_-_who_is_chief_surgeon.mp4',
        type: 'video/mp4'
    });

}(jQuery));

Demos

default default.min.css