cutcutcodec.core.io.scheduler

Combine several stream to yield frame in monotonic order.

It is helpfull for writing and muxing.

Functions

audio_frames_async(stream, rate, start_time)

Decode the audio frames in an over thread for performance.

scheduler(streams, rates[, start_time, shapes])

Extract in chronological order the frames of all flows.

video_frames_async(stream, out_fps, ...)

Decode the video frames in an over thread for performance.

Details

cutcutcodec.core.io.scheduler.audio_frames_async(stream: StreamAudio, rate: Fraction | int, start_time: Fraction, samples: int | None = None, **_) Iterable[FrameAudio][source]

Decode the audio frames in an over thread for performance.

Parameters

streamcutcutcodec.core.classes.stream_audio.StreamAudio

The audio stream for extract the frames.

rateint

The time frequency between each samples to catch.

start_timefraction.Fraction

The frame with start time < start_time are ignored.

samplesint, optional

The maximum number of samples in a frame. The last frame can to contains less samples in order to reach the end. The special default value None means to choose automaticaly the optimal number of samples in accordance to the sample rate. By default, the samples are choose for a duration of 100 ms.

Yields

cutcutcodec.core.classes.frame_audio.FrameAudio

The frame audio such as create the complete signal if we concatenate her.

Examples

>>> from fractions import Fraction
>>> from cutcutcodec.core.filter.audio.subclip import FilterAudioSubclip
>>> from cutcutcodec.core.generation.audio.noise import GeneratorAudioNoise
>>> from cutcutcodec.core.io.scheduler import audio_frames_async
>>>
>>> (stream,) = FilterAudioSubclip(GeneratorAudioNoise(0).out_streams, 0, 1).out_streams
>>> for frame in audio_frames_async(stream, 1000, Fraction(10, 1001), samples=200):
...     frame.time, frame.samples
...
(Fraction(1, 100), 200)
(Fraction(21, 100), 200)
(Fraction(41, 100), 200)
(Fraction(61, 100), 200)
(Fraction(81, 100), 190)
>>>
cutcutcodec.core.io.scheduler.scheduler(streams: list[Stream], rates: list[Fraction | int], start_time: Fraction = Fraction(0, 1), shapes: None | tuple[int, int] | list[None | tuple[int, int]] = None, **kwargs) Iterable[tuple[int, Frame]][source]

Extract in chronological order the frames of all flows.

Gives up frames until all streams have raised the OutOfTimeRange exception.

Parameters

streamslist[cutcutcodec.core.classes.stream.Stream]

Audio or video streams to exract the frames.

rateslist[Fraction]

The frame rate for video streams and the sample rate for audio streams.

start_timeFraction, default=0

The position of the first frame yielded. The frame before are ignored.

shapestuple[int, int] or list[tuple[int, int]], optional

For video only, ignore if there is no video stream. Each shape are transmitted to the stream. If the list is not provided, the same shape is transmitted to all video streams.

**kwargsdict

Transmitted to the functions cutcutcodec.core.io.scheduler.audio_frames_async and cutcutcodec.core.io.scheduler.video_frames_async.

Yields

indexint

The index of the concerned stream in the order of the provided list.

framecutcutcodec.core.classes.frame.Frame

The future frame of the stream considered. The time attribute is guaranteed to be monotonic.

Raises

cutcutcodec.core.exceptions.MissingStreamError

If no frame are yielded.

Examples

