def decode(self, encoded_frame: JitterFrame) -> List[Frame]: frame = AudioFrame(format="s16", layout="mono", samples=SAMPLES_PER_FRAME) frame.planes[0].update(self._convert(encoded_frame.data, SAMPLE_WIDTH)) frame.pts = encoded_frame.timestamp frame.sample_rate = SAMPLE_RATE frame.time_base = TIME_BASE return [frame]
async def recv(self) -> Frame: """ Receive the next :class:`~av.audio.frame.AudioFrame`. The base implementation just reads silence, subclass :class:`AudioStreamTrack` to provide a useful implementation. """ if self.readyState != "live": raise MediaStreamError sample_rate = 8000 samples = int(AUDIO_PTIME * sample_rate) if hasattr(self, "_timestamp"): self._timestamp += samples wait = self._start + (self._timestamp / sample_rate) - time.time() await asyncio.sleep(wait) else: self._start = time.time() self._timestamp = 0 frame = AudioFrame(format="s16", layout="mono", samples=samples) for p in frame.planes: p.update(bytes(p.buffer_size)) frame.pts = self._timestamp frame.sample_rate = sample_rate frame.time_base = fractions.Fraction(1, sample_rate) return frame
def test_pts_assertion_new_rate(self): resampler = AudioResampler("s16", "mono", 44100) # resample one frame iframe = AudioFrame("s16", "stereo", 1024) iframe.sample_rate = 48000 iframe.time_base = "1/48000" iframe.pts = 0 oframes = resampler.resample(iframe) self.assertEqual(len(oframes), 1) oframe = oframes[0] self.assertEqual(oframe.pts, 0) self.assertEqual(oframe.time_base, Fraction(1, 44100)) self.assertEqual(oframe.sample_rate, 44100) self.assertEqual(oframe.samples, 925) # flush oframes = resampler.resample(None) self.assertEqual(len(oframes), 1) oframe = oframes[0] self.assertEqual(oframe.pts, 925) self.assertEqual(oframe.time_base, Fraction(1, 44100)) self.assertEqual(oframe.sample_rate, 44100) self.assertEqual(oframe.samples, 16)
def create_audio_frame(self, samples, pts, layout="mono", sample_rate=48000): frame = AudioFrame(format="s16", layout=layout, samples=samples) for p in frame.planes: p.update(bytes(p.buffer_size)) frame.pts = pts frame.sample_rate = sample_rate frame.time_base = fractions.Fraction(1, sample_rate) return frame
def generate_audio_frame(): """Generate a blank audio frame.""" from av import AudioFrame audio_frame = AudioFrame(format='dbl', layout='mono', samples=1024) # audio_bytes = b''.join(b'\x00\x00\x00\x00\x00\x00\x00\x00' # for i in range(0, 1024)) audio_bytes = b'\x00\x00\x00\x00\x00\x00\x00\x00' * 1024 audio_frame.planes[0].update(audio_bytes) audio_frame.sample_rate = AUDIO_SAMPLE_RATE audio_frame.time_base = Fraction(1, AUDIO_SAMPLE_RATE) return audio_frame
def create_audio_frame(sample_func, samples, pts, layout="mono", sample_rate=48000): frame = AudioFrame(format="s16", layout=layout, samples=samples) for p in frame.planes: buf = bytearray() for i in range(samples): sample = int(sample_func(i) * 32767) buf.extend(int.to_bytes(sample, 2, sys.byteorder, signed=True)) p.update(buf) frame.pts = pts frame.sample_rate = sample_rate frame.time_base = fractions.Fraction(1, sample_rate) return frame
def test_pts_complex_time_base(self): resampler = AudioResampler('s16', 'mono', 44100) iframe = AudioFrame('s16', 'stereo', 1024) iframe.sample_rate = 48000 iframe.time_base = '1/96000' iframe.pts = 0 oframe = resampler.resample(iframe) self.assertIs(oframe.pts, None) self.assertIs(oframe.time_base, None) self.assertEqual(oframe.sample_rate, 44100)
def create_audio_frames(self, layout, sample_rate, count): frames = [] timestamp = 0 samples_per_frame = int(AUDIO_PTIME * sample_rate) for i in range(count): frame = AudioFrame(format="s16", layout=layout, samples=samples_per_frame) for p in frame.planes: p.update(bytes(p.buffer_size)) frame.pts = timestamp frame.sample_rate = sample_rate frame.time_base = fractions.Fraction(1, sample_rate) frames.append(frame) timestamp += samples_per_frame return frames
def decode(self, encoded_frame): frame = AudioFrame(format='s16', layout='stereo', samples=SAMPLES_PER_FRAME) frame.pts = encoded_frame.timestamp frame.sample_rate = SAMPLE_RATE frame.time_base = TIME_BASE length = lib.opus_decode( self.decoder, encoded_frame.data, len(encoded_frame.data), ffi.cast('int16_t *', frame.planes[0].buffer_ptr), SAMPLES_PER_FRAME, 0) assert length == SAMPLES_PER_FRAME return [frame]
def test_pts_assertion_same_rate(self): resampler = AudioResampler("s16", "mono") # resample one frame iframe = AudioFrame("s16", "stereo", 1024) iframe.sample_rate = 48000 iframe.time_base = "1/48000" iframe.pts = 0 oframes = resampler.resample(iframe) self.assertEqual(len(oframes), 1) oframe = oframes[0] self.assertEqual(oframe.pts, 0) self.assertEqual(oframe.time_base, iframe.time_base) self.assertEqual(oframe.sample_rate, iframe.sample_rate) self.assertEqual(oframe.samples, iframe.samples) # resample another frame iframe.pts = 1024 oframes = resampler.resample(iframe) self.assertEqual(len(oframes), 1) oframe = oframes[0] self.assertEqual(oframe.pts, 1024) self.assertEqual(oframe.time_base, iframe.time_base) self.assertEqual(oframe.sample_rate, iframe.sample_rate) self.assertEqual(oframe.samples, iframe.samples) # resample another frame with a pts gap, do not raise exception iframe.pts = 9999 oframes = resampler.resample(iframe) self.assertEqual(len(oframes), 1) oframe = oframes[0] self.assertEqual(oframe.pts, 9999) self.assertEqual(oframe.time_base, iframe.time_base) self.assertEqual(oframe.sample_rate, iframe.sample_rate) self.assertEqual(oframe.samples, iframe.samples) # flush oframes = resampler.resample(None) self.assertEqual(len(oframes), 0)
def decode(self, encoded_frame: JitterFrame) -> List[Frame]: frame = AudioFrame(format="s16", layout="stereo", samples=SAMPLES_PER_FRAME) frame.pts = encoded_frame.timestamp frame.sample_rate = SAMPLE_RATE frame.time_base = TIME_BASE length = lib.opus_decode( self.decoder, encoded_frame.data, len(encoded_frame.data), ffi.cast("int16_t *", frame.planes[0].buffer_ptr), SAMPLES_PER_FRAME, 0, ) assert length == SAMPLES_PER_FRAME return [frame]
def test_pts_assertion_new_rate(self): resampler = AudioResampler('s16', 'mono', 44100) iframe = AudioFrame('s16', 'stereo', 1024) iframe.sample_rate = 48000 iframe.time_base = '1/48000' iframe.pts = 0 oframe = resampler.resample(iframe) self.assertEqual(oframe.pts, 0) self.assertEqual(str(oframe.time_base), '1/44100') self.assertEqual(oframe.sample_rate, 44100) samples_out = resampler.samples_out self.assertTrue(samples_out > 0) iframe.pts = 1024 oframe = resampler.resample(iframe) self.assertEqual(oframe.pts, samples_out) self.assertEqual(str(oframe.time_base), '1/44100') self.assertEqual(oframe.sample_rate, 44100)
def test_pts_assertion_same_rate(self): resampler = AudioResampler('s16', 'mono') iframe = AudioFrame('s16', 'stereo', 1024) iframe.sample_rate = 48000 iframe.time_base = '1/48000' iframe.pts = 0 oframe = resampler.resample(iframe) self.assertEqual(oframe.pts, 0) self.assertEqual(oframe.time_base, iframe.time_base) self.assertEqual(oframe.sample_rate, iframe.sample_rate) iframe.pts = 1024 oframe = resampler.resample(iframe) self.assertEqual(oframe.pts, 1024) self.assertEqual(oframe.time_base, iframe.time_base) self.assertEqual(oframe.sample_rate, iframe.sample_rate) iframe.pts = 9999 self.assertRaises(ValueError, resampler.resample, iframe)
async def recv(self): """ Receive the next :class:`~av.audio.frame.AudioFrame`. The base implementation just reads silence, subclass :class:`AudioStreamTrack` to provide a useful implementation. """ if self.readyState != 'live': raise MediaStreamError sample_rate = 8000 samples = int(AUDIO_PTIME * sample_rate) timestamp = getattr(self, '_timestamp', 0) self._timestamp = timestamp + samples await asyncio.sleep(AUDIO_PTIME) frame = AudioFrame(format='s16', layout='mono', samples=samples) for p in frame.planes: p.update(bytes(p.buffer_size)) frame.pts = timestamp frame.sample_rate = sample_rate frame.time_base = fractions.Fraction(1, sample_rate) return frame