1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- # 播放p3格式的音频文件
- import opuslib
- import struct
- import numpy as np
- import sounddevice as sd
- import argparse
- def play_p3_file(input_file):
- """
- 播放p3格式的音频文件
- p3格式: [1字节类型, 1字节保留, 2字节长度, Opus数据]
- """
- # 初始化Opus解码器
- sample_rate = 16000 # 采样率固定为16000Hz
- channels = 1 # 单声道
- decoder = opuslib.Decoder(sample_rate, channels)
-
- # 帧大小 (60ms)
- frame_size = int(sample_rate * 60 / 1000)
-
- # 打开音频流
- stream = sd.OutputStream(
- samplerate=sample_rate,
- channels=channels,
- dtype='int16'
- )
- stream.start()
-
- try:
- with open(input_file, 'rb') as f:
- print(f"正在播放: {input_file}")
-
- while True:
- # 读取头部 (4字节)
- header = f.read(4)
- if not header or len(header) < 4:
- break
-
- # 解析头部
- packet_type, reserved, data_len = struct.unpack('>BBH', header)
-
- # 读取Opus数据
- opus_data = f.read(data_len)
- if not opus_data or len(opus_data) < data_len:
- break
-
- # 解码Opus数据
- pcm_data = decoder.decode(opus_data, frame_size)
-
- # 将字节转换为numpy数组
- audio_array = np.frombuffer(pcm_data, dtype=np.int16)
-
- # 播放音频
- stream.write(audio_array)
-
- except KeyboardInterrupt:
- print("\n播放已停止")
- finally:
- stream.stop()
- stream.close()
- print("播放完成")
- def main():
- parser = argparse.ArgumentParser(description='播放p3格式的音频文件')
- parser.add_argument('input_file', help='输入的p3文件路径')
- args = parser.parse_args()
-
- play_p3_file(args.input_file)
- if __name__ == "__main__":
- main()
|