>>> from fractions import Fraction
>>> from cutcutcodec.core.filter.audio.subclip import FilterAudioSubclip
>>> from cutcutcodec.core.filter.video.subclip import FilterVideoSubclip
>>> from cutcutcodec.core.generation.audio.noise import GeneratorAudioNoise
>>> from cutcutcodec.core.generation.video.noise import GeneratorVideoNoise
>>> from cutcutcodec.core.io.scheduler import scheduler
>>>
>>> s_1 = (
...     FilterVideoSubclip(GeneratorVideoNoise(0).out_streams, 0, Fraction(1, 10)).out_streams
... )
>>> s_2 = (
...     FilterVideoSubclip(GeneratorVideoNoise(0).out_streams, 0, Fraction(1, 4)).out_streams
... )
>>> streams_video = [s_1[0], s_2[0]]
>>> rates_video = [Fraction(30), Fraction(24)]
>>> s_3 = (
...     FilterAudioSubclip(GeneratorAudioNoise(0).out_streams, 0, Fraction(1, 10)).out_streams
... )
>>> s_4 = (
...     FilterAudioSubclip(GeneratorAudioNoise(0).out_streams, 0, Fraction(1, 4)).out_streams
... )
>>> streams_audio = [s_3[0], s_4[0]]
>>> rates_audio = [96000, 48000]
>>>
>>> # test audio only
>>> for index, frame in scheduler(streams_audio, rates_audio):
...     index, frame.time
...
(0, Fraction(0, 1))
(1, Fraction(0, 1))
(0, Fraction(32, 375))
(1, Fraction(32, 375))
(1, Fraction(64, 375))
>>> for index, frame in scheduler(streams_audio, rates_audio, start_time=Fraction(1, 10)):
...     index, frame.time
...
(1, Fraction(1, 10))
(1, Fraction(139, 750))
>>>
>>> # test video only
>>> for index, frame in scheduler(streams_video, rates_video, shape=(1, 1)):
...     index, frame.time
...
(0, Fraction(0, 1))
(1, Fraction(0, 1))
(0, Fraction(1, 30))
(1, Fraction(1, 24))
(0, Fraction(1, 15))
(1, Fraction(1, 12))
(1, Fraction(1, 8))
(1, Fraction(1, 6))
(1, Fraction(5, 24))
>>> for index, frame in scheduler(streams_video, rates_video, Fraction(1, 10), shape=(1, 1)):
...     index, frame.time
...
(1, Fraction(1, 8))
(1, Fraction(1, 6))
(1, Fraction(5, 24))
>>>
>>> # test audio and video
>>> for index, frame in scheduler(
...     streams_audio+streams_video, rates_audio+rates_video, shape=(1, 1), samples=4096
... ):
...     index, frame.time
...
(0, Fraction(0, 1))
(1, Fraction(0, 1))
(2, Fraction(0, 1))
(3, Fraction(0, 1))
(2, Fraction(1, 30))
(3, Fraction(1, 24))
(0, Fraction(16, 375))
(2, Fraction(1, 15))
(3, Fraction(1, 12))
(0, Fraction(32, 375))
(1, Fraction(32, 375))
(3, Fraction(1, 8))
(3, Fraction(1, 6))
(1, Fraction(64, 375))
(3, Fraction(5, 24))
>>>
cutcutcodec.core.io.scheduler.video_frames_async(stream: StreamVideo, out_fps: Fraction, start_time: Fraction, shape: tuple[int, int], **_) Iterable[FrameVideo][source]

Decode the video frames in an over thread for performance.

Parameters

streamcutcutcodec.core.classes.stream_video.StreamVideo

The video stream for extract the frames.

out_fpsFraction

The 1/step interval for each frame timestamp request.

start_timeFraction

The frame with timestamp < start_time are ignored.

shapetuple[int, int]

Transmitted to mocia.core.classes.stream_video.snapshot.

Yields

cutcutcodec.core.classes.frame_video.FrameVideo

The frame videos in monotonic (non strict) order.

Examples

>>> from fractions import Fraction
>>> from cutcutcodec.core.filter.video.subclip import FilterVideoSubclip
>>> from cutcutcodec.core.generation.video.noise import GeneratorVideoNoise
>>> from cutcutcodec.core.io.scheduler import video_frames_async
>>>
>>> (stream,) = FilterVideoSubclip(GeneratorVideoNoise(0).out_streams, 0, 1).out_streams
>>> for frame in video_frames_async(stream, Fraction(10, 1), Fraction(99, 200), shape=(1, 1)):
...     frame.time
...
Fraction(1, 2)
Fraction(3, 5)
Fraction(7, 10)
Fraction(4, 5)
Fraction(9, 10)
>>>