用户麦克风提供的WAV文件与文件提供的WAV文件:有些差异会导致错误,但是有什么不同?

时间:2018-07-19 16:00:12

标签: 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是包含记录的声音的AudioBuffergetChannelData(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除外,URL在访问或下载时会同时播放两种声音)。

这里必须有一些区别,但是我不知道它是什么,并且已经为此苦苦挣扎了几天。 :(

1 个答案:

答案 0 :(得分:3)

您创建的声音文件是32位PCM,这可以说是非标准的音频编解码器。 Chrome支持(source),但Firefox不支持(sourcebug)。

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

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