import av
avin = av.open("test.264", "r", "h264")
avout = av.open("test.mp4", "w", format="mp4")
avout.add_stream(template=avin.streams[0])
time_base = int(1 / avin.streams[0].time_base)
rate = avin.streams[0].base_rate
ts_inc = int(time_base / rate)
ts = 0
for pkt in avin.demux():
pkt.pts = ts
pkt.dts = ts
avout.mux(pkt)
ts += ts_inc
avin.close()
avout.close()
while
loop is also be slowed down. so it can also help solve this issue if it's really because the Python is slow.>>> import av
>>> a = av.open("https://stream.live.vc.bbcmedia.co.uk/bbc_radio_one")
>>> s = a.streams.audio[0]
>>> s
<av.AudioStream #0 mp3float at 48000Hz, stereo, fltp at 0x1c4ce7a9940>
>>> for pkt in a.demux(s):
... print(pkt.pts)
...
0
338688
677376
1016064
1354752
1693440
2032128
2370816
2709504
...
async def _start_av(self):
input_ = await run_in_executor(av.open, self.url, options={"format": "s16le", "acodec": "pcm_s16le", "ac": "2", "ar": "48k"})
for frame in input_.decode():
if frame:
self._fifo.write(frame)
So I've started with something like this:
self._fifo = av.AudioFifo(format="s16le")
def _start_av(self):
input_ = av.open(self.url, options={"format": "s16le", "acodec": "pcm_s16le", "ac": "2", "ar": "48k"})
for frame in input_decode():
if frame:
self._fifo.write(frame)
def read(self, length):
data = self._fifo.read(length)
if data:
data = data.to_ndarray().tobytes()
return data # returns the data to the library
But I have a small problem, the data received from the AudioFifo is bigger than the one requested
AudioFifo.read
method expects number of samples to read. You mentioned that the library supplying length
expects length amount of bytes. With Audio, amount of samples is not equal to amount of bytes. For example, in your case, pcm_s16le
means that each sample is 16 bit little endian and this is 2 bytes per sample. If library is indeed supplying to you number of bytes it expects, you need to read length / 2
number of samples. With that, I hope the library is aligned with audio realities and asks for number of samples.
fifo: av.AudioFifo = av.AudioFifo(format="s16le")
resampler: av.AudioResampler = av.AudioResampler(
format="s16", layout="stereo", rate=48000)
def on_played_data(_, length):
data = fifo.read(length / 4)
if data:
data = data.to_ndarray().tobytes()
return data
group_call_factory = GroupCallFactory(client, CLIENT_TYPE)
group_call = group_call_factory.get_raw_group_call(
on_played_data=on_played_data)
await group_call.start(PEER)
while not group_call.is_connected:
await asyncio.sleep(1)
input_ = av.open(STREAM)
for frame in input_.decode():
if frame:
print(frame)
frame = resampler.resample(frame)
fifo.write(frame)
await client.run_until_disconnected()~~~