需要把AI生成音频信息通过网络发送,使用 pydub 来完成编码解码。
不希望使用临时文件。
例子1,pydub 字节流在内存的编解码
from pydub import AudioSegment
import io
# 读入声音进入内存,模拟字节流
encode_data = open(r"黒兎ウル - 四季刻歌.mp3", 'rb').read()
# 解码字节流,自动识别和解码mp3格式
seg = AudioSegment.from_file(io.BytesIO(encode_data))
# 打印一些信息
print('样本大小', seg.sample_width)
print('通道数', seg.channels)
print('采样率', seg.frame_rate)
print('PCM数据长度', len(seg.raw_data))
# 网络发送 sample_width channels frame_rate raw_data
# 内存里加载PCM数据流到 AudioSegment
seg2 = AudioSegment.from_raw(io.BytesIO(seg.raw_data),
sample_width=seg.sample_width,
channels=seg.channels,
frame_rate=seg.frame_rate
)
# 编码字节流
## 使用内存文件流来获得编码后字节流
mem_f = io.BytesIO()
seg2.export(mem_f, 'ogg')
encode_data2 = mem_f.getbuffer().tobytes()
# 保存编码后字节流到文件
open('out.ogg', 'wb').write(encode_data2)
例子2,加载 np.ndarray PCM数据 到 AudioSegment
from pydub import AudioSegment
import io
import numpy as np
sample_width = 2
channels = 1
frame_rate = 44100
# AI生成的浮点数音频序列,数值范围为 [-1, 1],使用numpy的随机数来模拟,生成5秒的均匀噪音序列
gen_seg = np.random.uniform(-1, 1, [channels * frame_rate * 5])
# 取范围[-1, 1],然后量化到 int16
gen_seg_int16 = (gen_seg.clip(-1, 1) * (65535 / 2)).round().astype(np.int16)
# 每个样本的 都是一个int16的数值,占位2字节
assert sample_width == gen_seg_int16.itemsize
# 内存里加载PCM数据流到 AudioSegment
seg2 = AudioSegment.from_raw(io.BytesIO(gen_seg_int16.tobytes()),
sample_width=sample_width,
channels=channels,
frame_rate=frame_rate
)
# 编码字节流到文件
seg2.export('out2.ogg', 'ogg')