本地可播放但Live Server/GitHub Pages无法播放音频的问题求助
本地可播放但Live Server/GitHub Pages无法播放音频的问题求助
大家好,我最近做了一个音频可视化项目,遇到了一个头疼的播放问题,想请教下各位:
- 项目本地下载运行时一切正常,但部署到GitHub Pages(或者用Live Server启动)后,完全没有声音,不管是预加载的音频文件还是用户上传的文件都没法播放
- 控制台没有任何错误提示,音频看起来已经加载完成(比如能看到歌曲时长),但就是听不到声音:
- Safari中点击播放后,进度条会移动,但没声音;Chrome中进度条完全不动,但两个浏览器都能拖动进度条调整位置
- 我排查时发现一个关键线索:把代码里的
const source = audioCtx.createMediaElementSource(audio);这一行注释掉后,音频就能正常播放了 - 我尝试添加
source.connect(audioCtx.destination);来重新连接音频,也没用,audio是关联到HTML里的audio标签的 - 确认不是CORS问题,当MP3文件在开发者工具中显示时(出现时机好像很随机),标记的是同源
- 即使用户主动触发操作(比如点击按钮后再播放),音频还是听不到
后续测试更新
- 更新1:在GitHub Codespaces里用Live Server运行时,Chrome浏览器下程序可以正常工作,但Safari依然不行
- 更新2:Safari还有个奇怪的现象:第一次打开本地Live Server时能正常播放,但只要浏览器打开过这个页面,之后再访问就听不到声音,必须完全退出Safari再重新打开才行
注:我目前只能在Safari和Chrome上测试,项目里的示例音频没法在这里加载,但我把完整代码贴在下面了:
window.addEventListener("load", function () { //added by SO recommendation, changed nothing //colors const colorPallette=[ ["#060647","#0209d1",(i)=>`rgb(105 25 ${(i/FreqBufferLength) * 115+(255-115)})`], ["#fadb61","#b00202",(i)=>`rgb(${(i/FreqBufferLength) * 15+(255-15)} 100 25)`], ] let colorOption=0 //set up list of default songs const audioMap = new Map(); audioMap.set("Sample1.mp3","./Sample1.mp3") audioMap.set("Sample2.mp3","./Sample2.mp3") //set up select and file input const select=document.querySelector("select") const fileInput = document.querySelector('input[type="file"]'); //set up audio const audio=document.querySelector("audio") const audioCtx = new AudioContext(); const source = audioCtx.createMediaElementSource(audio); //set up analyser const analyser = audioCtx.createAnalyser(); source.connect(analyser); source.connect(audioCtx.destination); //set up analyser arrays const FreqBufferLength = analyser.frequencyBinCount; const TimeBufferLength = analyser.fftSize; const timeArray = new Uint8Array(TimeBufferLength); const freqArray = new Uint8Array(FreqBufferLength); //set up canvas const canvas=document.querySelector("canvas") canvas.width=600; canvas.height=300; const w=canvas.width; const h=canvas.height; const canvasCtx=canvas.getContext("2d"); canvasCtx.lineWidth = 2; //set up document events document.querySelector(".color").addEventListener("click",()=> {colorOption++ colorOption=colorOption%colorPallette.length }) document.querySelector(".fileButton").addEventListener("click",()=>fileInput.click()) fileInput.addEventListener('change', (event) => { for (const file of fileInput.files){ const url = URL.createObjectURL(file); canvasCtx.fillStyle = colorPallette[colorOption][0]; canvasCtx.fillRect(0, 0, w, h); select.innerHTML=`<option>${file.name}</option>`+select.innerHTML audio.src=url audioMap.set(file.name, url); select.value=file.name } }) //start let val=select.value requestAnimationFrame(draw) function draw(){ //set song if(val!=select.value){ audio.src=audioMap.get(select.value) val=select.value } //pause visualizer if paused if(!audio.paused){ analyser.getByteFrequencyData(freqArray); analyser.getByteTimeDomainData(timeArray); } //set up canvas colors canvasCtx.fillStyle = colorPallette[colorOption][0]; canvasCtx.fillRect(0, 0, w, h); let x=0 let skip=5 /////////////// ///frequency/// /////////////// const barWidth = (w / FreqBufferLength)*1.5*skip; let barHeight; x = 0; for (let i = 0; i < FreqBufferLength; i+=skip) { barHeight = freqArray[i]; canvasCtx.fillStyle = colorPallette[colorOption][2](i); canvasCtx.fillRect(x, (h/2)-barHeight/2, barWidth, barHeight+1); x += (barWidth); } canvasCtx.strokeStyle = colorPallette[colorOption][1]; canvasCtx.beginPath(); x = 0; //////// //time// //////// let timeSkip=1 const sw = (w / TimeBufferLength)*timeSkip; for(let i=0;i<TimeBufferLength;i+=timeSkip){ const v = timeArray[i] / 128.0; const y = v * (h / 2); if (i === 0) { canvasCtx.moveTo(x, y); } else { canvasCtx.lineTo(x, y); } x += sw; } canvasCtx.stroke(); canvasCtx.closePath(); requestAnimationFrame(draw) } })
body{ background-color: black; overflow-x: hidden; } h1{ color:white; font-size:70px; margin-bottom:30px; font-family:sans-serif; } canvas{ width:600px; height:300px; border: 2px solid rgb(255, 255, 255); border-radius:20px; position:relative; z-index:0; } audio{ height:50px; z-index:100; position:relative; } select{ margin-bottom:5px; height:30px; font-size: 15px; width:300px; text-align:center; border-radius:5px; } .fileButton{ margin-bottom:5px; font-size: 20px; width:300px; height:50px; align-items:center; border-radius:20px; border:none; } .color{ margin-top:5px; font-size: 20px; height:50px; width:300px; align-items:center; border-radius:50px; border:none; } input{ display:none; } .flex{ display:flex; width:100vw; height:100%; align-items:center; justify-content: center; flex-flow:column; } button:hover{ background-color:rgb(191, 187, 187); } button{ background-color:rgb(255, 255, 255); } button:active{ background-color:rgb(168, 161, 161); }
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="shortcut icon" href="#"> <title>Audio Visualizer</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="flex"> <h1>Audio Viewer</h1> <input multiple type="file" id="input"/> <button class="fileButton">Add Song</button> <select> <option>Sample1.mp3</option> <option>Sample2.mp3</option> </select> <canvas></canvas> <audio preload="auto" controls src="./Sample1.mp3"></audio> <!-- Having cors:anonymous changes nothing --> <button class="color">Change Theme</button> </div> <script src="index.js"></script> </body> </html>
备注:内容来源于stack exchange,提问作者Jocowl
相关产品推荐
相关产品推荐

