来自用户麦克风的WAV文件与来自文件的WAV:有些差异会导致错误,但这些不同之处是什么



现在我有两种向服务器发送WAV文件的方法。用户可以直接上传所述文件,或者在他们的麦克风上录制。一旦文件被发送,它们将以几乎相同的方式进行处理。文件被发送到S3,稍后可以通过点击某个链接来播放(该链接通过audio = new Audio('https://S3.url'); audio.play()播放文件

处理来自麦克风的文件时:

  • audio.play()似乎有效。audio对象中的所有内容都是相同的(除了URL本身(,但声音实际上不会通过扬声器播放。另一方面,对于上传的文件,声音通过扬声器播放
  • 当我直接访问URL时,它们都会打开声音播放器(在Chrome中(或提示下载WAV文件(在Firefox中(。声音播放器可以适当地播放这两种声音,下载的WAV文件都包含各自的声音,其他程序可以播放这些声音
  • 如果我真的从用户的麦克风下载带有声音的文件,而不是直接将其发送到服务器,然后手动上传WAV文件,一切都会正常工作(就像其他上传的WAV文件一样(
  • 在麦克风声音上传到某个地方,然后下载的任何场景中,它都会作为WAV文件下载并相应播放。任何使用重新上传的WAV文件的东西都能按预期工作

以下是我如何从用户的麦克风中获得声音。首先,我使用WebAudioTrack在我的网页上放置一个录制按钮。一旦用户停止录制,他们就会点击提交按钮,该按钮将运行:

saveRecButton.addEventListener("click", function() {
save_recording(audioTrack.audioData.getChannelData(0))
});

这里,audioTrack.audioData是包含所记录的声音的AudioBuffer。CCD_ 5是表示声音的CCD_。我通过AJAX将这个数组发送到服务器(Django(:

function save_recording(channelData){
var uploadFormData = new FormData();
uploadFormData.append('data', $('#some_field').val());
...
uploadFormData.append('audio', channelData);
$.ajax({
'method': 'POST',
'url': '/soundtests/save_recording/',
'data': uploadFormData,
'cache': false,
'contentType': false,
'processData': false,
success: function(dataReturned) { 
if (dataReturned != "success") {
[- Do Some Stuff -]
}
});
}

然后,使用wavio,从数组中写入WAV文件:

import wavio
import tempfile
from numpy import array
def save_recording(request):
if request.is_ajax() and request.method == 'POST':
form = SoundForm(request.POST)
if form.is_valid():
with tempfile.NamedTemporaryFile() as sound_recording:
sound_array_string = request.POST.get('audio')
sound_array = array([float(x) for x in sound_array_string.split(',')])
wavio.write(sound_recording, sound_array, 48000, sampwidth=4)
sound_recording.seek(0)
s3_bucket.put_object(Key=some_key, Body=sound_recording, ContentType='audio/x-wav')
return HttpResponse('success')

然后,当需要收听声音时:

在Python中:

import boto3
session = boto3.Session(aws_access_key_id='key', aws_secret_access_key='s_key')
bucket = self.session.resource('s3').Bucket(name='bucket_name')
url = session.client('s3').generate_presigned_url('get_object', Params={'Bucket':bucket.name, Key:'appropriate_sound_key'})

然后,在JavaScript:中

audio = new Audio('url_given_by_above_python')
audio.play()

如果我上传文件,音频会播放得很好,但如果我使用用户的麦克风,音频根本不会播放。当我将麦克风声音上传到S3,然后重新下载时,WAV文件中是否有我可能遗漏的内容?我不知道下一步该去哪里;这两个文件之间的内容似乎完全相同。下面是两个Audio对象的转储,其中包含来自用户麦克风的URL。另一个是从手动上传的文件创建的,该文件是从该用户麦克风重新下载的。文件看起来完全相同(除了URL,它在访问或下载时同时播放两种声音(。

这里肯定有一些不同,但我不知道这是什么,我已经为此挣扎了几天。:(

您正在创建的声音文件是32位PCM,这可以说是一种非标准音频编解码器。Chrome支持它(源代码(,但Firefox不支持(源代码,错误(。

将其编码为16位PCM,它将被普遍接受。

编辑:正如评论中提到的,这是有问题的参数。