[HTML]播放wav格式音频
html
<!doctype html>
<html>
<head>
<title>音频播放 - 调试版</title>
<style>
.error { color: red; }
.success { color: green; }
.debug-info {
margin-top: 20px;
border: 1px solid #ccc;
padding: 10px;
background-color: #f9f9f9;
}
</style>
</head>
<body>
<h1>音频播放 - 调试版</h1>
<div>
<h3>方法1: 原生Audio元素</h3>
<button onclick="playAudioNative()">原生播放</button>
<audio id="audio-native" controls></audio>
</div>
<div>
<h3>方法2: Fetch + Blob URL</h3>
<button onclick="playAudioFetch()">Fetch方式播放</button>
<audio id="audio-fetch" controls></audio>
</div>
<div>
<h3>方法3: XMLHttpRequest</h3>
<button onclick="playAudioXHR()">XHR方式播放</button>
<audio id="audio-xhr" controls></audio>
</div>
<div>
<h3>方法4: iframe嵌入</h3>
<button onclick="showAudioFrame()">iframe方式</button>
<div id="frame-container"></div>
</div>
<div class="debug-info">
<h3>调试信息:</h3>
<div id="debug-log"></div>
<h3>检查音频文件:</h3>
<button onclick="checkAudioFile()">检查文件是否存在</button>
<div id="file-status"></div>
</div>
<script>
const audioUrl = 'http://127.0.0.1:8080/tts-audio/tts_3691e8bf-1ff9-4b81-804e-ae83546279ce.wav';
function log(message, isError = false) {
const logElem = document.getElementById('debug-log');
const entry = document.createElement('div');
entry.textContent = `[${new Date().toLocaleTimeString()}] ${message}`;
if (isError) entry.className = 'error';
else entry.className = 'success';
logElem.appendChild(entry);
console.log(message);
}
// 方法1: 原生Audio元素
function playAudioNative() {
log('尝试使用原生Audio元素播放...');
const audio = document.getElementById('audio-native');
audio.src = audioUrl;
audio.onloadeddata = () => log('音频加载成功,准备播放');
audio.onplay = () => log('开始播放');
audio.onplaying = () => log('正在播放');
audio.onerror = (e) => {
const errorMsg = getAudioErrorMessage(audio.error);
log(`音频加载错误: ${errorMsg}`, true);
};
audio.play().catch(err => {
log(`播放失败: ${err.message}`, true);
});
}
// 方法2: Fetch + Blob URL
async function playAudioFetch() {
log('尝试使用Fetch方式获取音频...');
try {
const response = await fetch(audioUrl);
if (!response.ok) {
log(`服务器响应错误: ${response.status} ${response.statusText}`, true);
return;
}
const blob = await response.blob();
log(`获取音频成功,大小: ${(blob.size / 1024).toFixed(2)}KB`);
const audio = document.getElementById('audio-fetch');
const url = URL.createObjectURL(blob);
audio.src = url;
audio.onloadeddata = () => log('Blob音频加载成功');
audio.onerror = (e) => log(`Blob音频错误: ${getAudioErrorMessage(audio.error)}`, true);
audio.play().catch(err => {
log(`Blob播放失败: ${err.message}`, true);
});
} catch (err) {
log(`Fetch错误: ${err.message}`, true);
}
}
// 方法3: XMLHttpRequest
function playAudioXHR() {
log('尝试使用XHR方式获取音频...');
const xhr = new XMLHttpRequest();
xhr.open('GET', audioUrl, true);
xhr.responseType = 'blob';
xhr.onload = function() {
if (xhr.status === 200) {
log(`XHR获取音频成功,大小: ${(xhr.response.size / 1024).toFixed(2)}KB`);
const audio = document.getElementById('audio-xhr');
const url = URL.createObjectURL(xhr.response);
audio.src = url;
audio.onloadeddata = () => log('XHR音频加载成功');
audio.onerror = (e) => log(`XHR音频错误: ${getAudioErrorMessage(audio.error)}`, true);
audio.play().catch(err => {
log(`XHR播放失败: ${err.message}`, true);
});
} else {
log(`XHR错误: ${xhr.status} ${xhr.statusText}`, true);
}
};
xhr.onerror = function() {
log('XHR网络错误', true);
};
xhr.send();
}
// 方法4: iframe嵌入
function showAudioFrame() {
log('尝试使用iframe嵌入音频...');
const container = document.getElementById('frame-container');
container.innerHTML = `<iframe src="${audioUrl}" width="300" height="100"></iframe>`;
log('已加载iframe');
}
// 检查文件是否存在
async function checkAudioFile() {
const statusElem = document.getElementById('file-status');
statusElem.textContent = '正在检查文件...';
try {
const response = await fetch(audioUrl, { method: 'HEAD' });
if (response.ok) {
const contentType = response.headers.get('content-type') || '未知';
const contentLength = response.headers.get('content-length') || '未知';
statusElem.innerHTML = `
<div class="success">文件存在!</div>
<div>Content-Type: ${contentType}</div>
<div>Content-Length: ${contentLength} 字节</div>
`;
// 检查CORS头
const cors = response.headers.get('access-control-allow-origin');
if (cors) {
statusElem.innerHTML += `<div>CORS: ${cors}</div>`;
} else {
statusElem.innerHTML += `<div class="error">警告: 未检测到CORS头</div>`;
}
} else {
statusElem.innerHTML = `<div class="error">文件不存在或无权访问! 状态码: ${response.status}</div>`;
}
} catch (err) {
statusElem.innerHTML = `<div class="error">检查失败: ${err.message}</div>`;
}
}
// 获取音频错误信息
function getAudioErrorMessage(error) {
if (!error) return '未知错误';
// 媒体错误代码
switch(error.code) {
case 1: return 'MEDIA_ERR_ABORTED: 用户中止了获取过程';
case 2: return 'MEDIA_ERR_NETWORK: 网络错误导致下载失败';
case 3: return 'MEDIA_ERR_DECODE: 解码失败,可能是文件损坏或浏览器不支持的格式';
case 4: return 'MEDIA_ERR_SRC_NOT_SUPPORTED: 媒体源不可用或不支持';
default: return `未知错误(${error.code})`;
}
}
// 页面加载时记录浏览器信息
window.onload = function() {
log(`浏览器: ${navigator.userAgent}`);
log('页面已加载,请点击按钮测试不同播放方法');
};
</script>
</body>
</html>