Hướng dẫn custom audio html - html âm thanh tùy chỉnh

UPDATE: HTML5 Audio Player với Playlist: https://github.com/trangsihung/html5-audio-player-with-playlist HTML5 Audio Player với Playlist: https://github.com/trangsihung/html5-audio-player-with-playlist

Show

Trong bài trước mình đã hướng dẫn sử dụng jQuery để điều khiển HTML5 Audio Tag, lần này dựa vào đó chúng ta sẽ tạo một HTML5 Audio Player đơn giản. Trong bài mình tập trung vào jQuery, còn phần giao diện HTML-CSS thì các bạn có thể tham khảo phần trong phần code HTML-CSS hoặc tự code một cái.

HTML – CSS

1

Một cái mới trong code HTML-CSS trên là tag trong HTML5. Về

var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
0 bạn có thể xem thêm thông tin tại http://diveintohtml5.info/forms.html#type-range.

Các nút đều khiển của player là mình dùng Font Awesome để làm.

JAVASCRIPT

Đây là phần quan trọng nhất đối với HTML5 Audio Player, ta thêm vào các file js sau: thư viện jQuery, plugin prefixfree giúp tự thêm các tiền tố

var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
1 trong CSS.





  • player.js xử lý các thao tác mà ta thực hiện trên player như: ấn play/pause, stop, tăng/giảm volume.
  • main.js là phần script chính

Bắt đầu với

var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
2, đầu tiên ta tạo các jQuery selector cho các thành phần của player và gọi function
var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
3 với tham số là biến
var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
4.

var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);

Sau đó trong file

var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
5 ta tạo function
var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
3 với các sự kiện click vào nút play và nút stop trên player

function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}

Ta thấy khi click vào

var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
7, nếu icon là pause thì sẽ chuyển thành play và ngược lại khi icon là play thì sẽ chuyển thành pause. Khi nhấn stop thì icon pause sẽ thành play. Nếu thấy khó hiểu bạn có thể xem click vào demo bên dưới để dễ hiểu hơn. function
var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
8 giúp code gọn hơn khi addClass và removeClass.

1

Tiếp tục trong

var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
2 tạo thêm biến
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
0 lưu các thông tin về bài hát, gồm tên bài hát, ca sĩ và link file mp3

songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}

Đổi

function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
1,
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
2 và giá trị
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
3 theo
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
0. Đặt mức volume ban đầu của Audio theo giá trị của
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
5, do volume chỉ có giá trị 0 đến 1 nên ta chia val của
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
5 cho 100 (do ta đặt max=100). Dùng
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
7 để audio tự play.

$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();

F5 lại trình duyệt để kiểm tra kết quả. Ta thấy audio đã tự play. Tiếp đến là liên kết các điều khiển trên player với phần Audio.
Tiếp đến là liên kết các điều khiển trên player với phần Audio.

song.addEventListener('timeupdate',function (){
        per = (song.currentTime/song.duration)*100;

        if(per == 100){
            $('.fill').css({'width': '0%'});
            $('#seek').attr('value',0);
        }else{
            $('.fill').css({'width': per + '%'});
            $('#seek').attr('value', per);
        }
    });

Giải thích đoạn code trên, khi Audio được phát thì giá trị

function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
8 sẽ thay đổi và có sự kiện
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
9, khi đó ta tính phần trăm giữa
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
8 và
songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
1 và lấy phần trăm này set width cho
songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
2 và value của
songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
3. Còn
songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
2 và
songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
3 là phần nào thì hãy xem lại phần HTML-CSS.

$('#seek').click(function(event) {
    time = ($(this).val()/100)*song.duration;
    song.currentTime = time;
});

Khi click vào

songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
3, ta lấy
songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
7 là phần trăm thời gian đã phát, từ đó tính ra thời gian của Audio khi đã phát theo
songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
7. VD: Khi click thì
songDetail = {
    'tenbaihat' : 'Anh Không Đòi Quà',
    'trinhbay'  : 'OnlyC - Karik',
    'link'      : 'dropbox'
}
7 là 40. Ta đặt
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
0 là 40% của
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
1.

Hoàn thành chức năng các control, sữa lại function control trong

var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
2 thành
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
3, mở file
var player = {
        play  : $('#play'),
        stop  : $('#stop'),
        vol :   $('.volume input'),
    },
    song = new Audio();
    song.type = 'audio/mpeg';
    control_player(song, player);
5 và thêm tham số
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
5 vào hàm player. Viết thêm
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
6 khi chuyển từ
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
7 sang
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
8,
function control(ctrl) {
    ctrl.play.on('click', function(e) {
        e.preventDefault();
        status = $(this).find('i').hasClass('icon-pause') ? 'play' : 'pause';

        if(status == 'play'){
            $(this).changeClass('icon-pause','icon-play');
        }else{
            $(this).changeClass('icon-play','icon-pause');
        }
    });

    ctrl.stop.on('click', function(e) {
        e.preventDefault();
        button.play.changeClass('icon-pause','icon-play');
    });
}

$.fn.changeClass = function(before, after) {
    $(this).find('i').removeClass(before).addClass(after);
}
7 khi chuyển từ
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
8 sang
$('h3.tenbaihat').text(songDetail.tenbaihat);
$('h4.trinhbay').text(songDetail.trinhbay);

song.src = songData.link;
song.volume = player.vol.val()/100;
song.play();
7. Và thêm
song.addEventListener('timeupdate',function (){
        per = (song.currentTime/song.duration)*100;

        if(per == 100){
            $('.fill').css({'width': '0%'});
            $('#seek').attr('value',0);
        }else{
            $('.fill').css({'width': per + '%'});
            $('#seek').attr('value', per);
        }
    });
2 khi click vào nút stop.

function control_player(song,ctrl) {
...
if(status == 'play'){
    $(this).changeClass('icon-pause','icon-play');
    song.pause();
}else{
    $(this).changeClass('icon-play','icon-pause');
    song.play();
}
...
button.play.changeClass('icon-pause','icon-play');
song.pause(); song.currentTime = 0;

Do ta lấy giá trị của

song.addEventListener('timeupdate',function (){
        per = (song.currentTime/song.duration)*100;

        if(per == 100){
            $('.fill').css({'width': '0%'});
            $('#seek').attr('value',0);
        }else{
            $('.fill').css({'width': per + '%'});
            $('#seek').attr('value', per);
        }
    });
3 là phần trăm volume nên khi thay đổi giá trị sẽ làm thay đổi volume

button.vol.change(function(e) {
    song.volume = ($(this).val())/100;
    $('#vol-fill').css('width', $(this).val() + '%');
});

Tóm lại

Vậy là đã hoàn thành HTML5 Audio Player đơn giản. Dựa vào code trong bài này, bài sau mình sẽ hướng dẫn tạo playlist cho HTML5 Audio Player mới tạo này.

Do mình viết theo cách hiểu của mình khi code nên có thể khi đọc bài viết bạn sẽ không hiểu lắm. Bạn nên vừa đọc vừa thực hành code thì sẽ dễ hiểu hơn. Ở cuối bài có phần demo và code khi hoàn thành bạn có thể down về xem.democode khi hoàn thành bạn có thể down về xem.

Nếu gặp vần đề gì hay có góp ý thì comment lại bên dưới nhé.

Demo Source Code
Source Code