javascript - 来自用户麦克风的 WAV 文件与来自文件 : Some difference is causing bugs, 的 WAV 文件,但它们有何不同?

标签 javascript django audio amazon-s3

现在我有两种方法可以将 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包含录制的声音。 getChannelData(0) 是一个代表声音的 Float32Array。我通过 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 支持它 ( source ) 但 Firefox 不支持 ( source , bug )。

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

编辑:如评论中所述,this是有问题的参数。

关于javascript - 来自用户麦克风的 WAV 文件与来自文件 : Some difference is causing bugs, 的 WAV 文件,但它们有何不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51427208/

相关文章:

python - Python 中的线程 : Python 'args' is an invalid keyword argument for this function, 为什么?

javascript - 在javascript中获取声音长度(持续时间)

javascript - cordova应用程序可以调用android特定操作

javascript - 正则表达式拆分可选组

javascript - 更好的解决方案或替换window.unload

linux - 如何跨平台从 Haskell 代码播放音频文件

Android 在通话期间播放音频文件

javascript - 如何通过 .xyz.com/#divname 访问我的网站,有人可以帮助我吗?

javascript - 如何在托管 Web 服务器上实际部署 Node.js(或 django)项目?

python - 在 python 中启动 python 和时区问题