【发布时间】:2018-12-27 20:39:29
【问题描述】:
现在我有两种方法可以将 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,它在访问或下载时会播放两种声音)。
这里肯定有一些不同,但我不知道它是什么,并且已经为此苦苦挣扎了几天。 :(
【问题讨论】:
-
每个文件的
fmt块包含什么?
标签: javascript django audio amazon-s3