Exemplo n.º 1
0
    def test_pts_simple(self):

        fifo = av.AudioFifo()

        iframe = av.AudioFrame(samples=1024)
        iframe.pts = 0
        iframe.sample_rate = 48000
        iframe.time_base = "1/48000"

        fifo.write(iframe)

        oframe = fifo.read(512)
        self.assertTrue(oframe is not None)
        self.assertEqual(oframe.pts, 0)
        self.assertEqual(oframe.time_base, iframe.time_base)

        self.assertEqual(fifo.samples_written, 1024)
        self.assertEqual(fifo.samples_read, 512)
        self.assertEqual(fifo.pts_per_sample, 1.0)

        iframe.pts = 1024
        fifo.write(iframe)
        oframe = fifo.read(512)
        self.assertTrue(oframe is not None)
        self.assertEqual(oframe.pts, 512)
        self.assertEqual(oframe.time_base, iframe.time_base)

        iframe.pts = 9999  # Wrong!
        self.assertRaises(ValueError, fifo.write, iframe)
Exemplo n.º 2
0
    def test_data(self):

        container = av.open(
            fate_suite("audio-reference/chorusnoise_2ch_44kHz_s16.wav"))
        stream = container.streams.audio[0]

        fifo = av.AudioFifo()

        input_ = []
        output = []

        for i, packet in enumerate(container.demux(stream)):
            for frame in packet.decode():
                input_.append(bytes(frame.planes[0]))
                fifo.write(frame)
                for frame in fifo.read_many(512, partial=i == 10):
                    output.append(bytes(frame.planes[0]))
            if i == 10:
                break

        input_ = b"".join(input_)
        output = b"".join(output)
        min_len = min(len(input_), len(output))

        self.assertTrue(min_len > 10 * 512 * 2 * 2)
        self.assertTrue(input_[:min_len] == output[:min_len])
Exemplo n.º 3
0
def player_worker(loop, container, audio_track, video_track, quit_event, throttle_playback):
    audio_fifo = av.AudioFifo()
    audio_format = av.AudioFormat('s16')
    audio_sample_rate = 48000
    audio_samples = 0
    audio_samples_per_frame = int(audio_sample_rate * AUDIO_PTIME)
    audio_resampler = av.AudioResampler(
        format=audio_format,
        rate=audio_sample_rate)

    video_first_pts = None

    frame_time = None
    start_time = time.time()

    while not quit_event.is_set():
        try:
            frame = next(container.decode())
        except (av.AVError, StopIteration):
            if audio_track:
                asyncio.run_coroutine_threadsafe(audio_track._queue.put(None), loop)
            if video_track:
                asyncio.run_coroutine_threadsafe(video_track._queue.put(None), loop)
            break

        # read up to 1 second ahead
        if throttle_playback:
            elapsed_time = (time.time() - start_time)
            if frame_time and frame_time > elapsed_time + 1:
                time.sleep(0.1)

        if isinstance(frame, AudioFrame) and audio_track:
            if frame.format != audio_format or frame.sample_rate != audio_sample_rate:
                frame.pts = None
                frame = audio_resampler.resample(frame)

            # fix timestamps
            frame.pts = audio_samples
            frame.time_base = fractions.Fraction(1, audio_sample_rate)
            audio_samples += frame.samples

            audio_fifo.write(frame)
            while True:
                frame = audio_fifo.read(audio_samples_per_frame)
                if frame:
                    frame_time = frame.time
                    asyncio.run_coroutine_threadsafe(audio_track._queue.put(frame), loop)
                else:
                    break
        elif isinstance(frame, VideoFrame) and video_track:
            # video from a webcam doesn't start at pts 0, cancel out offset
            if frame.pts is not None:
                if video_first_pts is None:
                    video_first_pts = frame.pts
                frame.pts -= video_first_pts

            frame_time = frame.time
            asyncio.run_coroutine_threadsafe(video_track._queue.put(frame), loop)
Exemplo n.º 4
0
    def test_missing_time_base(self):

        fifo = av.AudioFifo()

        iframe = av.AudioFrame(samples=1024)
        iframe.pts = 0
        iframe.sample_rate = 48000

        fifo.write(iframe)

        oframe = fifo.read(512)

        self.assertTrue(oframe is not None)
        self.assertIsNone(oframe.pts)
        self.assertIsNone(oframe.time_base)
        self.assertEqual(oframe.sample_rate, iframe.sample_rate)
Exemplo n.º 5
0
    def test_pts_complex(self):

        fifo = av.AudioFifo()

        iframe = av.AudioFrame(samples=1024)
        iframe.pts = 0
        iframe.sample_rate = 48000
        iframe.time_base = "1/96000"

        fifo.write(iframe)
        iframe.pts = 2048
        fifo.write(iframe)

        oframe = fifo.read_many(1024)[-1]

        self.assertEqual(oframe.pts, 2048)
        self.assertEqual(fifo.pts_per_sample, 2.0)
