import wave,struct
f = wave.open('bird.wav', 'r')
for i in range(5,10):
frame = f.readframes(i)
print frame
struct.unpack('<H',frame)
我使用上面的代码从 python 中的立体声 wav 文件中提取字节。然而,我得到的不是字节,而是一些乱码。使用 struct.unpack() 函数我收到以下错误
"unpack requires a string argument of length 2"
我需要对代码进行哪些更改才能以 1 和 0 打印这些字节?我想稍后修改音频帧的 LSB 以进行隐写术。
最佳答案
我不确定为什么要以二进制形式打印这些字节,但这样做很容易。
您需要将字节转换为整数,然后使用 str.format
方法对其进行格式化,旧的 %
样式格式不能处理位。
执行此转换的简单方法是使用 ord
函数,但对于大量字节,最好通过创建 bytearray
一次性转换它们。
#Some bytes, using hexadecimal escape codes
s = '\x01\x07\x0f\x35\xad\xff'
print ' '.join(['{0:08b}'.format(ord(c)) for c in s])
b = bytearray(s)
print ' '.join(['{0:08b}'.format(u) for u in b])
输出
00000001 00000111 00001111 00110101 10101101 11111111
00000001 00000111 00001111 00110101 10101101 11111111
一般来说,十六进制表示比二进制更方便阅读。
from binascii import hexlify
print hexlify(s)
print ' '.join(['%02X' % u for u in b])
print ' '.join(['%02X' % ord(c) for c in s])
print ' '.join(['{0:02X}'.format(ord(c)) for c in s])
输出
01070f35adff
01 07 0F 35 AD FF
01 07 0F 35 AD FF
01 07 0F 35 AD FF
我刚刚看到你对隐写术的评论。调整字节位的最方便方法是使用bytearray
。您可以使用 str
函数轻松地将 bytearray
转换回字节字符串。
print hexlify(str(b))
输出
01070f35adff
Python 官方文档中描述了字符串格式化选项。对于旧的 %
样式格式,请参阅 5.6.2. String Formatting Operations 。对于现代 str.format
选项,请参阅 7.1.3. Format String Syntax和 7.1.3.1. Format Specification Mini-Language .
在{0:08b}
中,冒号之前的0
是字段位置(在最新版本的Python中可以省略)。它表示我们希望将此格式化代码应用于 .format
的第一个参数,即索引为零的参数。例如,
'{0} {2} {1}'.format('one', 'two', 'three')
打印
one three two
b
表示我们想要将数字打印为二进制。 08
表示我们希望输出为 8 个字符宽,对于小于 8 位的二进制数使用零填充。
在%02X
中,大写的X
表示我们想要以十六进制的形式打印数字,对于大于9的数字使用大写字母A-F,我们可以使用小写的 x
获取小写字母。 02
表示我们希望输出为 2 个字符宽,对于小于 2 个十六进制数字的十六进制数字用零填充。
关于python - 在python中读取WAV文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35518874/