Tự tìm niềm vui qua ứng dụng hát karaoke bằng HTML5 Audio

Trong cuộc sống, thỉnh thoảng bạn hãy tìm vài trò vui vui để làm với công việc của mình, có thể nó sẽ giúp bạn giảm stress và thấy công việc có chút ý nghĩa hơn.

Mấy hôm nay rảnh rỗi, mình cũng viết ra một cái (chả biết gọi nó là cái gì, tạm gọi là ứng dụng vậy) có chức năng để highlight các đoạn text theo lời bài hát (hay còn gọi là ca ra ô cê). Thì cũng chả có gì đặc biệt, nhưng mình cũng thấy vui khi code xong và thỉnh thoảng căng thẳng, mở cái ứng dụng đấy ra vừa nghe nhạc, vừa xem cái thành quả của mình cũng thấy có thêm tí động lực học. Thì mình cũng mạn phép chia sẻ cái mớ code dở hơi, lôi thôi và nhiều bug của mình, có thể có bạn nào đó cần tới thì lấy về mà fix bug. Thì do toàn code và một chút thuật toán xử lý nên mình chỉ nói qua về cái ý tưởng vớ vẩn của mình thôi nhé, còn các bạn đọc code chắc cũng hiểu phần nào.

Ý tưởng

Đơn giản là mình muốn viết một cái ứng dụng web, có thể highlight các đoạn text theo lời một bài hát.

.ue709ed696fcd290d347a76ce202ec9b7 { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .ue709ed696fcd290d347a76ce202ec9b7:active, .ue709ed696fcd290d347a76ce202ec9b7:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .ue709ed696fcd290d347a76ce202ec9b7 { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .ue709ed696fcd290d347a76ce202ec9b7 .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .ue709ed696fcd290d347a76ce202ec9b7 .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .ue709ed696fcd290d347a76ce202ec9b7:hover .postTitle { text-decoration: underline!important; }

  Thử làm ứng dụng tô màu ảnh với mạng Deep Learning

.u6ea6c4fd85661c9a85512358c62b494a { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .u6ea6c4fd85661c9a85512358c62b494a:active, .u6ea6c4fd85661c9a85512358c62b494a:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .u6ea6c4fd85661c9a85512358c62b494a { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .u6ea6c4fd85661c9a85512358c62b494a .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .u6ea6c4fd85661c9a85512358c62b494a .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .u6ea6c4fd85661c9a85512358c62b494a:hover .postTitle { text-decoration: underline!important; }

  Giỗ Tổ Hùng Vương 2019: Cung cấp ứng dụng CNTT về Đền Hùng trên smartphone

  • Đầu tiên, mình cần một thứ để có thể load được bài hát và control được nó (play, pause, seeked). Thì trên HTML 5 có một thành phần là audio hỗ trợ tất cả các yêu cầu mà mình mong muốn nên mình sẽ dùng thằng này.
  • Tiếp theo mình cần một tập các đoạn lời trong bài hát, cái này mình phải tự tạo bằng tay, mình tạo một mảng gồm các mảng con, mỗi mảng con chứa thông tin của một đoạn lời bài hát gồm [lời bài hátthời gian bắt đầuthời gian kết thúc]. Tạo kiểu mảng ntn thì sẽ dễ control hơn.

  var words = [      ['Đêm nghe hạt mưa rơi', 23.516146, 25.81885],      ['Lòng chợt nhớ em vô cùng', 26, 30.344052],     
//...  ] 

  • Khi các bạn play hoặc tua đoạn nhạc đến các khoảng thời gian khác nhau, thì mình sẽ cần tính toán xem sẽ hiển thị đoạn lời nào ra, thì mình viết một hàm tạm đặt tên là findWordIndex để làm nhiệm vụ này.

  var aud = document.getElementById('audio'); 
//...  var findWordIndex = function() {
    if (aud.currentTime === 0) {
      return 0;    
}    for (var i = 0; i 
< words.length; i++) {
      if (aud.currentTime >= words[i][1] && aud.currentTime 
<= words[i][2]) {
        return i;      
} else if (words[i][1] >= aud.currentTime) {
        return i;      
}    
}    return words.length;  
} 

  • Và khi play đoạn nhạc, thì mình sẽ chạy một hàm interval liên tục cập nhật thời gian hiện tại của đoạn nhạc và tính toán giữa thời gian bắt đầu, kết thúc của lời bài hát để cập nhật hiệu ứng highlight cho đoạn text.

  var startTime, endTime = 0;  var karaText, karaTextHighlight; 
//...  aud.addEventListener('play', function() {
    audInterval = setInterval(function() {
      if ((aud.currentTime - startTime) >= 0) {
        var duration = endTime - startTime;        if (endTime - aud.currentTime > 0) {
          var ratio = ((100 / duration) * (endTime - aud.currentTime)) - 100;          karaTextHighlight.style.width = ratio * -1 + '%';        
} else {
          nIndex++;          nextWord(nIndex);        
}      
}    
}, 1000 / 60);  
});    var nextWord = function(index) {
    if (!words[nIndex]) {
      return;    
}      var word = words[index];      karaText.textContent = word[0];    karaTextHighlight.textContent = word[0];    karaTextHighlight.style.width = '0%';      startTime = word[1];    endTime = word[2];  
} 

  • Còn cái hiệu ứng highlight text thì chỉ cần tạo ra 2 đoạn text giống nhau, 1 cái nằm dưới, 1 cái nằm trên, cái nẳm trên sẽ có màu mè và thay đổi chiều dài để tạo cái hiệu ứng highlight từ trái qua phải.

  #karaoke .kara-text,  #karaoke .kara-text-highlight {
    display: inline-block;    font-size: 50px;    white-space: nowrap;  
}    #karaoke .kara-text {
    position: relative;  
}    #karaoke .kara-text-highlight {
    position: absolute;    top: 0;    left: 0;    color: violet;    text-shadow: 0px 0px 20px violet;    overflow: hidden;  
} 

