Câu hỏi thường gặp về nội dung âm thanh trên web

Boris Smus

Trong vài tháng qua, Web Audio API (API âm thanh web) của STDEV đã nổi lên như một nền tảng hấp dẫn cho các trò chơi và ứng dụng âm thanh trên web. Khi nhà phát triển đã làm quen với giao diện này, tôi nghe được những câu hỏi tương tự xuất hiện liên tục. Thông tin cập nhật nhanh này là nhằm giải đáp một số câu hỏi thường gặp hơn nhằm giúp bạn có trải nghiệm dễ chịu hơn với Web Audio API.

Hỏi: Hãy trợ giúp, tôi không thể phát ra âm thanh!

Đáp: Nếu bạn mới sử dụng API Web âm thanh, hãy xem hướng dẫn bắt đầu sử dụng hoặc công thức phát âm thanh dựa trên tương tác của người dùng của Eric.

Hỏi: Tôi nên có bao nhiêu Ngữ cảnh âm thanh?

Đáp: Nói chung, bạn nên thêm một AudioContext trên mỗi trang và một ngữ cảnh âm thanh có thể hỗ trợ nhiều nút được kết nối với ngữ cảnh đó. Mặc dù bạn có thể đưa nhiều AudioContexts vào một trang, nhưng điều này có thể giúp bạn tăng hiệu suất.

Hỏi: Tôi có một AudioBufferSourceNode mà tôi vừa phát bằng noteOn() và tôi muốn phát lại, nhưng noteOn() lại không có gì! Giúp tôi với!

Đ: Sau khi phát xong nút nguồn, nút đó không thể phát lại thêm nữa. Để phát lại vùng đệm cơ bản, bạn nên tạo AudioBufferSourceNode mới rồi gọi noteOn().

Mặc dù việc tạo lại nút nguồn có thể không hiệu quả, nhưng các nút nguồn đã được tối ưu hoá rất nhiều cho mẫu này. Ngoài ra, nếu giữ tên người dùng đối với AudioBuffer, bạn không cần gửi yêu cầu khác đối với nội dung để phát lại âm thanh đó. Nếu bạn thấy cần phải lặp lại mẫu này, hãy đóng gói phát lại bằng một chức năng trợ giúp đơn giản như playSound(buffer).

Hỏi: Khi phát lại âm thanh, tại sao lần nào bạn cũng cần tạo nút nguồn mới?

Đáp: Ý tưởng của kiến trúc này là tách riêng tài sản âm thanh khỏi trạng thái phát. Tương tự như trình phát bản ghi, vùng đệm cũng tương tự như bản ghi và nguồn đối với đầu phát. Vì nhiều ứng dụng liên quan đến nhiều phiên bản của cùng một vùng đệm phát đồng thời, mẫu này là cần thiết.

Hỏi: Làm cách nào để xử lý âm thanh từ các thẻ audiovideo?

Đáp: MediaElementAudioSourceNode đang trong quá trình phát triển! Khi có sẵn, tuỳ chọn này sẽ hoạt động đại loại như sau (thêm hiệu ứng bộ lọc vào một đoạn nhạc đang phát qua thẻ âm thanh):

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

Tính năng này được theo dõi trong công cụ tìm kiếm này. Lưu ý rằng trong quá trình thiết lập này, bạn không cần gọi mediaSourceNode.noteOn(), thẻ âm thanh sẽ kiểm soát việc phát.

Hỏi: Khi nào tôi có thể nghe âm thanh từ Micrô?

Đáp: Phần đầu vào âm thanh của thoả thuận này sẽ được triển khai như một phần của WebRTC bằng getUserMedia và có sẵn dưới dạng nút nguồn đặc biệt trong API Web âm thanh. Mã này sẽ hoạt động cùng với createMediaElementSource.

Hỏi: Làm cách nào để kiểm tra thời điểm AudioSourceNode phát xong?

Đáp: Hiện tại, bạn phải sử dụng bộ tính giờ JavaScript vì API Web âm thanh không hỗ trợ chức năng này. Đoạn mã sau trong hướng dẫn Bắt đầu với API Web âm thanh là một ví dụ về cách này trong thực tế:

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

Đã xảy ra lỗi mở khiến cho API Web âm thanh triển khai lệnh gọi lại chính xác hơn.

Hỏi: Việc tải âm thanh khiến toàn bộ luồng giao diện người dùng bị khoá và giao diện người dùng của tôi không phản hồi. Tôi cần trợ giúp!**

Đáp: Dùng API decodeAudioData để tải không đồng bộ nhằm tránh chặn luồng chính. Hãy xem ví dụ này.

Hỏi: Có thể sử dụng API Web âm thanh để xử lý âm thanh nhanh hơn thời gian thực không?

Đáp: Có, giải pháp đang được nghiên cứu. Hãy chú ý theo dõi!

Hỏi: Tôi đã tạo một ứng dụng API Web âm thanh tuyệt vời, nhưng bất cứ khi nào thẻ ứng dụng đang chạy chạy ở chế độ nền, âm thanh đều trở nên kỳ lạ!

Đáp: Điều này có thể là do bạn đang sử dụng setTimeouts. Lớp này sẽ hoạt động khác nếu trang được chạy ở chế độ nền. Trong tương lai, API Web âm thanh sẽ có thể gọi lại vào những thời điểm cụ thể bằng bộ tính giờ nội bộ của âm thanh trên web (thuộc tính context.currentTime). Để biết thêm thông tin, vui lòng xem yêu cầu về tính năng này.

Nhìn chung, bạn nên dừng phát khi ứng dụng chuyển sang chạy ở chế độ nền. Bạn có thể phát hiện thời điểm một trang chuyển sang chạy ở chế độ nền bằng cách sử dụng API Chế độ hiển thị trang.

Hỏi: Làm cách nào để tôi thay đổi cao độ của âm thanh bằng API Web âm thanh?

Đáp: Thay đổi playbackRate trên nút nguồn.

Hỏi: Tôi có thể thay đổi độ cao mà không cần thay đổi tốc độ không?

Đáp: Web Audio API có thể có PitchNode trong ngữ cảnh âm thanh, nhưng rất khó triển khai. Điều này là do không có thuật toán thay đổi cao độ đơn giản nào trong cộng đồng âm thanh. Các kỹ thuật đã biết tạo ra các cấu phần phần mềm, đặc biệt là trong trường hợp sự thay đổi độ cao lớn. Có hai loại phương pháp tiếp cận để giải quyết vấn đề này:

  • Các thuật toán miền thời gian, gây ra phân đoạn lặp lại sẽ lặp lại cấu phần phần mềm.
  • Các kỹ thuật liên quan đến miền tần số gây ra hiện tượng âm thanh vang.

Mặc dù không có nút gốc nào để thực hiện những kỹ thuật này, nhưng bạn có thể thực hiện việc này bằng JavaScriptAudioNode. Đoạn mã này có thể đóng vai trò là điểm bắt đầu.

Hỏi: Làm cách nào để tạo AudioContext theo tốc độ lấy mẫu tôi chọn?

Đáp: Hiện tại chúng tôi chưa hỗ trợ việc này nhưng chúng tôi đang tìm hiểu vấn đề. Xem yêu cầu về tính năng này.

Nếu bạn có thêm câu hỏi, vui lòng đặt câu hỏi trên StackOverflow bằng cách sử dụng thẻ web-audio.