coderDemo

html,
body {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
    overflow: hidden;
}

#upload {
    position: fixed;
    top: 0;
    left: 0;
}

audio {
    position: fixed;
    top: 0;
    right: 0;
}
<input type="file" id="upload" accept="audio/mpeg">
  const upload = document.querySelector(\'#upload\')

  upload.addEventListener(\'change\', (e) => {
    const [file] = e.target.files
    if (!file) upload.value = \'\'
    const { type } = file
    if (!type.includes(\'audio\')) {
      alert(\'仅支持音频格式文件\')
      upload.value = \'\'
      return false
    }
    const url = URL.createObjectURL(file)
    draw(url)
  })

  function draw(url) {
    const {
      clientWidth: width,
      clientHeight: height,
    } = document.body
    const audio = new Audio
    audio.src = url
    audio.controls = true
    audio.load()
    const canvas = document.createElement(\'canvas\')
    canvas.width = width
    canvas.height = height
    document.body.appendChild(audio)
    document.body.appendChild(canvas)
    const canvasCtx = canvas.getContext(\'2d\')
    const audioCtx = new AudioContext
    const sourceNode = audioCtx.createMediaElementSource(audio)
    // 音频分析器
    const analyser = audioCtx.createAnalyser()
    analyser.fftSize = 128 // FFT
    sourceNode.connect(analyser)
    analyser.connect(audioCtx.destination)
    const len = analyser.frequencyBinCount
    const buffer = new Uint8Array(len)
    const gap = 2 // 间隙
    const pillarWidth = (width / len) - gap
    const gradient = canvasCtx.createLinearGradient(0, 0, 0, 500)
    gradient.addColorStop(.8, \'#1eec1e\')
    gradient.addColorStop(.5, \'#c97a3d\')
    gradient.addColorStop(0, \'#f00f00\')

    const render = () => {
      canvasCtx.fillStyle = \'#fff\'
      canvasCtx.fillRect(0, 0, width, height)
      analyser.getByteFrequencyData(buffer)
      let x = 0
      buffer.forEach(v => {
        const pillarHeight = (v / 255) * height
        canvasCtx.fillStyle = gradient
        canvasCtx.fillRect(x, height - (pillarHeight || 2), pillarWidth, pillarHeight || 2)
        x += (pillarWidth + gap)
      })
      requestAnimationFrame(render)
    }
    render()
    audio.play()
  }

分类:

技术点:

相关文章:

  • 2021-09-18
  • 2021-11-29
  • 2021-08-31
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-09-24
  • 2022-12-23
  • 2021-06-25
  • 2021-12-24
  • 2021-12-04
相关资源
相似解决方案