googletag.cmd.push(function() { googletag.display(‘p-gpt-ad-1546852316124-0’); });

Chúc các bạn làm được nhiều cái hay ho hơn thế này và thêm yêu công việc của mình hơn nhé!

Techtalk via viblo

.u22422fd2e797222350ed6c21ecc7a29e { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .u22422fd2e797222350ed6c21ecc7a29e:active, .u22422fd2e797222350ed6c21ecc7a29e:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .u22422fd2e797222350ed6c21ecc7a29e { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .u22422fd2e797222350ed6c21ecc7a29e .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .u22422fd2e797222350ed6c21ecc7a29e .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .u22422fd2e797222350ed6c21ecc7a29e:hover .postTitle { text-decoration: underline!important; }

  Bí kíp cheat sheet của HTML dành cho anh em muốn làm web

.u8293c12631be285d154ab8adc164023a { padding:0px; margin: 0; padding-top:1em!important; padding-bottom:1em!important; width:100%; display: block; font-weight:bold; background-color:#eaeaea; border:0!important; border-left:4px solid #34495E!important; text-decoration:none; } .u8293c12631be285d154ab8adc164023a:active, .u8293c12631be285d154ab8adc164023a:hover { opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; text-decoration:none; } .u8293c12631be285d154ab8adc164023a { transition: background-color 250ms; webkit-transition: background-color 250ms; opacity: 1; transition: opacity 250ms; webkit-transition: opacity 250ms; } .u8293c12631be285d154ab8adc164023a .ctaText { font-weight:bold; color:inherit; text-decoration:none; font-size: 16px; } .u8293c12631be285d154ab8adc164023a .postTitle { color:#000000; text-decoration: underline!important; font-size: 16px; } .u8293c12631be285d154ab8adc164023a:hover .postTitle { text-decoration: underline!important; }

  Kiệt tác này được dựng lên hoàn toàn nhờ code HTML và CSS

googletag.cmd.push(function() { googletag.display(‘p-gpt-ad-1529578121466-1’); });

Sending
User Review
0 (0 votes)

Leave a Reply

avatar
  Subscribe  
Notify of