Exemplo n.º 6
0
def player_worker(loop, container, streams, audio_track, video_track,
                  quit_event, throttle_playback):
    audio_fifo = av.AudioFifo()
    audio_format_name = "s16"
    audio_layout_name = "stereo"
    audio_sample_rate = 48000
    audio_samples = 0
    audio_samples_per_frame = int(audio_sample_rate * AUDIO_PTIME)
    audio_resampler = av.AudioResampler(format=audio_format_name,
                                        layout=audio_layout_name,
                                        rate=audio_sample_rate)

    video_first_pts = None

    frame_time = None
    start_time = time.time()

    while not quit_event.is_set():
        try:
            frame = next(container.decode(*streams))
        except (av.AVError, StopIteration) as exc:
            if isinstance(exc, av.FFmpegError) and exc.errno == errno.EAGAIN:
                time.sleep(0.01)
                continue
            if audio_track:
                asyncio.run_coroutine_threadsafe(audio_track._queue.put(None),
                                                 loop)
            if video_track:
                asyncio.run_coroutine_threadsafe(video_track._queue.put(None),
                                                 loop)
            break

        # read up to 1 second ahead
        if throttle_playback:
            elapsed_time = time.time() - start_time
            if frame_time and frame_time > elapsed_time + 1:
                time.sleep(0.1)

        if isinstance(frame, AudioFrame) and audio_track:
            if (frame.format.name != audio_format_name
                    or frame.layout.name != audio_layout_name
                    or frame.sample_rate != audio_sample_rate):
                frame.pts = None
                frame = audio_resampler.resample(frame)

            # fix timestamps
            frame.pts = audio_samples
            frame.time_base = fractions.Fraction(1, audio_sample_rate)
            audio_samples += frame.samples

            audio_fifo.write(frame)
            while True:
                frame = audio_fifo.read(audio_samples_per_frame)
                if frame:
                    frame_time = frame.time
                    asyncio.run_coroutine_threadsafe(
                        audio_track._queue.put(frame), loop)
                else:
                    break
        elif isinstance(frame, VideoFrame) and video_track:
            if frame.pts is None:  # pragma: no cover
                logger.warning(
                    "MediaPlayer(%s) Skipping video frame with no pts",
                    container.name)
                continue

            # video from a webcam doesn't start at pts 0, cancel out offset
            if video_first_pts is None:
                video_first_pts = frame.pts
            frame.pts -= video_first_pts

            frame_time = frame.time
            asyncio.run_coroutine_threadsafe(video_track._queue.put(frame),
                                             loop)
Exemplo n.º 7
0
def worker(player, loop, container, streams, tracks, lock_tracks, quit_event,
           throttle_playback, audio_effect, video_effect):

    import fractions
    import time

    audio_fifo = av.AudioFifo()
    audio_format_name = "s16"
    audio_layout_name = "stereo"
    audio_sample_rate = 48000
    audio_samples = 0
    audio_samples_per_frame = int(audio_sample_rate * AUDIO_PTIME)
    audio_resampler = av.AudioResampler(format=audio_format_name,
                                        layout=audio_layout_name,
                                        rate=audio_sample_rate)

    video_first_pts = None
    audio_frame_time = None
    start_time = time.time()

    audio_print_warning = True
    video_print_warning = True

    def iter_tracks(kind=None):
        with lock_tracks:
            for track in tracks:
                track = track()
                if track is not None:
                    if kind is None or kind == track.kind:
                        yield track

    def cleanup_tracks():

        with lock_tracks:
            to_remove = {track for track in tracks if track() is None}
            for track in to_remove:
                tracks.discard(track)

    def run_threadsafe(coro):
        asyncio.run_coroutine_threadsafe(coro, loop)

    def append_frame(frame, kind=None, force=True):

        for track in iter_tracks(kind=kind):
            if track._queue.full():

                # remove one frame and append the new frame
                if force:
                    run_threadsafe(track._queue.get())
                    run_threadsafe(track._queue.put(frame))

            else:
                run_threadsafe(track._queue.put(frame))

    while not quit_event.is_set():

        # clean invalid ref
        cleanup_tracks()

        # decode frame
        try:
            frame = next(container.decode(*streams))
        except (av.AVError, StopIteration):
            for track in iter_tracks():
                append_frame(None, force=True)
            break

        # read up to 1 second ahead
        if throttle_playback:
            elapsed_time = time.time() - start_time
            if audio_frame_time and audio_frame_time > elapsed_time + 1:
                time.sleep(0.1)

        # audio
        if isinstance(frame, av.AudioFrame) and (set(iter_tracks('audio'))
                                                 or player.always_running):

            if (frame.format.name != audio_format_name
                    or frame.layout.name != audio_layout_name
                    or frame.sample_rate != audio_sample_rate):
                frame.pts = None
                frame = audio_resampler.resample(frame)

            # fix timestamps
            frame.pts = audio_samples
            frame.time_base = fractions.Fraction(1, audio_sample_rate)
            audio_samples += frame.samples

            # apply audio effect
            if audio_effect is not None:

                try:
                    frame = audio_effect(loop, frame)
                    audio_print_warning = True
                except BaseException:
                    if audio_print_warning:
                        logger.exception('Failed to apply audio effect')
                        audio_print_warning = False

            audio_fifo.write(frame)
            while True:
                frame = audio_fifo.read(audio_samples_per_frame)
                if frame:
                    audio_frame_time = frame.time
                    append_frame(frame, 'audio')
                else:
                    break

        # video
        if isinstance(frame, av.VideoFrame) and (set(iter_tracks('video'))
                                                 or player.always_running):

            if frame.pts is None:  # pragma: no cover
                logger.warning("Skipping video frame with no pts")
                continue

            # video from a webcam doesn't start at pts 0, cancel out offset
            if video_first_pts is None:
                video_first_pts = frame.pts
            frame.pts -= video_first_pts

            # drop frame if too late
            if throttle_playback:
                elapsed_time = time.time() - start_time
                if elapsed_time - frame.time > 0.1:
                    continue

            # apply video effect
            if video_effect is not None:

                try:
                    frame = video_effect(loop, frame)
                    video_print_warning = True
                except BaseException:
                    if video_print_warning:
                        logger.exception('Failed to apply video effect')
                        video_print_warning = False

            append_frame(frame, 'video')
