typed-ffmpeg-compatible 2.6.3__py3-none-any.whl → 2.6.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- typed_ffmpeg/__init__.py +24 -0
- typed_ffmpeg/base.py +87 -29
- typed_ffmpeg/common/schema.py +281 -3
- typed_ffmpeg/common/serialize.py +118 -21
- typed_ffmpeg/dag/__init__.py +13 -0
- typed_ffmpeg/dag/compile.py +39 -4
- typed_ffmpeg/dag/context.py +137 -29
- typed_ffmpeg/dag/factory.py +27 -0
- typed_ffmpeg/dag/global_runnable/global_args.py +11 -0
- typed_ffmpeg/dag/global_runnable/runnable.py +143 -34
- typed_ffmpeg/dag/io/_input.py +2 -1
- typed_ffmpeg/dag/io/_output.py +2 -1
- typed_ffmpeg/dag/nodes.py +402 -67
- typed_ffmpeg/dag/schema.py +3 -1
- typed_ffmpeg/dag/utils.py +29 -8
- typed_ffmpeg/dag/validate.py +83 -20
- typed_ffmpeg/exceptions.py +42 -9
- typed_ffmpeg/info.py +137 -16
- typed_ffmpeg/probe.py +31 -6
- typed_ffmpeg/schema.py +32 -5
- typed_ffmpeg/streams/channel_layout.py +13 -0
- typed_ffmpeg/utils/escaping.py +47 -7
- typed_ffmpeg/utils/forzendict.py +108 -0
- typed_ffmpeg/utils/lazy_eval/operator.py +43 -1
- typed_ffmpeg/utils/lazy_eval/schema.py +122 -6
- typed_ffmpeg/utils/run.py +44 -7
- typed_ffmpeg/utils/snapshot.py +36 -1
- typed_ffmpeg/utils/typing.py +29 -4
- typed_ffmpeg/utils/view.py +46 -4
- {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.6.4.dist-info}/METADATA +1 -1
- typed_ffmpeg_compatible-2.6.4.dist-info/RECORD +48 -0
- typed_ffmpeg_compatible-2.6.3.dist-info/RECORD +0 -47
- {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.6.4.dist-info}/LICENSE +0 -0
- {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.6.4.dist-info}/WHEEL +0 -0
- {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.6.4.dist-info}/entry_points.txt +0 -0
typed_ffmpeg/__init__.py
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
"""
|
2
|
+
typed-ffmpeg: A strongly-typed FFmpeg binding for Python.
|
3
|
+
|
4
|
+
This module provides a high-level, type-safe interface to FFmpeg, enabling
|
5
|
+
Python developers to process audio and video with compile-time validation.
|
6
|
+
The library uses Python's type annotations to ensure correct filter graphs
|
7
|
+
and parameter usage.
|
8
|
+
|
9
|
+
Key components:
|
10
|
+
- Input/output handling via `input` and `output` functions
|
11
|
+
- Stream manipulation with `VideoStream`, `AudioStream`, and `AVStream` classes
|
12
|
+
- Filter application through the `filters` module
|
13
|
+
- Media information analysis using `probe` function
|
14
|
+
- Codec and encoder detection with `get_codecs`, `get_decoders`, and `get_encoders`
|
15
|
+
|
16
|
+
Example:
|
17
|
+
```python
|
18
|
+
import ffmpeg
|
19
|
+
|
20
|
+
# Simple video transcoding
|
21
|
+
(ffmpeg.input("input.mp4").output("output.mp4").run())
|
22
|
+
```
|
23
|
+
"""
|
24
|
+
|
1
25
|
from . import dag, filters, sources
|
2
26
|
from .base import afilter, filter_multi_output, input, merge_outputs, output, vfilter
|
3
27
|
from .dag import Stream
|
typed_ffmpeg/base.py
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
Core functions for creating and manipulating FFmpeg filter graphs.
|
3
|
+
|
4
|
+
This module defines the fundamental functions for building FFmpeg filter graphs
|
5
|
+
in typed-ffmpeg. It provides functions to create custom filters, handle
|
6
|
+
multi-output filters, and merge output streams. These functions serve as the
|
7
|
+
foundation for the more specialized filters defined in the filters module.
|
3
8
|
"""
|
4
9
|
|
5
10
|
from typing import Any
|
@@ -16,17 +21,32 @@ from .dag.nodes import (
|
|
16
21
|
from .schema import StreamType
|
17
22
|
from .streams.audio import AudioStream
|
18
23
|
from .streams.video import VideoStream
|
24
|
+
from .utils.forzendict import FrozenDict
|
19
25
|
|
20
26
|
|
21
27
|
def merge_outputs(*streams: OutputStream) -> GlobalStream:
|
22
28
|
"""
|
23
|
-
Merge multiple output streams into
|
29
|
+
Merge multiple output streams into a single command execution.
|
30
|
+
|
31
|
+
This function combines multiple output streams that need to be executed together
|
32
|
+
in a single FFmpeg command. This is useful when you need to generate multiple
|
33
|
+
outputs from the same input(s) in a single pass, which is more efficient than
|
34
|
+
running separate commands.
|
24
35
|
|
25
36
|
Args:
|
26
|
-
*streams:
|
37
|
+
*streams: Two or more output streams to be merged together
|
27
38
|
|
28
39
|
Returns:
|
29
|
-
|
40
|
+
A global stream representing all merged outputs
|
41
|
+
|
42
|
+
Example:
|
43
|
+
```python
|
44
|
+
input_video = ffmpeg.input("input.mp4")
|
45
|
+
output1 = input_video.output("output1.mp4", vcodec="libx264")
|
46
|
+
output2 = input_video.output("output2.mp4", vcodec="libx265")
|
47
|
+
merged = ffmpeg.merge_outputs(output1, output2)
|
48
|
+
merged.run() # Executes both outputs in a single FFmpeg command
|
49
|
+
```
|
30
50
|
"""
|
31
51
|
return GlobalNode(inputs=streams).stream()
|
32
52
|
|
@@ -38,26 +58,37 @@ def vfilter(
|
|
38
58
|
**kwargs: Any,
|
39
59
|
) -> VideoStream:
|
40
60
|
"""
|
41
|
-
Apply a custom video filter
|
61
|
+
Apply a custom video filter that has a single video output.
|
62
|
+
|
63
|
+
This function allows you to use any FFmpeg video filter that isn't explicitly
|
64
|
+
implemented in typed-ffmpeg. It creates a FilterNode with a video output type
|
65
|
+
and returns the resulting video stream.
|
42
66
|
|
43
67
|
Args:
|
44
|
-
*streams:
|
45
|
-
name:
|
46
|
-
input_typings:
|
47
|
-
**kwargs:
|
68
|
+
*streams: One or more input streams to apply the filter to
|
69
|
+
name: The FFmpeg filter name (e.g., 'hflip', 'scale', etc.)
|
70
|
+
input_typings: The expected types of the input streams (defaults to video)
|
71
|
+
**kwargs: Filter-specific parameters as keyword arguments
|
48
72
|
|
49
73
|
Returns:
|
50
|
-
the output
|
74
|
+
A VideoStream representing the filtered output
|
75
|
+
|
76
|
+
Example:
|
77
|
+
```python
|
78
|
+
# Apply a custom deflicker filter (if not directly implemented)
|
79
|
+
filtered = ffmpeg.vfilter(stream, name="deflicker", mode="pm", size=10)
|
80
|
+
```
|
51
81
|
|
52
82
|
Note:
|
53
|
-
This function is for custom
|
83
|
+
This function is for custom filters not implemented in typed-ffmpeg.
|
84
|
+
Use the built-in filters from the filters module when available.
|
54
85
|
"""
|
55
86
|
return FilterNode(
|
56
87
|
name=name,
|
57
88
|
inputs=streams,
|
58
89
|
output_typings=(StreamType.video,),
|
59
90
|
input_typings=input_typings,
|
60
|
-
kwargs=
|
91
|
+
kwargs=FrozenDict(kwargs),
|
61
92
|
).video(0)
|
62
93
|
|
63
94
|
|
@@ -68,26 +99,37 @@ def afilter(
|
|
68
99
|
**kwargs: Any,
|
69
100
|
) -> AudioStream:
|
70
101
|
"""
|
71
|
-
Apply a custom audio filter
|
102
|
+
Apply a custom audio filter that has a single audio output.
|
103
|
+
|
104
|
+
This function allows you to use any FFmpeg audio filter that isn't explicitly
|
105
|
+
implemented in typed-ffmpeg. It creates a FilterNode with an audio output type
|
106
|
+
and returns the resulting audio stream.
|
72
107
|
|
73
108
|
Args:
|
74
|
-
*streams:
|
75
|
-
name:
|
76
|
-
input_typings:
|
77
|
-
**kwargs:
|
109
|
+
*streams: One or more input streams to apply the filter to
|
110
|
+
name: The FFmpeg filter name (e.g., 'equalizer', 'dynaudnorm', etc.)
|
111
|
+
input_typings: The expected types of the input streams (defaults to audio)
|
112
|
+
**kwargs: Filter-specific parameters as keyword arguments
|
78
113
|
|
79
114
|
Returns:
|
80
|
-
the output
|
115
|
+
An AudioStream representing the filtered output
|
116
|
+
|
117
|
+
Example:
|
118
|
+
```python
|
119
|
+
# Apply a custom audio compressor filter (if not directly implemented)
|
120
|
+
compressed = ffmpeg.afilter(stream, name="acompressor", threshold=0.1, ratio=2)
|
121
|
+
```
|
81
122
|
|
82
123
|
Note:
|
83
|
-
This function is for custom
|
124
|
+
This function is for custom filters not implemented in typed-ffmpeg.
|
125
|
+
Use the built-in filters from the filters module when available.
|
84
126
|
"""
|
85
127
|
return FilterNode(
|
86
128
|
name=name,
|
87
129
|
inputs=streams,
|
88
130
|
output_typings=(StreamType.audio,),
|
89
131
|
input_typings=input_typings,
|
90
|
-
kwargs=
|
132
|
+
kwargs=FrozenDict(kwargs),
|
91
133
|
).audio(0)
|
92
134
|
|
93
135
|
|
@@ -99,24 +141,40 @@ def filter_multi_output(
|
|
99
141
|
**kwargs: Any,
|
100
142
|
) -> FilterNode:
|
101
143
|
"""
|
102
|
-
Apply a custom filter
|
144
|
+
Apply a custom filter that produces multiple output streams.
|
145
|
+
|
146
|
+
This function allows you to use any FFmpeg filter that generates multiple outputs
|
147
|
+
(like split, asplit, or complex filters). Unlike vfilter and afilter which return
|
148
|
+
a single stream, this returns a FilterNode that you can extract specific outputs from.
|
103
149
|
|
104
150
|
Args:
|
105
|
-
*streams:
|
106
|
-
name:
|
107
|
-
input_typings:
|
108
|
-
output_tyings:
|
109
|
-
**kwargs:
|
151
|
+
*streams: One or more input streams to apply the filter to
|
152
|
+
name: The FFmpeg filter name (e.g., 'split', 'channelsplit', etc.)
|
153
|
+
input_typings: The expected types of the input streams
|
154
|
+
output_tyings: The expected types of each output stream
|
155
|
+
**kwargs: Filter-specific parameters as keyword arguments
|
110
156
|
|
111
157
|
Returns:
|
112
|
-
|
158
|
+
A FilterNode object that you can extract specific outputs from
|
159
|
+
using methods like .video(0), .audio(1), etc.
|
160
|
+
|
161
|
+
Example:
|
162
|
+
```python
|
163
|
+
# Split a video into two identical streams
|
164
|
+
split_node = ffmpeg.filter_multi_output(
|
165
|
+
stream, name="split", output_tyings=(StreamType.video, StreamType.video)
|
166
|
+
)
|
167
|
+
stream1 = split_node.video(0)
|
168
|
+
stream2 = split_node.video(1)
|
169
|
+
```
|
113
170
|
|
114
171
|
Note:
|
115
|
-
This function is for custom
|
172
|
+
This function is for custom filters not implemented in typed-ffmpeg.
|
173
|
+
Use the built-in filters from the filters module when available.
|
116
174
|
"""
|
117
175
|
return FilterNode(
|
118
176
|
name=name,
|
119
|
-
kwargs=
|
177
|
+
kwargs=FrozenDict(kwargs),
|
120
178
|
inputs=streams,
|
121
179
|
input_typings=input_typings,
|
122
180
|
output_typings=output_tyings,
|
typed_ffmpeg/common/schema.py
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
"""
|
2
|
+
Schema definitions for FFmpeg filters and options.
|
3
|
+
|
4
|
+
This module defines the core data structures and enumerations used to represent
|
5
|
+
FFmpeg filters, their options, and stream types. These schemas are used throughout
|
6
|
+
the typed-ffmpeg library to provide type-safe interfaces to FFmpeg functionality.
|
7
|
+
"""
|
8
|
+
|
1
9
|
from __future__ import annotations
|
2
10
|
|
3
11
|
from dataclasses import dataclass
|
@@ -7,16 +15,30 @@ from typing import Literal
|
|
7
15
|
|
8
16
|
class StreamType(str, Enum):
|
9
17
|
"""
|
10
|
-
|
18
|
+
Enumeration of possible stream types in FFmpeg.
|
19
|
+
|
20
|
+
This enum defines the fundamental types of media streams that can be
|
21
|
+
processed by FFmpeg filters. Each stream in FFmpeg is either an audio
|
22
|
+
stream or a video stream, and filters are designed to work with
|
23
|
+
specific stream types.
|
11
24
|
"""
|
12
25
|
|
13
26
|
audio = "audio"
|
14
|
-
"""
|
27
|
+
"""Represents an audio stream containing sound data"""
|
28
|
+
|
15
29
|
video = "video"
|
16
|
-
"""
|
30
|
+
"""Represents a video stream containing visual frame data"""
|
17
31
|
|
18
32
|
|
19
33
|
class FFMpegFilterOptionType(str, Enum):
|
34
|
+
"""
|
35
|
+
Enumeration of possible data types for FFmpeg filter options.
|
36
|
+
|
37
|
+
This enum defines the various data types that can be used for options
|
38
|
+
in FFmpeg filters. Each type corresponds to a specific kind of value
|
39
|
+
that can be passed to a filter parameter.
|
40
|
+
"""
|
41
|
+
|
20
42
|
boolean = "boolean"
|
21
43
|
duration = "duration"
|
22
44
|
color = "color"
|
@@ -36,86 +58,232 @@ class FFMpegFilterOptionType(str, Enum):
|
|
36
58
|
|
37
59
|
|
38
60
|
class FFMpegFilterType(str, Enum):
|
61
|
+
"""
|
62
|
+
Enumeration of FFmpeg filter types based on input/output stream types.
|
63
|
+
|
64
|
+
This enum categorizes filters according to what types of streams they
|
65
|
+
process and produce. The naming convention follows FFmpeg's internal
|
66
|
+
categorization of filters.
|
67
|
+
"""
|
68
|
+
|
39
69
|
af = "af"
|
70
|
+
"""Audio filter: processes audio and outputs audio"""
|
71
|
+
|
40
72
|
asrc = "asrc"
|
73
|
+
"""Audio source: generates audio without input"""
|
74
|
+
|
41
75
|
asink = "asink"
|
76
|
+
"""Audio sink: consumes audio without producing output"""
|
77
|
+
|
42
78
|
vf = "vf"
|
79
|
+
"""Video filter: processes video and outputs video"""
|
80
|
+
|
43
81
|
vsrc = "vsrc"
|
82
|
+
"""Video source: generates video without input"""
|
83
|
+
|
44
84
|
vsink = "vsink"
|
85
|
+
"""Video sink: consumes video without producing output"""
|
86
|
+
|
45
87
|
avsrc = "avsrc"
|
88
|
+
"""Audio-video source: generates both audio and video without input"""
|
89
|
+
|
46
90
|
avf = "avf"
|
91
|
+
"""Audio-video filter: processes and outputs both audio and video"""
|
92
|
+
|
47
93
|
vaf = "vaf"
|
94
|
+
"""Video-to-audio filter: processes video and outputs audio"""
|
48
95
|
|
49
96
|
|
50
97
|
@dataclass(frozen=True, kw_only=True)
|
51
98
|
class FFMpegFilterOptionChoice:
|
99
|
+
"""
|
100
|
+
Represents a single choice for an FFmpeg filter option with enumerated values.
|
101
|
+
|
102
|
+
Some FFmpeg filter options accept only specific enumerated values. This class
|
103
|
+
represents one such value along with its description and internal representation.
|
104
|
+
"""
|
105
|
+
|
52
106
|
name: str
|
107
|
+
"""The name of the choice as it appears in FFmpeg documentation"""
|
108
|
+
|
53
109
|
help: str
|
110
|
+
"""Description of what this choice does"""
|
111
|
+
|
54
112
|
value: str | int
|
113
|
+
"""The actual value to pass to FFmpeg when this choice is selected"""
|
114
|
+
|
55
115
|
flags: str | None = None
|
116
|
+
"""Optional flags associated with this choice"""
|
56
117
|
|
57
118
|
|
58
119
|
@dataclass(frozen=True, kw_only=True)
|
59
120
|
class FFMpegFilterOption:
|
121
|
+
"""
|
122
|
+
Represents a configurable option for an FFmpeg filter.
|
123
|
+
|
124
|
+
This class defines the metadata for a single option that can be passed to
|
125
|
+
an FFmpeg filter, including its type, constraints, and default value.
|
126
|
+
"""
|
127
|
+
|
60
128
|
name: str
|
129
|
+
"""The primary name of the option as used in FFmpeg"""
|
130
|
+
|
61
131
|
alias: tuple[str, ...] = ()
|
132
|
+
"""Alternative names that can be used for this option"""
|
133
|
+
|
62
134
|
description: str
|
135
|
+
"""Human-readable description of what the option does"""
|
136
|
+
|
63
137
|
type: FFMpegFilterOptionType
|
138
|
+
"""The data type of the option (boolean, int, string, etc.)"""
|
139
|
+
|
64
140
|
min: str | None = None
|
141
|
+
"""Minimum allowed value for numeric options"""
|
142
|
+
|
65
143
|
max: str | None = None
|
144
|
+
"""Maximum allowed value for numeric options"""
|
145
|
+
|
66
146
|
default: bool | int | float | str | None = None
|
147
|
+
"""Default value used by FFmpeg if the option is not specified"""
|
148
|
+
|
67
149
|
required: bool = False
|
150
|
+
"""Whether the option must be provided or can be omitted"""
|
151
|
+
|
68
152
|
choices: tuple[FFMpegFilterOptionChoice, ...] = ()
|
153
|
+
"""Enumerated values that this option accepts, if applicable"""
|
154
|
+
|
69
155
|
flags: str | None = None
|
156
|
+
"""Optional flags that modify the behavior of this option"""
|
70
157
|
|
71
158
|
|
72
159
|
@dataclass(frozen=True, kw_only=True)
|
73
160
|
class FFMpegIOType:
|
161
|
+
"""
|
162
|
+
Defines the type information for a filter's input or output stream.
|
163
|
+
|
164
|
+
This class associates a name with a stream type (audio or video) for
|
165
|
+
a specific input or output of an FFmpeg filter.
|
166
|
+
"""
|
167
|
+
|
74
168
|
name: str | None = None
|
169
|
+
"""Optional name for this input/output stream"""
|
170
|
+
|
75
171
|
type: StreamType
|
172
|
+
"""The type of the stream (audio or video)"""
|
76
173
|
|
77
174
|
|
78
175
|
@dataclass(frozen=True, kw_only=True)
|
79
176
|
class FFMpegFilterDef:
|
177
|
+
"""
|
178
|
+
Defines the basic structure of an FFmpeg filter.
|
179
|
+
|
180
|
+
This class provides a simplified representation of an FFmpeg filter,
|
181
|
+
focusing on its name and the types of its inputs and outputs.
|
182
|
+
"""
|
183
|
+
|
80
184
|
name: str
|
185
|
+
"""The name of the filter as used in FFmpeg"""
|
81
186
|
|
82
187
|
typings_input: str | tuple[Literal["video", "audio"], ...] = ()
|
188
|
+
"""
|
189
|
+
The types of input streams this filter accepts.
|
190
|
+
Can be a tuple of stream types or a string expression that evaluates to a tuple.
|
191
|
+
"""
|
192
|
+
|
83
193
|
typings_output: str | tuple[Literal["video", "audio"], ...] = ()
|
194
|
+
"""
|
195
|
+
The types of output streams this filter produces.
|
196
|
+
Can be a tuple of stream types or a string expression that evaluates to a tuple.
|
197
|
+
"""
|
84
198
|
|
85
199
|
|
86
200
|
@dataclass(frozen=True, kw_only=True)
|
87
201
|
class FFMpegFilter:
|
202
|
+
"""
|
203
|
+
Comprehensive representation of an FFmpeg filter with all its metadata.
|
204
|
+
|
205
|
+
This class contains the complete definition of an FFmpeg filter, including
|
206
|
+
its name, description, capabilities, input/output specifications, and options.
|
207
|
+
It serves as the central schema for representing filters in typed-ffmpeg.
|
208
|
+
"""
|
209
|
+
|
88
210
|
id: str | None = None
|
211
|
+
"""Optional unique identifier for the filter"""
|
89
212
|
|
90
213
|
name: str
|
214
|
+
"""The name of the filter as used in FFmpeg commands"""
|
215
|
+
|
91
216
|
description: str
|
217
|
+
"""Human-readable description of what the filter does"""
|
218
|
+
|
92
219
|
ref: str | None = None
|
220
|
+
"""Optional reference to documentation or source code"""
|
93
221
|
|
94
222
|
# Flags
|
95
223
|
is_support_slice_threading: bool | None = None
|
224
|
+
"""Whether the filter supports slice-based multithreading"""
|
225
|
+
|
96
226
|
is_support_timeline: bool | None = None
|
227
|
+
"""Whether the filter supports timeline editing features"""
|
228
|
+
|
97
229
|
is_support_framesync: bool | None = None
|
230
|
+
"""Whether the filter supports frame synchronization"""
|
231
|
+
|
98
232
|
is_support_command: bool | None = None
|
233
|
+
"""Whether the filter supports runtime commands"""
|
234
|
+
|
99
235
|
is_filter_sink: bool | None = None
|
236
|
+
"""Whether the filter is a sink (consumes input without producing output)"""
|
237
|
+
|
100
238
|
is_filter_source: bool | None = None
|
239
|
+
"""Whether the filter is a source (produces output without requiring input)"""
|
101
240
|
|
102
241
|
# IO Typing
|
103
242
|
is_dynamic_input: bool = False
|
243
|
+
"""Whether the filter can accept a variable number of inputs"""
|
244
|
+
|
104
245
|
is_dynamic_output: bool = False
|
246
|
+
"""Whether the filter can produce a variable number of outputs"""
|
247
|
+
|
105
248
|
stream_typings_input: tuple[FFMpegIOType, ...] = ()
|
249
|
+
"""The types of input streams this filter accepts"""
|
250
|
+
|
106
251
|
stream_typings_output: tuple[FFMpegIOType, ...] = ()
|
252
|
+
"""The types of output streams this filter produces"""
|
253
|
+
|
107
254
|
formula_typings_input: str | None = None
|
255
|
+
"""Optional formula to dynamically determine input types"""
|
256
|
+
|
108
257
|
formula_typings_output: str | None = None
|
258
|
+
"""Optional formula to dynamically determine output types"""
|
109
259
|
|
110
260
|
pre: tuple[tuple[str, str], ...] = ()
|
261
|
+
"""Pre-defined parameter pairs for the filter"""
|
262
|
+
|
111
263
|
options: tuple[FFMpegFilterOption, ...] = ()
|
264
|
+
"""The configurable options this filter accepts"""
|
112
265
|
|
113
266
|
@property
|
114
267
|
def pre_dict(self) -> dict[str, str]:
|
268
|
+
"""
|
269
|
+
Convert the pre-defined parameter pairs to a dictionary.
|
270
|
+
|
271
|
+
Returns:
|
272
|
+
A dictionary mapping parameter names to their values
|
273
|
+
"""
|
115
274
|
return dict(self.pre)
|
116
275
|
|
117
276
|
@property
|
118
277
|
def to_def(self) -> FFMpegFilterDef:
|
278
|
+
"""
|
279
|
+
Convert this comprehensive filter definition to a simplified FFMpegFilterDef.
|
280
|
+
|
281
|
+
This creates a simplified representation of the filter focusing only on
|
282
|
+
its name and input/output types, which is useful for filter node creation.
|
283
|
+
|
284
|
+
Returns:
|
285
|
+
A simplified FFMpegFilterDef representation of this filter
|
286
|
+
"""
|
119
287
|
return FFMpegFilterDef(
|
120
288
|
name=self.name,
|
121
289
|
typings_input=self.formula_typings_input
|
@@ -126,6 +294,18 @@ class FFMpegFilter:
|
|
126
294
|
|
127
295
|
@property
|
128
296
|
def input_typings(self) -> set[StreamType]:
|
297
|
+
"""
|
298
|
+
Determine the set of input stream types this filter accepts.
|
299
|
+
|
300
|
+
This property analyzes the filter's input specifications to determine
|
301
|
+
what types of streams (audio, video, or both) it can accept as input.
|
302
|
+
|
303
|
+
Returns:
|
304
|
+
A set of StreamType values representing accepted input types
|
305
|
+
|
306
|
+
Raises:
|
307
|
+
AssertionError: If a dynamic input filter has no input formula
|
308
|
+
"""
|
129
309
|
if self.is_filter_source:
|
130
310
|
return set()
|
131
311
|
if not self.is_dynamic_input:
|
@@ -150,6 +330,18 @@ class FFMpegFilter:
|
|
150
330
|
|
151
331
|
@property
|
152
332
|
def output_typings(self) -> set[StreamType]:
|
333
|
+
"""
|
334
|
+
Determine the set of output stream types this filter produces.
|
335
|
+
|
336
|
+
This property analyzes the filter's output specifications to determine
|
337
|
+
what types of streams (audio, video, or both) it can produce as output.
|
338
|
+
|
339
|
+
Returns:
|
340
|
+
A set of StreamType values representing produced output types
|
341
|
+
|
342
|
+
Raises:
|
343
|
+
AssertionError: If a dynamic output filter has no output formula
|
344
|
+
"""
|
153
345
|
if self.is_filter_sink:
|
154
346
|
return set()
|
155
347
|
if not self.is_dynamic_output:
|
@@ -174,6 +366,22 @@ class FFMpegFilter:
|
|
174
366
|
|
175
367
|
@property
|
176
368
|
def filter_type(self) -> FFMpegFilterType:
|
369
|
+
"""
|
370
|
+
Determine the FFmpeg filter type based on input and output stream types.
|
371
|
+
|
372
|
+
This property analyzes the filter's input and output specifications to
|
373
|
+
determine which category of filter it belongs to according to FFmpeg's
|
374
|
+
classification system (audio filter, video filter, source, sink, etc.).
|
375
|
+
|
376
|
+
Returns:
|
377
|
+
The appropriate FFMpegFilterType for this filter
|
378
|
+
|
379
|
+
Raises:
|
380
|
+
ValueError: If the filter's input/output configuration doesn't match
|
381
|
+
any known filter type
|
382
|
+
AssertionError: If a sink filter has multiple input types or
|
383
|
+
if a filter has no input types
|
384
|
+
"""
|
177
385
|
if self.is_filter_sink:
|
178
386
|
assert len(self.input_typings) == 1
|
179
387
|
if {StreamType.video} == self.input_typings:
|
@@ -284,35 +492,96 @@ class FFMpegOptionFlag(int, Enum):
|
|
284
492
|
|
285
493
|
|
286
494
|
class FFMpegOptionType(str, Enum):
|
495
|
+
"""
|
496
|
+
Enumeration of FFmpeg option data types.
|
497
|
+
|
498
|
+
This enum defines the various data types that can be used for FFmpeg
|
499
|
+
command-line options. These types correspond to the internal option
|
500
|
+
types defined in FFmpeg's libavutil/opt.h header.
|
501
|
+
"""
|
502
|
+
|
287
503
|
OPT_TYPE_FUNC = "OPT_TYPE_FUNC"
|
504
|
+
"""Function option type, typically used for callback functions"""
|
505
|
+
|
288
506
|
OPT_TYPE_BOOL = "OPT_TYPE_BOOL"
|
507
|
+
"""Boolean option type (true/false)"""
|
508
|
+
|
289
509
|
OPT_TYPE_STRING = "OPT_TYPE_STRING"
|
510
|
+
"""String option type"""
|
511
|
+
|
290
512
|
OPT_TYPE_INT = "OPT_TYPE_INT"
|
513
|
+
"""Integer option type"""
|
514
|
+
|
291
515
|
OPT_TYPE_INT64 = "OPT_TYPE_INT64"
|
516
|
+
"""64-bit integer option type"""
|
517
|
+
|
292
518
|
OPT_TYPE_FLOAT = "OPT_TYPE_FLOAT"
|
519
|
+
"""Floating-point option type"""
|
520
|
+
|
293
521
|
OPT_TYPE_DOUBLE = "OPT_TYPE_DOUBLE"
|
522
|
+
"""Double-precision floating-point option type"""
|
523
|
+
|
294
524
|
OPT_TYPE_TIME = "OPT_TYPE_TIME"
|
525
|
+
"""Time value option type (e.g., duration in seconds)"""
|
295
526
|
|
296
527
|
|
297
528
|
@dataclass(frozen=True, kw_only=True)
|
298
529
|
class FFMpegOption:
|
530
|
+
"""
|
531
|
+
Represents a command-line option for FFmpeg.
|
532
|
+
|
533
|
+
This class defines the metadata for a single option that can be passed
|
534
|
+
to the FFmpeg command line, including its type, help text, and flags
|
535
|
+
that determine its behavior.
|
536
|
+
"""
|
537
|
+
|
299
538
|
name: str
|
539
|
+
"""The name of the option as used in FFmpeg commands"""
|
540
|
+
|
300
541
|
type: FFMpegOptionType
|
542
|
+
"""The data type of the option (boolean, int, string, etc.)"""
|
543
|
+
|
301
544
|
flags: int
|
545
|
+
"""Bitmap of FFMpegOptionFlag values that define the option's behavior"""
|
546
|
+
|
302
547
|
help: str
|
548
|
+
"""Human-readable description of what the option does"""
|
549
|
+
|
303
550
|
argname: str | None = None
|
551
|
+
"""Optional name for the option's argument in help text"""
|
552
|
+
|
304
553
|
canon: str | None = None
|
554
|
+
"""For alternative option forms, the name of the canonical option"""
|
305
555
|
|
306
556
|
@property
|
307
557
|
def is_input_option(self) -> bool:
|
558
|
+
"""
|
559
|
+
Check if this option applies to input files.
|
560
|
+
|
561
|
+
Returns:
|
562
|
+
True if this option is meant to be used with input files
|
563
|
+
"""
|
308
564
|
return bool(self.flags & FFMpegOptionFlag.OPT_INPUT)
|
309
565
|
|
310
566
|
@property
|
311
567
|
def is_output_option(self) -> bool:
|
568
|
+
"""
|
569
|
+
Check if this option applies to output files.
|
570
|
+
|
571
|
+
Returns:
|
572
|
+
True if this option is meant to be used with output files
|
573
|
+
"""
|
312
574
|
return bool(self.flags & FFMpegOptionFlag.OPT_OUTPUT)
|
313
575
|
|
314
576
|
@property
|
315
577
|
def is_global_option(self) -> bool:
|
578
|
+
"""
|
579
|
+
Check if this option applies globally rather than to specific files.
|
580
|
+
|
581
|
+
Returns:
|
582
|
+
True if this option is a global option that doesn't apply to
|
583
|
+
specific input or output files
|
584
|
+
"""
|
316
585
|
return (
|
317
586
|
not self.is_input_option
|
318
587
|
and not self.is_output_option
|
@@ -321,4 +590,13 @@ class FFMpegOption:
|
|
321
590
|
|
322
591
|
@property
|
323
592
|
def is_support_stream_specifier(self) -> bool:
|
593
|
+
"""
|
594
|
+
Check if this option supports stream specifiers.
|
595
|
+
|
596
|
+
Stream specifiers allow options to be applied to specific streams
|
597
|
+
within a file, using syntax like "-c:v" for video codec.
|
598
|
+
|
599
|
+
Returns:
|
600
|
+
True if this option can be used with stream specifiers
|
601
|
+
"""
|
324
602
|
return bool(self.flags & FFMpegOptionFlag.OPT_SPEC)
|