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')

我正在尝试为我的webapp编写一个wav上传函数。前端部分似乎工作得很好。问题是我的后端(python)。当它接收到二进制数据时,我不知道如何将其写入文件。我试着使用基本的写入功能,但声音已经损坏。。。听起来像“gobbly-gook”。有没有一种用Python编写wav文件的特殊方法

这是我的后台。。。没什么大不了的

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编码发送,而不仅仅是二进制来修复它。不过还是要谢谢你的帮助。