Python wav文件的二进制字符串
我正在尝试为我的webapp编写一个wav上传函数。前端部分似乎工作得很好。问题是我的后端(python)。当它接收到二进制数据时,我不知道如何将其写入文件。我试着使用基本的写入功能,但声音已经损坏。。。听起来像“gobbly-gook”。有没有一种用Python编写wav文件的特殊方法 这是我的后台。。。没什么大不了的Python wav文件的二进制字符串,python,python-2.7,Python,Python 2.7,我正在尝试为我的webapp编写一个wav上传函数。前端部分似乎工作得很好。问题是我的后端(python)。当它接收到二进制数据时,我不知道如何将其写入文件。我试着使用基本的写入功能,但声音已经损坏。。。听起来像“gobbly-gook”。有没有一种用Python编写wav文件的特殊方法 这是我的后台。。。没什么大不了的 form = cgi.FieldStorage() fileData = str(form.getvalue('data')) with open("audio", 'w')
form = cgi.FieldStorage()
fileData = str(form.getvalue('data'))
with open("audio", 'w') as file:
file.write(fileData)
我甚至试过
with open("audio", 'wb') as file:
file.write(fileData)
我正在使用aplay播放声音,我注意到所有的属性都被弄乱了
之前:
有符号16位小端点,速率44100 Hz,立体声
上传后:
无符号8位,速率8000 Hz,单声道可能有帮助吗
import wave
import struct
import numpy as np
rate = 44100
def sine_samples(freq, dur):
# Get (sample rate * duration) samples on X axis (between freq
# occilations of 2pi)
X = (2*np.pi*freq/rate) * np.arange(rate*dur)
# Get sine values for these X axis samples (as integers)
S = (32767*np.sin(X)).astype(int)
# Pack integers as signed "short" integers (-32767 to 32767)
as_packed_bytes = (map(lambda v:struct.pack('h',v), S))
return as_packed_bytes
def output_wave(path, frames):
# Python 3.X allows the use of the with statement
# with wave.open(path,'w') as output:
# # Set parameters for output WAV file
# output.setparams((2,2,rate,0,'NONE','not compressed'))
# output.writeframes(frames)
output = wave.open(path,'w')
output.setparams((2,2,rate,0,'NONE','not compressed'))
output.writeframes(frames)
output.close()
def output_sound(path, freq, dur):
# join the packed bytes into a single bytes frame
frames = b''.join(sine_samples(freq,dur))
# output frames to file
output_wave(path, frames)
output_sound('sine440.wav', 440, 2)
编辑:
我认为在您的情况下,您可能只需要:
packedData = map(lambda v:struct.pack('h',v), fileData)
frames = b''.join(packedData)
output_wave('example.wav', frames)
在这种情况下,您只需要知道采样率。检查wave模块,了解其他输出文件参数的信息(即setparams
方法的参数)。可能会有帮助吗
import wave
import struct
import numpy as np
rate = 44100
def sine_samples(freq, dur):
# Get (sample rate * duration) samples on X axis (between freq
# occilations of 2pi)
X = (2*np.pi*freq/rate) * np.arange(rate*dur)
# Get sine values for these X axis samples (as integers)
S = (32767*np.sin(X)).astype(int)
# Pack integers as signed "short" integers (-32767 to 32767)
as_packed_bytes = (map(lambda v:struct.pack('h',v), S))
return as_packed_bytes
def output_wave(path, frames):
# Python 3.X allows the use of the with statement
# with wave.open(path,'w') as output:
# # Set parameters for output WAV file
# output.setparams((2,2,rate,0,'NONE','not compressed'))
# output.writeframes(frames)
output = wave.open(path,'w')
output.setparams((2,2,rate,0,'NONE','not compressed'))
output.writeframes(frames)
output.close()
def output_sound(path, freq, dur):
# join the packed bytes into a single bytes frame
frames = b''.join(sine_samples(freq,dur))
# output frames to file
output_wave(path, frames)
output_sound('sine440.wav', 440, 2)
编辑:
我认为在您的情况下,您可能只需要:
packedData = map(lambda v:struct.pack('h',v), fileData)
frames = b''.join(packedData)
output_wave('example.wav', frames)
在这种情况下,您只需要知道采样率。检查wave模块,了解其他输出文件参数的信息(即
setparams
方法的参数)。只要数据没有损坏,我粘贴的代码将写入wav文件。不需要使用波形模块
with open("audio", 'w') as file:
file.write(fileData)
我最初是以FileAPI.readAsBinaryString的形式读取Javascript中的文件。我将其更改为FileAPI.readAsDataURL,然后使用base64.decode()在python中对其进行解码。一旦我解码了它,我就可以把数据写入一个文件。.wav文件状态良好。只要数据没有损坏,我粘贴的代码将编写一个wav文件。不需要使用波形模块
with open("audio", 'w') as file:
file.write(fileData)
我最初是以FileAPI.readAsBinaryString的形式读取Javascript中的文件。我将其更改为FileAPI.readAsDataURL,然后使用base64.decode()在python中对其进行解码。一旦我解码了它,我就可以把数据写入一个文件。.wav文件状态良好。什么是
cgi.FieldStorage()
?此外,您不应该用二进制数据生成字符串。CGI(公共网关接口)是我用来获取HTTP请求的。我的声音文件二进制数据通过AJAX请求发送,脚本从cgi.FieldStorage读取二进制字符串。那么您使用的是Python的内置模块?在发布原始声音数据的情况下,我认为您根本不应该使用cgi.FieldStorage
。我忘了CGI是如何工作的,但我想你只是从标准输入法读取数据FieldStorage
看起来像是用于
标记的。如果下载的数据没有格式化为文件格式,那么简单地写入文件就太简单了。Python有一个会有帮助的参数。@Mark Ransom-如果我使用它,那么我必须设置所有参数(例如帧速率和nframes)。如果用户正在上载文件,我想这些参数不可用。什么是cgi.FieldStorage()
?此外,您不应该用二进制数据生成字符串。CGI(公共网关接口)是我用来获取HTTP请求的。我的声音文件二进制数据通过AJAX请求发送,脚本从cgi.FieldStorage读取二进制字符串。那么您使用的是Python的内置模块?在发布原始声音数据的情况下,我认为您根本不应该使用cgi.FieldStorage
。我忘了CGI是如何工作的,但我想你只是从标准输入法读取数据FieldStorage
看起来像是用于
标记的。如果下载的数据没有格式化为文件格式,那么简单地写入文件就太简单了。Python有一个会有帮助的参数。@Mark Ransom-如果我使用它,那么我必须设置所有参数(例如帧速率和nframes)。如果用户正在上传文件,我想我不会有这些参数。我唯一关心的是上传的文件。我不知道频率和持续时间。这就是为什么我希望制作一个二进制副本。我在Javascript中使用file.readAsBinaryString。我猜我必须得到频率、持续时间等等。。。在我把它发送到python之前?我不这么认为。我只是把这段代码放在那里,作为如何生成原始二进制数据的示例。我会更新我的评论。我可以用上面发布的代码来做。发送的数据实际上是乱七八糟的。我通过将其作为base64编码发送,而不仅仅是二进制来修复它。不过还是谢谢你的帮助。我唯一关心的是上传的文件。我不知道频率和持续时间。这就是为什么我希望制作一个二进制副本。我在Javascript中使用file.readAsBinaryString。我猜我必须得到频率、持续时间等等。。。在我把它发送到python之前?我不这么认为。我只是把这段代码放在那里,作为如何生成原始二进制数据的示例。我会更新我的评论。我可以用上面发布的代码来做。发送的数据实际上是乱七八糟的。我通过将其作为base64编码发送,而不仅仅是二进制来修复它。不过还是要谢谢你的帮助。