标签: web-audio-api

在重构时,如何在段之间没有间隙(或音频弹出)的情况​​下对音频文件进行编码和分段?

我正在开发一个需要流式传输和同步多个音频文件的Web应用程序.为此,我使用Web Audio API而非HTML5音频标签,因为计时音频的重要性.

目前,我正在使用FFMPEG的分段功能将音频文件编码并分段为更小的块.我正在对它们进行分段的原因是我可以从文件的中间开始流式传输而不是从头开始(否则我只是使用UNIX拆分来拆分文件,如下所示.问题是当我串起音频片段重新组合在一起,我在片段之间获得了音频流.

如果我在.wav文件中使用PCM编码(pcm_s24le)对段进行编码,则回放是无缝的,这使我相信编码器正在填充文件的开头或结尾.由于我将处理许多不同的音频文件,使用.wav将需要太多的带宽.

我正在寻找以下解决方案之一:

  • 如何无缝分割编码的音频文件,
  • 如何强制编码器使用ffmpeg(或其他实用程序)填充音频帧,或者
  • 什么是更好的方式来流式传输音频(从任意轨道时间开始)而不使用音频标签?

系统信息

  • 自定义node.js服务器
  • 上传音频文件后,node.js将数据传输到ffmpeg的编码器中
  • 需要使用HTML5 Web Audio API支持的编码
  • 服务器通过WebSockets套接字一次发送音频块1

提前致谢.我试图尽可能清楚,但如果你需要澄清我会更愿意提供它.

html5 ffmpeg audio-streaming node.js web-audio-api

8
推荐指数
1
解决办法
1136
查看次数

使用WebAudio API计算Live Mic Audio频率的简单代码

我有网站,我需要显示Live Mic Audio的频率.我有一个这个代码,但它很难理解(它使用傅里叶变换和所有).在一些研究中,我知道getByteFrequencyData()哪个返回音频的频率.有没有人之前使用过Live Mic Audio,最好是在Web Audio API中?

javascript audio frequency-analysis web-audio-api

8
推荐指数
2
解决办法
9841
查看次数

如何使用React在音频元素上设置srcObject

我一直在尝试src在React中设置音频标签的属性,但是轨道永远不会播放.

playTrack(track) {
    const stream = new MediaStream()
    stream.addTrack(track)
    this.setState(() => ({ stream }))
}

render() {
    return (
        <audio src={this.state.stream || null} controls volume="true" autoPlay />
    )
}
Run Code Online (Sandbox Code Playgroud)

当我检查chrome调试器时,它显示音频标签已[MediaStream]设置为其源,但没有播放,所有控件都保持灰色.

这样做而不是设置状态有效,但我认为这在React中非常不受欢迎.

const audio = document.querySelector('audio')
audio.srcObject = stream
Run Code Online (Sandbox Code Playgroud)

reactjs web-audio-api

8
推荐指数
2
解决办法
4702
查看次数

audioParam.exponentialRampToValueAtTime如何工作?

我无法通过GainNode的exponentialRampToValueAtTime获得音量的滑动变化.

这是一个例子:

var context = new AudioContext(),
    osc = context.createOscillator(),
    gain = context.createGain();

osc.frequency.value = 440; // A note
osc.start( 0 );
osc.connect( gain );

gain.gain.value = 0;
gain.connect( context.destination );

gain.gain.cancelScheduledValues( 0 );
gain.gain.setValueAtTime( 0, context.currentTime );
gain.gain.exponentialRampToValueAtTime( 1, context.currentTime + 2 );
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这应该逐渐增加音量,直到达到1(100%),整个过程应该花费2秒.这个假设是否正确?

如果是,为什么保持0为2秒,然后突然切换到满音量?

提前感谢您的时间和精力.

javascript web-audio-api

7
推荐指数
1
解决办法
1320
查看次数

使用 AudioContext (Web Audio API) 断开节点的问题

我正在构建一个显示有关视频音频的信息的组件。我使用AudioContext接口从 HTML5 视频元素获取音频样本。第一次创建组件时它工作正常,但是当卸载组件然后在稍后重新创建时,我收到以下错误消息:

未捕获的 InvalidStateError:无法在“AudioContext”上执行“createMediaElementSource”:HTMLMediaElement 之前已连接到不同的 MediaElementSourceNode。

这是我获取音频的方式:

const video = document.querySelectorAll('video')[0]

if (!window.audioContext) {
  window.audioContext = new (window.AudioContext || window.webkitAudioContext)
}

if (!this.source && !this.scriptNode) {
  this.source = window.audioContext.createMediaElementSource(video)
  this.scriptNode = window.audioContext.createScriptProcessor(4096, 1, 1)
}

this.scriptNode.onaudioprocess = (evt) => {
 // Processing audio works fine...
}

this.source.connect(this.scriptNode)
this.scriptNode.connect(window.audioContext.destination)
Run Code Online (Sandbox Code Playgroud)

当组件被卸载时,我会这样做:

if (this.source && this.scriptNode) {
  this.source.disconnect(this.scriptNode)
  this.scriptNode.disconnect(window.audioContext.destination)
}
Run Code Online (Sandbox Code Playgroud)

我认为这会让我处于可以安全地创建和连接新节点的状态。但是下次挂载组件时,这个块会抛出前面提到的错误:

if (!this.source && !this.scriptNode) {
  this.source = window.audioContext.createMediaElementSource(video) // this throws the error
  this.scriptNode = window.audioContext.createScriptProcessor(4096, 1, 1)
} …
Run Code Online (Sandbox Code Playgroud)

html javascript audio web-audio-api

7
推荐指数
1
解决办法
5517
查看次数

修剪或剪切用 mediarecorder JS 录制的音频

要求的知识

如何缩短(从前面)一组音频 blob 并仍然具有可播放的音频。

目标

我最终尝试使用 JS MediaRecorder API录制连续 45 秒的音频循环。用户将能够按下按钮,最后 45 秒的音频将被保存。我可以很好地录制、播放和下载单个录音。

问题

当我有一个chunks来自 MediaRecorder的数组称为1000 个 blob 并使用chunks.slice(500, 1000)生成的 blob 数组时,不能用于播放或下载音频。

奇怪的是chunks.slice(0,500)仍然可以正常工作。

代码

let chunks = [];

navigator.mediaDevices.getUserMedia({ audio: true })
  .then((stream) => {
    const mediaRecorder = new MediaRecorder(stream);
    mediaRecorder.ondataavailable = (e) => chunks.push(e.data);
  }

// At some later time, attempt to trim
const trimmedAudio = chunks.slice(500, 1000)
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' });
const audioURL = URL.createObjectURL(blob); …
Run Code Online (Sandbox Code Playgroud)

javascript typed-arrays arraybuffer mediarecorder web-audio-api

7
推荐指数
0
解决办法
2223
查看次数

您如何将多个音轨合并为一个用于 mediaRecorder API?

我想进行录音,从不同的 mediaStream 对象(其中一些,远程)获得多个音轨。使用 getAudioTracks() 方法并使用 addTrack() 将它们添加到 mediaStream 对象。在将最后一个对象作为 mediaRecorder 的参数传递时,我意识到它只记录位于 [0] 位置的音轨。这让我明白 mediaRecorder 能够按类型录制曲目,有没有办法将这些曲目合并为一个曲目以使用 mediaRecorder 正确录制它们?如果可能并且如果它存在,我将不胜感激任何解释这一点的页面

javascript mediarecorder webrtc web-audio-api

7
推荐指数
2
解决办法
3889
查看次数

防止 AudioWorkletNode 内存泄漏

我有一个 AudioWorkletNode,它是类实例的成员。当我删除/终止/删除该实例时,AudioWorkletNode 和 MessagePort 泄漏。

在删除实例之前,我确保相应的 AudioWorkletProcessor 的 process 方法没有运行。我还尝试调用端口的 close() 方法,甚至将 AudioWorkletNode 设置为 null。节点当时是否连接或断开似乎也并不重要。无论哪种方式都会泄漏。

建立audioWorklet模块:

AG_Recorder = class AG_Recorder {

  constructor(outNode) {

      AG_AudioManager.audioCtx.audioWorklet.addModule( '/audioWorkers/recorder.js').then(() => {

        this.recorderNode = new AudioWorkletNode(AG_AudioManager.audioCtx, 'recorder');
        this.recorderNode.connect(outNode);

        this.recorderNode.port.onmessage = (event) => {
          this.handleMessage(event.data);
        };

      }).catch(function (err) {
        console.log('recorder audioworklet error: ', err.name, err.message);
      });

   }
}
Run Code Online (Sandbox Code Playgroud)

以及处理器,为了相关性而强烈缩写:

class RecorderWorkletNode extends AudioWorkletProcessor {

  constructor (options) {

    super(options);
    this._running = true;

    this.port.onmessage = event => {

      if (event.data.release) {
        this._running = false;
      }
    }

    this.port.start();
  } …
Run Code Online (Sandbox Code Playgroud)

javascript web-audio-api

7
推荐指数
1
解决办法
1218
查看次数

IOS13损坏的&lt;audio&gt;标签是否已用作连接到音频上下文的音频缓冲区?

我们目前正在开发一个网站,该网站允许用户播放连接到audiocontext的简单音频标签。我们知道IOS的技术问题,例如由用户手势启动的播放。一切正常,直到IOS12。既然IOS13已经发布,那么什么也无法工作了。

它适用于所有台式机,Android和IOS(最高IOS13)。

有什么想法吗?

使用连接到iPhone的Desktop上的Safari进行调试时,控制台中没有错误消息。

https://codepen.io/gchad/pen/WNNvzzd

<!DOCTYPE html>
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<body>

<div>
  <h1>Play Audio Tag connected to audio context</h1>
  <div id="playbutton" style="width:100px; height:100px; background:blue; color:white; margin:auto; text-align: center; font-size: 30px; cursor: pointer;">
    Play
  </div>

  <audio  id="myPlayer" crossorigin="anonymous" >
    <source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/858/outfoxing.mp3"/>
      <!--http://commondatastorage.googleapis.com/codeskulptor-assets/week7-brrring.m4a-->
  </audio> 
</div>

<script>

var player = document.getElementById('myPlayer'),
playbutton = document.getElementById('playbutton'),
playStatus = 'paused';

var audioContext = new(window.AudioContext || window.webkitAudioContext)();
var audioSource = audioContext.createMediaElementSource(player); 
audioSource.connect(audioContext.destination); 

playbutton.addEventListener('click',function(ev){

  if( playStatus == 'paused'){

    audioContext.resume();
    player.play();
    playbutton.innerHTML = "Pause";
    playStatus = 'isPlaying'; …
Run Code Online (Sandbox Code Playgroud)

web-audio-api ios13

7
推荐指数
1
解决办法
240
查看次数

使用 javacript 将音频逐块流式传输到浏览器的最佳方法是什么

我正在尝试制作一个网络广播电台,我想经常自由地更改歌曲和叠加声音。我想对音频进行速率限制,以便可以在发送之前更改提要。如果可能的话,我还想提供连续的内容

到目前为止,我们对 websockets 的尝试已经接近成功,但质量有点混乱

这是代码:
server.js

const express     = require('express');
const app         = express()
const http        = require('http')
const server      = http.createServer(app)
const { Server }  = require("socket.io")
const io          = new Server(server)
const fs          = require('fs')

const SRC_PATH      = 'src.wav'
const PACKET_SIZE   = 6400
let   PACKET = 0

function getpacket(socket){
    const file_descriptor     = fs.openSync(SRC_PATH, 'r', null)
    const read_offset         = PACKET * PACKET_SIZE
    const buffer              = Buffer.alloc(PACKET_SIZE)
    const buffer_write_offset = 0
    const num_bytes_to_read   = PACKET_SIZE
    const num_bytes_read      = fs.readSync(file_descriptor, buffer, …
Run Code Online (Sandbox Code Playgroud)

javascript streaming audio-streaming node.js web-audio-api

7
推荐指数
1
解决办法
2845
查看次数