You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

本地可播放但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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 19:40:26