Меню
Спросить
???

Как сделать плеер? Часть 6.

28 сентября 2017
Как сделать плеер? Часть 6.

Всем привет, я думаю это будет последняя часть по созданию плеера для сайта, сегодня мы разберем довольно важный элемент плеера - линию трека. Сделаю полосу загрузку, полосу воспроизведения, поработаем с событием timeupdate и другое. Так отвечу на один не маловажный вопрос. Думаю уже многие начали делать свой плеер, совершать какие-то ошибки или наоборот все безупречно, в общем я рад если своими статьями хоть чем-то вам помог друзья. Поехали =)

Полоса воспроизведения, событие timeupdate

Кто читал эту статью, тот молодец и возможно помнит о событии timeupdate. Но я повторю для тех кто еще не знает или забыл. Событие timeupdate возникает когда трек воспроизводится, то есть музыка играет в данный момент. Этим мы и воспользуемся, в этой событии мы можем получить текущее время.
Для начала объявим в функции playNewSong две переменные:
- curtime, будет содержать в себе текущее время,
- cur, будет содержать в себе значение, для передвижения линии воспроизведения и изначально будет равно -100, так как изначальное положение нашей линии относительно левого края -100%.

  1. var
  2. curtime, cur = -100;

Думаю это понятно. Дальше в конце нашей функции последнее, что мы написали, это строчка где мы меняем громкость, вот после нее и пишем наше события для ауди-объекта.

  1. function playNewSong(id) {
  2.     var
  3.     curtime, cur = -100;
  4.     //код
  5.     Song.volume = volume;
  6.     Song.addEventListener('timeupdate', function(){

  7.     });
  8. }

Дальше работаем в этом событии, оно будет происходить буквально каждую секунду. Первое, что мы сделаем в этом событии timeupdate, так это получим текущее время с помощью свойства currentTime, вернет на в секундах. Сразу присвоим это значение объявленной выше переменной curtime.

  1. Song.addEventListener('timeupdate', function(){
  2.     curtime = Song.currentTime;
  3. });

Отлично, теперь нужно получить значение для полосы.
Полоса в данный момент находить на left: -100%, мы знаем продолжительность песни и можем получать текущее время, значит имея эти два значения нам нужно получить текущее положение в процентах. Я придумал формулу, кому то она может показаться сложной, но если посидеть и подумать, повычислять, то можно и разобраться:

  1. Song.addEventListener('timeupdate', function(){
  2.     curtime = Song.currentTime;
  3.     cur = -((songs[id_song][3] - curtime)*100)/songs[id_song][3];
  4. });

Вот и все, остается эти полученные значения вставить в нужные месте. У элемента с классом .time меняем текст по знакомой нам формуле из этой статьи. То есть берем текущее значение в секундах и представляем в виде минут и секунд.

  1. Song.addEventListener('timeupdate', function(){
  2.     curtime = Song.currentTime;
  3.     cur = -((songs[id_song][3] - curtime)*100)/songs[id_song][3];
  4.     $('.time').text(parseInt(curtime/60)+':'+parseInt(curtime%60));
  5. });

Теперь поменяем значение left у элемента с классом .progress.

  1. Song.addEventListener('timeupdate', function(){
  2.     curtime = Song.currentTime;
  3.     cur = -((songs[id_song][3] - curtime)*100)/songs[id_song][3];
  4.     $('.time').text(parseInt(curtime/60)+':'+parseInt(curtime%60));
  5.     $('.progress').css({'left':cur+'%'});
  6. });

Запускаем и смотрим как работает, секунды тикают линия двигается, поздравляю **ять =)
Теперь займемся простейшей перемоткой.

Перемотка трека на нужную секунду

Схема простая, наводим мышку на линию трека - появляется .setTime, который содержит в себе секунду над которыми висит курсор и при нажатии на нужное место песня перематывается с эти секунды.
Для начала запишем обработчик события - появление курсора на элементе с классом .range:

  1. $('.range').on('mouseenter', function(){

  2. });

Дальше проверим существует ли аудио-объект и объявим несколько переменных:
- id, будет содержать в себе текущее айди, хотя можно и просто обойтись переменной id_song,
- offset, будет содержать в себе координаты .range относительно начала документа,
- dur, содержит в себе продолжительность песни в секундах, берем из массива,
- w, будет содержать в себе ширину .range.

  1. $('.range').on('mouseenter', function(){
  2.     if (Song) {
  3.         var
  4.         id = $('.play-pause').attr('id'),
  5.         offset = $(this).offset(),
  6.         dur = songs[id][3],
  7.         w = $(this).width();
  8.     }
  9. });

