iOS Safari yêu cầu header Content-Range để phát file WAV (và một số định dạng media khác) đúng cách, đặc biệt khi streaming hoặc seek.
Header cần thiết
Content-Range: bytes 0-1023/2048 Content-Type: audio/wav Content-Disposition: attachment; filename="audio.wav" Content-Length: 2048
Content-Range: Chỉ định byte range đang phục vụ (bắt đầu 0, kết thúc, tổng size).Content-Type:audio/wav(hoặcaudio/x-wav,audio/wave).Content-Disposition: Gợi ý tên file khi tải xuống.Content-Length: Kích thước toàn bộ file (hoặc chunk).
Lưu ý
- Server phải hỗ trợ Range Requests (HTTP 206 Partial Content) để seek hoạt động.
- Nếu dùng
<audio src="file.wav">trực tiếp, server static file server (Nginx, Apache, Express static) thường tự động xử lý Range request. - Nếu phục vụ qua script (PHP, Node.js), phải tự implement parse header
Rangevà trả206+Content-Range.
Ví dụ Node.js (Express) phục vụ WAV với Range support:
app.get('/audio.wav', (req, res) => {
const path = 'path/to/audio.wav';
const stat = fs.statSync(path);
const range = req.headers.range;
if (range) {
const parts = range.replace(/bytes=/, "").split("-");
const start = parseInt(parts[0], 10);
const end = parts[1] ? parseInt(parts[1], 10) : stat.size - 1;
const chunkSize = (end - start) + 1;
const file = fs.createReadStream(path, { start, end });
res.writeHead(206, {
'Content-Range': `bytes ${start}-${end}/${stat.size}`,
'Accept-Ranges': 'bytes',
'Content-Length': chunkSize,
'Content-Type': 'audio/wav'
});
file.pipe(res);
} else {
res.writeHead(200, {
'Content-Length': stat.size,
'Content-Type': 'audio/wav'
});
fs.createReadStream(path).pipe(res);
}
});