convert_p3_to_audio.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import struct
  2. import sys
  3. import opuslib
  4. import numpy as np
  5. from tqdm import tqdm
  6. import soundfile as sf
  7. def decode_p3_to_audio(input_file, output_file):
  8. sample_rate = 16000
  9. channels = 1
  10. decoder = opuslib.Decoder(sample_rate, channels)
  11. pcm_frames = []
  12. frame_size = int(sample_rate * 60 / 1000)
  13. with open(input_file, "rb") as f:
  14. f.seek(0, 2)
  15. total_size = f.tell()
  16. f.seek(0)
  17. with tqdm(total=total_size, unit="B", unit_scale=True) as pbar:
  18. while True:
  19. header = f.read(4)
  20. if not header or len(header) < 4:
  21. break
  22. pkt_type, reserved, opus_len = struct.unpack(">BBH", header)
  23. opus_data = f.read(opus_len)
  24. if len(opus_data) != opus_len:
  25. break
  26. pcm = decoder.decode(opus_data, frame_size)
  27. pcm_frames.append(np.frombuffer(pcm, dtype=np.int16))
  28. pbar.update(4 + opus_len)
  29. if not pcm_frames:
  30. raise ValueError("No valid audio data found")
  31. pcm_data = np.concatenate(pcm_frames)
  32. sf.write(output_file, pcm_data, sample_rate, subtype="PCM_16")
  33. if __name__ == "__main__":
  34. if len(sys.argv) != 3:
  35. print("Usage: python convert_p3_to_audio.py <input.p3> <output.wav>")
  36. sys.exit(1)
  37. decode_p3_to_audio(sys.argv[1], sys.argv[2])