Exemplo n.º 8
0
import subprocess
import time

from qtproxy import Q

import av


parser = argparse.ArgumentParser()
parser.add_argument('path')
args = parser.parse_args()

container = av.open(args.path)
stream = next(s for s in container.streams if s.type == 'audio')

fifo = av.AudioFifo()
resampler = av.AudioResampler(
    format=av.AudioFormat('s16').packed,
    layout='stereo',
    rate=48000,
)



qformat = Q.AudioFormat()
qformat.setByteOrder(Q.AudioFormat.LittleEndian)
qformat.setChannelCount(2)
qformat.setCodec('audio/pcm')
qformat.setSampleRate(48000)
qformat.setSampleSize(16)
qformat.setSampleType(Q.AudioFormat.SignedInt)
Exemplo n.º 9
0
arg_parser.add_argument('path')
arg_parser.add_argument('-p', '--play', action='store_true')
arg_parser.add_argument('-d', '--data', action='store_true')
arg_parser.add_argument('-f', '--format')
arg_parser.add_argument('-l', '--layout')
arg_parser.add_argument('-r', '--rate', type=int)
arg_parser.add_argument('-s', '--size', type=int, default=1024)
arg_parser.add_argument('-c', '--count', type=int, default=5)
args = arg_parser.parse_args()

ffplay = None

container = av.open(args.path)
stream = next(s for s in container.streams if s.type == 'audio')

fifo = av.AudioFifo() if args.size else None
resampler = av.AudioResampler(
    format=av.AudioFormat(args.format or stream.format.name).packed
    if args.format else None,
    layout=int(args.layout)
    if args.layout and args.layout.isdigit() else args.layout,
    rate=args.rate,
) if (args.format or args.layout or args.rate) else None

read_count = 0
fifo_count = 0
sample_count = 0

for i, packet in enumerate(container.demux(stream)):

    for frame in packet.decode():
Exemplo n.º 10
0
import os
from pytgcalls import GroupCallFactory
import pyrogram
import telethon
import av

API_HASH = None
API_ID = None

CHAT_PEER = '@tgcallschat'  # chat or channel where you want to play audio
SOURCE = 'input.mp3' # Audio file path or stream url: eg. https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3
CLIENT_TYPE = GroupCallFactory.MTPROTO_CLIENT_TYPE.PYROGRAM
# for Telethon uncomment line below
#CLIENT_TYPE = GroupCallFactory.MTPROTO_CLIENT_TYPE.TELETHON

fifo = av.AudioFifo(format='s16le')
resampler = av.AudioResampler(format='s16', layout='stereo', rate=48000)


def on_played_data(gc, length):
    data = fifo.read(length / 4)
    if data:
        data = data.to_ndarray().tobytes()
    return data


async def main(client):
    await client.start()
    while not client.is_connected:
        await asyncio.sleep(1)