def init_encoder( samples_per_second=48000, application="audio", channels=1, frame_size=20, #ms duration_ms=60, #ms set_sampling_frequency=True, set_application=True, set_channels=True, set_frame_size=True, callback=None): encoder = pyogg.OpusBufferedEncoder() if set_application: encoder.set_application(application) if set_sampling_frequency: encoder.set_sampling_frequency(samples_per_second) if set_channels: encoder.set_channels(channels) if set_frame_size: encoder.set_frame_size(frame_size) # Create a sample of silence bytes_per_sample = 2 buf = (b"\x00" * bytes_per_sample * channels * (samples_per_second // 1000) * duration_ms) if callback is None: # Encode the sample _ = encoder.encode(buf) else: # Encode with callback encoder.encode_with_samples(buf, callback=callback) return encoder
def init_encoder( samples_per_second: int = 48000, application: str = "audio", channels: int = 1, frame_size: int = 20, #ms duration_ms: int = 60, #ms set_sampling_frequency: bool = True, set_application: bool = True, set_channels: bool = True, set_frame_size: bool = True, callback: Callable[[memoryview, int, bool], None] = None, flush: bool = False) -> pyogg.OpusBufferedEncoder: encoder = pyogg.OpusBufferedEncoder() if set_application: encoder.set_application(application) if set_sampling_frequency: encoder.set_sampling_frequency(samples_per_second) if set_channels: encoder.set_channels(channels) if set_frame_size: encoder.set_frame_size(frame_size) # Create a sample of silence bytes_per_sample = 2 buf = bytearray(b"\x00" * bytes_per_sample * channels * (samples_per_second // 1000) * duration_ms) encoder.buffered_encode(memoryview(buf), flush=flush, callback=callback) return encoder
def test_n_frames_audio() -> None: # Number of frames to write n = 2 # Save the audio using OggOpusWriter filename = f"test_ogg_opus_writer__test_{n}_frames_audio.opus" encoder = pyogg.OpusBufferedEncoder() encoder.set_application("audio") samples_per_second = 48000 encoder.set_sampling_frequency(samples_per_second) channels = 1 encoder.set_channels(channels) frame_size_ms = 20 encoder.set_frame_size(frame_size_ms) # milliseconds frame_size_samples = frame_size_ms * samples_per_second // 1000 writer = pyogg.OggOpusWriter(filename, encoder) # Two bytes per sample, two frames bytes_per_sample = 2 buf = bytearray(b"\x00" * (bytes_per_sample * frame_size_samples * n)) writer.write(memoryview(buf)) # Close the file writer.close() # Test the length of the output opus_file = pyogg.OpusFile(filename) assert len(opus_file.buffer) == bytes_per_sample * frame_size_samples * n
def test_custom_pre_skip() -> None: # Save the audio using OggOpusWriter filename = "test_ogg_opus_writer__test_zero_length_audio.opus" samples_of_pre_skip = 500 encoder = pyogg.OpusBufferedEncoder() encoder.set_application("audio") encoder.set_sampling_frequency(48000) channels = 1 encoder.set_channels(channels) encoder.set_frame_size(20) # milliseconds writer = pyogg.OggOpusWriter(filename, encoder, custom_pre_skip=samples_of_pre_skip) # Create a buffer of silence bytes_per_sample = 2 buf = bytearray(b"\x00" * bytes_per_sample * channels * samples_of_pre_skip) writer.write(memoryview(buf)) # Close the file writer.close() # Test the length of the output is 0 opus_file = pyogg.OpusFile(filename) assert len(opus_file.buffer) == 0
def test_close_twice() -> None: mock_file = MockFile() encoder = pyogg.OpusBufferedEncoder() encoder.set_application("audio") encoder.set_sampling_frequency(48000) encoder.set_channels(2) encoder.set_frame_size(20) # milliseconds # MyPy complains at the MockFile class, but we can ignore the # error. writer = pyogg.OggOpusWriter(mock_file, encoder) # type: ignore writer.close() writer.close()
def test_duplicate_audio() -> None: # Load the demonstration file that is exactly 5 seconds long filename = "../examples/left-right-demo-5s.opus" opus_file = pyogg.OpusFile(filename) # Save the audio using OggOpusWriter out_filename = "test_ogg_opus_writer__test_duplicate_audio.opus" encoder = pyogg.OpusBufferedEncoder() encoder.set_application("audio") encoder.set_sampling_frequency(48000) encoder.set_channels(2) encoder.set_frame_size(20) # milliseconds writer = pyogg.OggOpusWriter(out_filename, encoder) writer.write(opus_file.buffer)
def test_error_after_close() -> None: mock_file = MockFile() encoder = pyogg.OpusBufferedEncoder() encoder.set_application("audio") encoder.set_sampling_frequency(48000) encoder.set_channels(2) encoder.set_frame_size(20) # milliseconds # MyPy complains at the MockFile class, but we can ignore the # error. writer = pyogg.OggOpusWriter(mock_file, encoder) # type: ignore writer.close() with pytest.raises(pyogg.PyOggError): writer.write(memoryview(bytearray(b"")))
def send_sample_opus(self): now = time.perf_counter_ns() encoder = pyogg.OpusBufferedEncoder() encoder.set_application(self.opus_application) encoder.set_sampling_frequency(self.sampling_rate) encoder.set_channels(1) encoder.set_frame_size(20) # 20ms is the opus default with io.BytesIO() as f: ogg = pyogg.OggOpusWriter(f, encoder) ogg.write(self.recording_buffer) ogg.close() dur = (time.perf_counter_ns() - now) / (1000 * 1000 * 1000) print("Encoding time: %.1f s" % dur) self.send_sample_payload(f.getvalue(), "audio/ogg;codecs=opus")
def test_zero_length_audio() -> None: # Save the audio using OggOpusWriter filename = "test_ogg_opus_writer__test_zero_length_audio.opus" encoder = pyogg.OpusBufferedEncoder() encoder.set_application("audio") encoder.set_sampling_frequency(48000) channels = 1 encoder.set_channels(channels) encoder.set_frame_size(20) # milliseconds writer = pyogg.OggOpusWriter(filename, encoder) buf = memoryview(bytearray(b"")) writer.write(buf) # Close the file writer.close() # Test the length of the output is 0 opus_file = pyogg.OpusFile(filename) assert len(opus_file.buffer) == 0
# Read a wav file to obtain PCM data filename = "left-right-demo-5s.wav" wave_read = wave.open(filename, "rb") print("Reading wav from file '{:s}'".format(filename)) # Extract the wav's specification channels = wave_read.getnchannels() print("Number of channels:", channels) samples_per_second = wave_read.getframerate() print("Sampling frequency:", samples_per_second) bytes_per_sample = wave_read.getsampwidth() original_length = wave_read.getnframes() print("Length:", original_length) # Create a OpusBufferedEncoder opus_buffered_encoder = pyogg.OpusBufferedEncoder() opus_buffered_encoder.set_application("audio") opus_buffered_encoder.set_sampling_frequency(samples_per_second) opus_buffered_encoder.set_channels(channels) opus_buffered_encoder.set_frame_size(20) # milliseconds # Create an OggOpusWriter output_filename = filename+".opus" print("Writing OggOpus file to '{:s}'".format(output_filename)) ogg_opus_writer = pyogg.OggOpusWriter( output_filename, opus_buffered_encoder ) # Calculate the desired frame size (in samples per channel) desired_frame_duration = 20/1000 # milliseconds
#!/usr/bin/env python3 import time import pyogg import io now = time.perf_counter_ns() encoder = pyogg.OpusBufferedEncoder() encoder.set_application("voip") encoder.set_sampling_frequency(16000) encoder.set_channels(1) encoder.set_frame_size(20) # ms with io.BytesIO() as f: ogg = pyogg.OggOpusWriter(f, encoder) ogg.write(bytearray(100)) ogg.close() dur = (time.perf_counter_ns() - now) / 1000 print(f"Encoding time: {dur} ms")