Поехали дальше, теперь покажем .setTime, элемент, который будет содержать секунды:

  1. $('.range').on('mouseenter', function(){
  2.     if (Song) {
  3.         var
  4.         id = $('.play-pause').attr('id'),
  5.         offset = $(this).offset(),
  6.         dur = songs[id][3],
  7.         w = $(this).width();
  8.         $('.setTime').show();
  9.     }
  10. });

Мышку мы навели, значения получили и элемент показали, теперь будем отслеживать движение мыши по элементу .range и передвигать за курсором элемент .setTime и записывать в него секунды.
Для начала запишем сам обработчик движения мыши в области элемента .range:

  1. $('.range').on('mouseenter', function(){
  2.     if (Song) {
  3.         var
  4.         id = $('.play-pause').attr('id'),
  5.         offset = $(this).offset(),
  6.         dur = songs[id][3],
  7.         w = $(this).width();
  8.         $('.setTime').show();
  9.         $('.range').on('mousemove', function(e){
  10.         
  11.         });
  12.     }
  13. });

Тут мы должны еще получить парочку значений:
- x, будет содержать в себе значение для изменения положения .setTime,
- xproc, будет содержать значение для линии прогресса,
- sec, будет содержать в себе значение в секундах, в зависимости от месте где расположен курсор мыши.

  1. $('.range').on('mouseenter', function(){
  2.     if (Song) {
  3.         var
  4.         id = $('.play-pause').attr('id'),
  5.         offset = $(this).offset(),
  6.         dur = songs[id][3],
  7.         w = $(this).width();
  8.         $('.setTime').show();
  9.         $('.range').on('mousemove', function(e){
  10.             var
  11.             x = e.PageX - offset.left,
  12.             xproc = (x*100)/w,
  13.             sec = (xproc*dur)/100;
  14.         });
  15.     }
  16. });

Думаю тут понятно, если нет в добавок посмотрите видео. Что делаем дальше, а дальше мы меняем положение .setTime относительно левого края и меняем его текст, представленный в виде минут и секунд:

  1. $('.range').on('mouseenter', function(){
  2.     if (Song) {
  3.         var
  4.         id = $('.play-pause').attr('id'),
  5.         offset = $(this).offset(),
  6.         dur = songs[id][3],
  7.         w = $(this).width();
  8.         $('.setTime').show();
  9.         $('.range').on('mousemove', function(e){
  10.             var
  11.             x = e.PageX - offset.left,
  12.             xproc = (x*100)/w,
  13.             sec = (xproc*dur)/100;
  14.             $('.setTime').css({'left':x-10});
  15.             $('.setTime').text(parseInt(sec/60)+':'+parseInt(sec%60));
  16.         });
  17.     }
  18. });

Теперь уже даже можно проверить, двигаем мышкой по области трека и у нас появляется .setTime с секундами, но все это конечно же если песня была уже хоть раз запущена. Дело осталось за малым, еще два события и перемотка готова.
Напишем, выше или ниже, главное отдельно, событие, когда курсор мыши выходит из области элемента, тут мы будет скрывать наш .setTime:

  1. $('.range').on('mouseenter', function(){
  2.     if (Song) {
  3.         var
  4.         id = $('.play-pause').attr('id'),
  5.         offset = $(this).offset(),
  6.         dur = songs[id][3],
  7.         w = $(this).width();
  8.         $('.setTime').show();
  9.         $('.range').on('mousemove', function(e){
  10.             var
  11.             x = e.PageX - offset.left,
  12.             xproc = (x*100)/w,
  13.             sec = (xproc*dur)/100;
  14.             $('.setTime').css({'left':x-10});
  15.             $('.setTime').text(parseInt(sec/60)+':'+parseInt(sec%60));
  16.         });
  17.     }
  18. });
  19. $('.range').on('mouseout', function(){
  20.     $('.setTime').hide();
  21. });

