python - 如何使用 python 从 sqlite BLOB 字段创建 WAV 文件
问题描述
我从一个包含来自仪器的单声道 wav 数据的 ms 访问数据库中得到一个 blob。这只是1秒。它以不同的值开头,所以我的意思是它是纯 wav 数据
b'\\f_?\xb2\xca^??;]?\xa9(Z?\xf8\x87V?\x8e\x11S?PCP?\xcc\x06O?\xf1RN?a\x07M?\x83DK?\xa9hH?\x94\nE?\x9d.B?mb??\xf9\x05=?\xf5X;?\xeb|:?M\xc7:?Qg;?\xbd\x0c<?\x8c\x05=?\x85I>?v\xd2??/`B?\xfe\xafF?\xafFL?b3S?,\x8dZ?\xc1}`?\x16Le?\xef\xb2h?@#j?a\x02k?\xb3\xcck?D\xd2l?\xec\xaen?\x19\xccp?\x9e\xdfr?\x82Uu?\x81\x03x?tCz?\xa5E{?\xec\xecz?5\xcey?\x08\x82x?\x83\xd2v?\xec\xb3t?\x8f\x04r?\xce\x08n?\x8d3h?\x11@a?\x1e\xfbX?\x9b\x11P?\xfc}G?\x08\'
...
我使用了这些包wave
并soundfile
创建了一个 wav 文件,但它从未符合原始格式。我可以从原始软件中导出一个文件,所以它应该可以工作。
import wave
wav = wave.open(wavfile, 'rb')
print("filename :", wavfile)
print("channels :", wav.getnchannels())
print("sampwidth:", wav.getsampwidth())
print("framerate:", wav.getframerate())
print("nframes :", wav.getnframes())
输出是:
filename : c:\DATEN\TS_org.wav
channels : 1
sampwidth: 2
framerate: 32768
nframes : 16384
我确实将这些参数设置为新文件并添加了 BLOB:
def create_audiofile(blobin, saveto):
nchannels = 1
#ok to read in another analyser, but wrong sound sampwidth = 1
sampwidth = 2
framerate = 32768
nframes = 16384
audio = wave.open (saveto, 'wb')
audio.setnchannels (nchannels)
audio.setsampwidth (sampwidth)
audio.setframerate (framerate)
audio.setnframes (nframes)
audio.writeframes(blobin)
#also no success
#audio.writeframesraw(blobin)
我在 SO 中检查了几个网站和答案。这里有一个很好的描述,但我从来没有得到一个工作的 wav 文件。
原始文件的前 36 个字节如下所示:
Bytenr :0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
integer:82 73 70 70 36 128 0 0 87 65 86 69 102 109 116 32 16 0 0 0 1 0 1 0 0 128 0 0 0 0 1 0 2 0 16 0
hexcode:0x52 0x49 0x46 0x46 0x24 0x80 0x0 0x0 0x57 0x41 0x56 0x45 0x66 0x6d 0x74 0x20 0x10 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x0 0x80 0x0 0x0 0x0 0x0 0x1 0x0 0x2 0x0 0x10 0x0
ASCII :R I F F $ W A V E f m t # # # # # #
如何使用这些信息来构建新的 wav 文件?
编辑
这是来自@mivk 的有趣脚本,作为用于测试转换的 python 脚本:
import subprocess
infile =("e:\\data\\wav\\raw.pcm")
ffmpeg = "e:\\data\\wav\\ffmpeg.exe"
samples = [8000, 11025, 22050, 16000, 32000, 22050, 44100]
formats = ['alaw', 'f32be', 'f32le', 'f64be', 'f64le', 'mulaw', 's16be', 's16le', 's24be', 's24le', 's32be',
's32le', 's8', 'u16be', 'u16le', 'u24be', 'u24le', 'u32be', 'u32le', 'u8']
for ar in samples:
for f in formats:
outfile = infile[:-4] + "_%s_%s.wav"%(f, ar)
order = '%s -f %s -ar %d -ac 1 -i %s %s'%(ffmpeg, f, ar, infile, outfile)
subprocess.call(order)
解决方案
推荐阅读
- ruby-on-rails - Ruby on Rails 6 AWS Elastic Beanstalk 部署命令 reload_initctl_for_sidekiq 失败
- mysql - 查询优化的 SQL 技巧
- git - 远程:在 github 上拒绝回购的权限
- reactjs - 是的验证问题:具有各自值的字段仍然说字段是必需的
- solr - 如何使用数据类型且不带任何后缀或前缀来决定 solr 中的动态文件
- git - 如何从我的 github 存储库中删除我的电子邮件
- php - 将自定义 HTML 属性添加到 Grav 生成表单的按钮
- embedded - 如何组织 freeRTOS 项目
- javascript - 在反应中使用索引作为键。什么时候有影响,什么时候没有?
- java - Java中有没有办法在一个类中设置变量的值并能够从另一个类中访问