typed-ffmpeg-compatible 2.6.3__py3-none-any.whl → 2.7.0__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 +285 -4
- typed_ffmpeg/common/serialize.py +149 -34
- 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 +403 -71
- typed_ffmpeg/dag/schema.py +5 -2
- 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.7.0.dist-info}/METADATA +1 -1
- typed_ffmpeg_compatible-2.7.0.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.7.0.dist-info}/LICENSE +0 -0
- {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.7.0.dist-info}/WHEEL +0 -0
- {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.7.0.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,22 +1,47 @@
|
|
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
|
4
12
|
from enum import Enum
|
5
13
|
from typing import Literal
|
6
14
|
|
15
|
+
from ffmpeg.common.serialize import Serializable, serializable
|
7
16
|
|
17
|
+
|
18
|
+
@serializable
|
8
19
|
class StreamType(str, Enum):
|
9
20
|
"""
|
10
|
-
|
21
|
+
Enumeration of possible stream types in FFmpeg.
|
22
|
+
|
23
|
+
This enum defines the fundamental types of media streams that can be
|
24
|
+
processed by FFmpeg filters. Each stream in FFmpeg is either an audio
|
25
|
+
stream or a video stream, and filters are designed to work with
|
26
|
+
specific stream types.
|
11
27
|
"""
|
12
28
|
|
13
29
|
audio = "audio"
|
14
|
-
"""
|
30
|
+
"""Represents an audio stream containing sound data"""
|
31
|
+
|
15
32
|
video = "video"
|
16
|
-
"""
|
33
|
+
"""Represents a video stream containing visual frame data"""
|
17
34
|
|
18
35
|
|
19
36
|
class FFMpegFilterOptionType(str, Enum):
|
37
|
+
"""
|
38
|
+
Enumeration of possible data types for FFmpeg filter options.
|
39
|
+
|
40
|
+
This enum defines the various data types that can be used for options
|
41
|
+
in FFmpeg filters. Each type corresponds to a specific kind of value
|
42
|
+
that can be passed to a filter parameter.
|
43
|
+
"""
|
44
|
+
|
20
45
|
boolean = "boolean"
|
21
46
|
duration = "duration"
|
22
47
|
color = "color"
|
@@ -36,86 +61,232 @@ class FFMpegFilterOptionType(str, Enum):
|
|
36
61
|
|
37
62
|
|
38
63
|
class FFMpegFilterType(str, Enum):
|
64
|
+
"""
|
65
|
+
Enumeration of FFmpeg filter types based on input/output stream types.
|
66
|
+
|
67
|
+
This enum categorizes filters according to what types of streams they
|
68
|
+
process and produce. The naming convention follows FFmpeg's internal
|
69
|
+
categorization of filters.
|
70
|
+
"""
|
71
|
+
|
39
72
|
af = "af"
|
73
|
+
"""Audio filter: processes audio and outputs audio"""
|
74
|
+
|
40
75
|
asrc = "asrc"
|
76
|
+
"""Audio source: generates audio without input"""
|
77
|
+
|
41
78
|
asink = "asink"
|
79
|
+
"""Audio sink: consumes audio without producing output"""
|
80
|
+
|
42
81
|
vf = "vf"
|
82
|
+
"""Video filter: processes video and outputs video"""
|
83
|
+
|
43
84
|
vsrc = "vsrc"
|
85
|
+
"""Video source: generates video without input"""
|
86
|
+
|
44
87
|
vsink = "vsink"
|
88
|
+
"""Video sink: consumes video without producing output"""
|
89
|
+
|
45
90
|
avsrc = "avsrc"
|
91
|
+
"""Audio-video source: generates both audio and video without input"""
|
92
|
+
|
46
93
|
avf = "avf"
|
94
|
+
"""Audio-video filter: processes and outputs both audio and video"""
|
95
|
+
|
47
96
|
vaf = "vaf"
|
97
|
+
"""Video-to-audio filter: processes video and outputs audio"""
|
48
98
|
|
49
99
|
|
50
100
|
@dataclass(frozen=True, kw_only=True)
|
51
101
|
class FFMpegFilterOptionChoice:
|
102
|
+
"""
|
103
|
+
Represents a single choice for an FFmpeg filter option with enumerated values.
|
104
|
+
|
105
|
+
Some FFmpeg filter options accept only specific enumerated values. This class
|
106
|
+
represents one such value along with its description and internal representation.
|
107
|
+
"""
|
108
|
+
|
52
109
|
name: str
|
110
|
+
"""The name of the choice as it appears in FFmpeg documentation"""
|
111
|
+
|
53
112
|
help: str
|
113
|
+
"""Description of what this choice does"""
|
114
|
+
|
54
115
|
value: str | int
|
116
|
+
"""The actual value to pass to FFmpeg when this choice is selected"""
|
117
|
+
|
55
118
|
flags: str | None = None
|
119
|
+
"""Optional flags associated with this choice"""
|
56
120
|
|
57
121
|
|
58
122
|
@dataclass(frozen=True, kw_only=True)
|
59
123
|
class FFMpegFilterOption:
|
124
|
+
"""
|
125
|
+
Represents a configurable option for an FFmpeg filter.
|
126
|
+
|
127
|
+
This class defines the metadata for a single option that can be passed to
|
128
|
+
an FFmpeg filter, including its type, constraints, and default value.
|
129
|
+
"""
|
130
|
+
|
60
131
|
name: str
|
132
|
+
"""The primary name of the option as used in FFmpeg"""
|
133
|
+
|
61
134
|
alias: tuple[str, ...] = ()
|
135
|
+
"""Alternative names that can be used for this option"""
|
136
|
+
|
62
137
|
description: str
|
138
|
+
"""Human-readable description of what the option does"""
|
139
|
+
|
63
140
|
type: FFMpegFilterOptionType
|
141
|
+
"""The data type of the option (boolean, int, string, etc.)"""
|
142
|
+
|
64
143
|
min: str | None = None
|
144
|
+
"""Minimum allowed value for numeric options"""
|
145
|
+
|
65
146
|
max: str | None = None
|
147
|
+
"""Maximum allowed value for numeric options"""
|
148
|
+
|
66
149
|
default: bool | int | float | str | None = None
|
150
|
+
"""Default value used by FFmpeg if the option is not specified"""
|
151
|
+
|
67
152
|
required: bool = False
|
153
|
+
"""Whether the option must be provided or can be omitted"""
|
154
|
+
|
68
155
|
choices: tuple[FFMpegFilterOptionChoice, ...] = ()
|
156
|
+
"""Enumerated values that this option accepts, if applicable"""
|
157
|
+
|
69
158
|
flags: str | None = None
|
159
|
+
"""Optional flags that modify the behavior of this option"""
|
70
160
|
|
71
161
|
|
72
162
|
@dataclass(frozen=True, kw_only=True)
|
73
163
|
class FFMpegIOType:
|
164
|
+
"""
|
165
|
+
Defines the type information for a filter's input or output stream.
|
166
|
+
|
167
|
+
This class associates a name with a stream type (audio or video) for
|
168
|
+
a specific input or output of an FFmpeg filter.
|
169
|
+
"""
|
170
|
+
|
74
171
|
name: str | None = None
|
172
|
+
"""Optional name for this input/output stream"""
|
173
|
+
|
75
174
|
type: StreamType
|
175
|
+
"""The type of the stream (audio or video)"""
|
76
176
|
|
77
177
|
|
78
178
|
@dataclass(frozen=True, kw_only=True)
|
79
179
|
class FFMpegFilterDef:
|
180
|
+
"""
|
181
|
+
Defines the basic structure of an FFmpeg filter.
|
182
|
+
|
183
|
+
This class provides a simplified representation of an FFmpeg filter,
|
184
|
+
focusing on its name and the types of its inputs and outputs.
|
185
|
+
"""
|
186
|
+
|
80
187
|
name: str
|
188
|
+
"""The name of the filter as used in FFmpeg"""
|
81
189
|
|
82
190
|
typings_input: str | tuple[Literal["video", "audio"], ...] = ()
|
191
|
+
"""
|
192
|
+
The types of input streams this filter accepts.
|
193
|
+
Can be a tuple of stream types or a string expression that evaluates to a tuple.
|
194
|
+
"""
|
195
|
+
|
83
196
|
typings_output: str | tuple[Literal["video", "audio"], ...] = ()
|
197
|
+
"""
|
198
|
+
The types of output streams this filter produces.
|
199
|
+
Can be a tuple of stream types or a string expression that evaluates to a tuple.
|
200
|
+
"""
|
84
201
|
|
85
202
|
|
86
203
|
@dataclass(frozen=True, kw_only=True)
|
87
|
-
class FFMpegFilter:
|
204
|
+
class FFMpegFilter(Serializable):
|
205
|
+
"""
|
206
|
+
Comprehensive representation of an FFmpeg filter with all its metadata.
|
207
|
+
|
208
|
+
This class contains the complete definition of an FFmpeg filter, including
|
209
|
+
its name, description, capabilities, input/output specifications, and options.
|
210
|
+
It serves as the central schema for representing filters in typed-ffmpeg.
|
211
|
+
"""
|
212
|
+
|
88
213
|
id: str | None = None
|
214
|
+
"""Optional unique identifier for the filter"""
|
89
215
|
|
90
216
|
name: str
|
217
|
+
"""The name of the filter as used in FFmpeg commands"""
|
218
|
+
|
91
219
|
description: str
|
220
|
+
"""Human-readable description of what the filter does"""
|
221
|
+
|
92
222
|
ref: str | None = None
|
223
|
+
"""Optional reference to documentation or source code"""
|
93
224
|
|
94
225
|
# Flags
|
95
226
|
is_support_slice_threading: bool | None = None
|
227
|
+
"""Whether the filter supports slice-based multithreading"""
|
228
|
+
|
96
229
|
is_support_timeline: bool | None = None
|
230
|
+
"""Whether the filter supports timeline editing features"""
|
231
|
+
|
97
232
|
is_support_framesync: bool | None = None
|
233
|
+
"""Whether the filter supports frame synchronization"""
|
234
|
+
|
98
235
|
is_support_command: bool | None = None
|
236
|
+
"""Whether the filter supports runtime commands"""
|
237
|
+
|
99
238
|
is_filter_sink: bool | None = None
|
239
|
+
"""Whether the filter is a sink (consumes input without producing output)"""
|
240
|
+
|
100
241
|
is_filter_source: bool | None = None
|
242
|
+
"""Whether the filter is a source (produces output without requiring input)"""
|
101
243
|
|
102
244
|
# IO Typing
|
103
245
|
is_dynamic_input: bool = False
|
246
|
+
"""Whether the filter can accept a variable number of inputs"""
|
247
|
+
|
104
248
|
is_dynamic_output: bool = False
|
249
|
+
"""Whether the filter can produce a variable number of outputs"""
|
250
|
+
|
105
251
|
stream_typings_input: tuple[FFMpegIOType, ...] = ()
|
252
|
+
"""The types of input streams this filter accepts"""
|
253
|
+
|
106
254
|
stream_typings_output: tuple[FFMpegIOType, ...] = ()
|
255
|
+
"""The types of output streams this filter produces"""
|
256
|
+
|
107
257
|
formula_typings_input: str | None = None
|
258
|
+
"""Optional formula to dynamically determine input types"""
|
259
|
+
|
108
260
|
formula_typings_output: str | None = None
|
261
|
+
"""Optional formula to dynamically determine output types"""
|
109
262
|
|
110
263
|
pre: tuple[tuple[str, str], ...] = ()
|
264
|
+
"""Pre-defined parameter pairs for the filter"""
|
265
|
+
|
111
266
|
options: tuple[FFMpegFilterOption, ...] = ()
|
267
|
+
"""The configurable options this filter accepts"""
|
112
268
|
|
113
269
|
@property
|
114
270
|
def pre_dict(self) -> dict[str, str]:
|
271
|
+
"""
|
272
|
+
Convert the pre-defined parameter pairs to a dictionary.
|
273
|
+
|
274
|
+
Returns:
|
275
|
+
A dictionary mapping parameter names to their values
|
276
|
+
"""
|
115
277
|
return dict(self.pre)
|
116
278
|
|
117
279
|
@property
|
118
280
|
def to_def(self) -> FFMpegFilterDef:
|
281
|
+
"""
|
282
|
+
Convert this comprehensive filter definition to a simplified FFMpegFilterDef.
|
283
|
+
|
284
|
+
This creates a simplified representation of the filter focusing only on
|
285
|
+
its name and input/output types, which is useful for filter node creation.
|
286
|
+
|
287
|
+
Returns:
|
288
|
+
A simplified FFMpegFilterDef representation of this filter
|
289
|
+
"""
|
119
290
|
return FFMpegFilterDef(
|
120
291
|
name=self.name,
|
121
292
|
typings_input=self.formula_typings_input
|
@@ -126,6 +297,18 @@ class FFMpegFilter:
|
|
126
297
|
|
127
298
|
@property
|
128
299
|
def input_typings(self) -> set[StreamType]:
|
300
|
+
"""
|
301
|
+
Determine the set of input stream types this filter accepts.
|
302
|
+
|
303
|
+
This property analyzes the filter's input specifications to determine
|
304
|
+
what types of streams (audio, video, or both) it can accept as input.
|
305
|
+
|
306
|
+
Returns:
|
307
|
+
A set of StreamType values representing accepted input types
|
308
|
+
|
309
|
+
Raises:
|
310
|
+
AssertionError: If a dynamic input filter has no input formula
|
311
|
+
"""
|
129
312
|
if self.is_filter_source:
|
130
313
|
return set()
|
131
314
|
if not self.is_dynamic_input:
|
@@ -150,6 +333,18 @@ class FFMpegFilter:
|
|
150
333
|
|
151
334
|
@property
|
152
335
|
def output_typings(self) -> set[StreamType]:
|
336
|
+
"""
|
337
|
+
Determine the set of output stream types this filter produces.
|
338
|
+
|
339
|
+
This property analyzes the filter's output specifications to determine
|
340
|
+
what types of streams (audio, video, or both) it can produce as output.
|
341
|
+
|
342
|
+
Returns:
|
343
|
+
A set of StreamType values representing produced output types
|
344
|
+
|
345
|
+
Raises:
|
346
|
+
AssertionError: If a dynamic output filter has no output formula
|
347
|
+
"""
|
153
348
|
if self.is_filter_sink:
|
154
349
|
return set()
|
155
350
|
if not self.is_dynamic_output:
|
@@ -174,6 +369,22 @@ class FFMpegFilter:
|
|
174
369
|
|
175
370
|
@property
|
176
371
|
def filter_type(self) -> FFMpegFilterType:
|
372
|
+
"""
|
373
|
+
Determine the FFmpeg filter type based on input and output stream types.
|
374
|
+
|
375
|
+
This property analyzes the filter's input and output specifications to
|
376
|
+
determine which category of filter it belongs to according to FFmpeg's
|
377
|
+
classification system (audio filter, video filter, source, sink, etc.).
|
378
|
+
|
379
|
+
Returns:
|
380
|
+
The appropriate FFMpegFilterType for this filter
|
381
|
+
|
382
|
+
Raises:
|
383
|
+
ValueError: If the filter's input/output configuration doesn't match
|
384
|
+
any known filter type
|
385
|
+
AssertionError: If a sink filter has multiple input types or
|
386
|
+
if a filter has no input types
|
387
|
+
"""
|
177
388
|
if self.is_filter_sink:
|
178
389
|
assert len(self.input_typings) == 1
|
179
390
|
if {StreamType.video} == self.input_typings:
|
@@ -284,35 +495,96 @@ class FFMpegOptionFlag(int, Enum):
|
|
284
495
|
|
285
496
|
|
286
497
|
class FFMpegOptionType(str, Enum):
|
498
|
+
"""
|
499
|
+
Enumeration of FFmpeg option data types.
|
500
|
+
|
501
|
+
This enum defines the various data types that can be used for FFmpeg
|
502
|
+
command-line options. These types correspond to the internal option
|
503
|
+
types defined in FFmpeg's libavutil/opt.h header.
|
504
|
+
"""
|
505
|
+
|
287
506
|
OPT_TYPE_FUNC = "OPT_TYPE_FUNC"
|
507
|
+
"""Function option type, typically used for callback functions"""
|
508
|
+
|
288
509
|
OPT_TYPE_BOOL = "OPT_TYPE_BOOL"
|
510
|
+
"""Boolean option type (true/false)"""
|
511
|
+
|
289
512
|
OPT_TYPE_STRING = "OPT_TYPE_STRING"
|
513
|
+
"""String option type"""
|
514
|
+
|
290
515
|
OPT_TYPE_INT = "OPT_TYPE_INT"
|
516
|
+
"""Integer option type"""
|
517
|
+
|
291
518
|
OPT_TYPE_INT64 = "OPT_TYPE_INT64"
|
519
|
+
"""64-bit integer option type"""
|
520
|
+
|
292
521
|
OPT_TYPE_FLOAT = "OPT_TYPE_FLOAT"
|
522
|
+
"""Floating-point option type"""
|
523
|
+
|
293
524
|
OPT_TYPE_DOUBLE = "OPT_TYPE_DOUBLE"
|
525
|
+
"""Double-precision floating-point option type"""
|
526
|
+
|
294
527
|
OPT_TYPE_TIME = "OPT_TYPE_TIME"
|
528
|
+
"""Time value option type (e.g., duration in seconds)"""
|
295
529
|
|
296
530
|
|
297
531
|
@dataclass(frozen=True, kw_only=True)
|
298
532
|
class FFMpegOption:
|
533
|
+
"""
|
534
|
+
Represents a command-line option for FFmpeg.
|
535
|
+
|
536
|
+
This class defines the metadata for a single option that can be passed
|
537
|
+
to the FFmpeg command line, including its type, help text, and flags
|
538
|
+
that determine its behavior.
|
539
|
+
"""
|
540
|
+
|
299
541
|
name: str
|
542
|
+
"""The name of the option as used in FFmpeg commands"""
|
543
|
+
|
300
544
|
type: FFMpegOptionType
|
545
|
+
"""The data type of the option (boolean, int, string, etc.)"""
|
546
|
+
|
301
547
|
flags: int
|
548
|
+
"""Bitmap of FFMpegOptionFlag values that define the option's behavior"""
|
549
|
+
|
302
550
|
help: str
|
551
|
+
"""Human-readable description of what the option does"""
|
552
|
+
|
303
553
|
argname: str | None = None
|
554
|
+
"""Optional name for the option's argument in help text"""
|
555
|
+
|
304
556
|
canon: str | None = None
|
557
|
+
"""For alternative option forms, the name of the canonical option"""
|
305
558
|
|
306
559
|
@property
|
307
560
|
def is_input_option(self) -> bool:
|
561
|
+
"""
|
562
|
+
Check if this option applies to input files.
|
563
|
+
|
564
|
+
Returns:
|
565
|
+
True if this option is meant to be used with input files
|
566
|
+
"""
|
308
567
|
return bool(self.flags & FFMpegOptionFlag.OPT_INPUT)
|
309
568
|
|
310
569
|
@property
|
311
570
|
def is_output_option(self) -> bool:
|
571
|
+
"""
|
572
|
+
Check if this option applies to output files.
|
573
|
+
|
574
|
+
Returns:
|
575
|
+
True if this option is meant to be used with output files
|
576
|
+
"""
|
312
577
|
return bool(self.flags & FFMpegOptionFlag.OPT_OUTPUT)
|
313
578
|
|
314
579
|
@property
|
315
580
|
def is_global_option(self) -> bool:
|
581
|
+
"""
|
582
|
+
Check if this option applies globally rather than to specific files.
|
583
|
+
|
584
|
+
Returns:
|
585
|
+
True if this option is a global option that doesn't apply to
|
586
|
+
specific input or output files
|
587
|
+
"""
|
316
588
|
return (
|
317
589
|
not self.is_input_option
|
318
590
|
and not self.is_output_option
|
@@ -321,4 +593,13 @@ class FFMpegOption:
|
|
321
593
|
|
322
594
|
@property
|
323
595
|
def is_support_stream_specifier(self) -> bool:
|
596
|
+
"""
|
597
|
+
Check if this option supports stream specifiers.
|
598
|
+
|
599
|
+
Stream specifiers allow options to be applied to specific streams
|
600
|
+
within a file, using syntax like "-c:v" for video codec.
|
601
|
+
|
602
|
+
Returns:
|
603
|
+
True if this option can be used with stream specifiers
|
604
|
+
"""
|
324
605
|
return bool(self.flags & FFMpegOptionFlag.OPT_SPEC)
|