И теперь самое главное, пишем событие клика по области трека, то есть мы кликаем мышкой в какую то секунду и песня должна туда перемотаться. Для начала пишем обработчик события - клик по .range:

  1. $('.range').on('mouseenter', function(){
  2.     if (Song) {
  3.         var
  4.         id = $('.play-pause').attr('id'),
  5.         offset = $(this).offset(),
  6.         dur = songs[id][3],
  7.         w = $(this).width();
  8.         $('.setTime').show();
  9.         $('.range').on('mousemove', function(e){
  10.             var
  11.             x = e.PageX - offset.left,
  12.             xproc = (x*100)/w,
  13.             sec = (xproc*dur)/100;
  14.             $('.setTime').css({'left':x-10});
  15.             $('.setTime').text(parseInt(sec/60)+':'+parseInt(sec%60));
  16.             $('.range').on('click', function(){

  17.             });
  18.         });
  19.     }
  20. });

Тут делаем всего три действия, к переменной xproc прибавляем начально значение линии прогрессе, то есть -100, дальше двигаем саму линию и свойству currentTime аудио-объекта меняем на значение переменной sec:

  1. $('.range').on('mouseenter', function(){
  2.     if (Song) {
  3.         var
  4.         id = $('.play-pause').attr('id'),
  5.         offset = $(this).offset(),
  6.         dur = songs[id][3],
  7.         w = $(this).width();
  8.         $('.setTime').show();
  9.         $('.range').on('mousemove', function(e){
  10.             var
  11.             x = e.PageX - offset.left,
  12.             xproc = (x*100)/w,
  13.             sec = (xproc*dur)/100;
  14.             $('.setTime').css({'left':x-10});
  15.             $('.setTime').text(parseInt(sec/60)+':'+parseInt(sec%60));
  16.             $('.range').on('click', function(){
  17.                 xproc = xproc-100;
  18.                 $('.progress').css({'left':xproc+'%'});
  19.                 Song.currentTime = sec;
  20.             });
  21.         });
  22.     }
  23. });

Вот и все перемотка готова. Осталось сделать последний шаг к финалу.

Полоса загрузки

Делать будем полосу загрузки, то есть когда песня грузится не с ваше компа, а с сервера к примеру, есть такая полоска, когда мы ждем ее чтобы музыка или видео загрузилось, вот ее мы и будем делать.
СОВЕТ, в конце, когда напишем код, для проверки, обновите кэш.
И так, мы возвращаемся к функции playNewSong, после события timeupdate пишем другое событие - progress, оно возникает каждый раз когда очередная порция файла подгружается.

  1. function playNewSong(id) {
  2.     Song.addEventListener('timeupdate', function(){ //блаблабла });
  3.     Song.addEventListener('progress', function(){

  4.     });
  5. }

Тут все довольно просто, объявляем переменную в которую записываем количество загруженной порции в секундах:

  1. Song.addEventListener('progress', function(){
  2.     var
  3.     load = Song.buffered.end(0);
  4. });

Дальше по накатанной уже, делаем тоже самое что и с линией воспроизведения, та же формула и так же двигаем ее относительно левого края.

  1. Song.addEventListener('progress', function(){
  2.     var
  3.     load = Song.buffered.end(0);
  4.     load = -((songs[id_song][3]-load)*100)/songs[id_song][3];
  5.     $('.load').css({'left':load+'%'}, 100);
  6. });

Вот и все, просто, дэ =)

Плеер для сайта

Плеер без остановок

Есть такие вопросы
- как сделать, чтобы плеер при переходе на другую страницу не останавливался,
- как сделать плеер как вконакте без остановок
- и тд.
Так вот, отвечаю на данный вопрос - я хз как это делается.
На самом деле, могу подтолкнуть вас в разные степи, я пробовал это сделать с помощью куков, get запросов, и все это работает, но не так как в контакте, так как в любом случае хоть мельчайшая остановка там есть, музыка прерывается, такак DOM при перезагрузке удаляется и создается новый, так что это вряд ли подходит.
Другой способ и возможно верный способ, так это сделать навигацию с аяксом, то есть меняем нужное содержимое с помощью аякса. В этом случае плеер точно останавливаться и прерываться не будет, а содержимое меняться будет, способ не плохой, но не всем подойдет.
Ну и последний способ, про него я только слышал, если вы что-то откопаете, то можете поделится со мной, я добавлю это в статью, способ заключается в том, чтобы сделать это все с помощью HTML 5 history.

Заключение

Это была финальная часть, хочу всем сказать спасибо, кто дошел до конца, кто читал, кто слушал, комментировал и ставил лайки и пальцы вниз, спасибо всем. Желаю всем запилить свой идеальный плеер, спасибо всем, пока =)

Следующая статьяПредыдущая статья