typed-ffmpeg-compatible 3.5.1__py3-none-any.whl → 3.6__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 +4 -1
- typed_ffmpeg/_version.py +2 -2
- typed_ffmpeg/base.py +4 -1
- typed_ffmpeg/codecs/__init__.py +2 -0
- typed_ffmpeg/codecs/decoders.py +1852 -1853
- typed_ffmpeg/codecs/encoders.py +2001 -1782
- typed_ffmpeg/codecs/schema.py +6 -12
- typed_ffmpeg/common/__init__.py +1 -0
- typed_ffmpeg/common/cache.py +9 -6
- typed_ffmpeg/common/schema.py +11 -0
- typed_ffmpeg/common/serialize.py +13 -7
- typed_ffmpeg/compile/__init__.py +1 -0
- typed_ffmpeg/compile/compile_cli.py +55 -8
- typed_ffmpeg/compile/compile_json.py +4 -0
- typed_ffmpeg/compile/compile_python.py +15 -0
- typed_ffmpeg/compile/context.py +15 -4
- typed_ffmpeg/compile/validate.py +9 -8
- typed_ffmpeg/dag/factory.py +2 -0
- typed_ffmpeg/dag/global_runnable/__init__.py +1 -0
- typed_ffmpeg/dag/global_runnable/global_args.py +2 -2
- typed_ffmpeg/dag/global_runnable/runnable.py +51 -11
- typed_ffmpeg/dag/io/__init__.py +1 -0
- typed_ffmpeg/dag/io/_input.py +20 -5
- typed_ffmpeg/dag/io/_output.py +24 -9
- typed_ffmpeg/dag/io/output_args.py +21 -7
- typed_ffmpeg/dag/nodes.py +20 -0
- typed_ffmpeg/dag/schema.py +19 -6
- typed_ffmpeg/dag/utils.py +2 -2
- typed_ffmpeg/exceptions.py +2 -1
- typed_ffmpeg/expressions.py +884 -0
- typed_ffmpeg/ffprobe/__init__.py +1 -0
- typed_ffmpeg/ffprobe/parse.py +7 -1
- typed_ffmpeg/ffprobe/probe.py +3 -1
- typed_ffmpeg/ffprobe/schema.py +83 -1
- typed_ffmpeg/ffprobe/xml2json.py +8 -2
- typed_ffmpeg/filters.py +540 -631
- typed_ffmpeg/formats/__init__.py +2 -0
- typed_ffmpeg/formats/demuxers.py +1869 -1921
- typed_ffmpeg/formats/muxers.py +1382 -1107
- typed_ffmpeg/formats/schema.py +6 -12
- typed_ffmpeg/info.py +8 -0
- typed_ffmpeg/options/__init__.py +15 -0
- typed_ffmpeg/options/codec.py +711 -0
- typed_ffmpeg/options/format.py +196 -0
- typed_ffmpeg/options/framesync.py +43 -0
- typed_ffmpeg/options/timeline.py +22 -0
- typed_ffmpeg/schema.py +15 -0
- typed_ffmpeg/sources.py +392 -381
- typed_ffmpeg/streams/__init__.py +2 -0
- typed_ffmpeg/streams/audio.py +1071 -882
- typed_ffmpeg/streams/av.py +9 -3
- typed_ffmpeg/streams/subtitle.py +3 -3
- typed_ffmpeg/streams/video.py +1873 -1725
- typed_ffmpeg/types.py +3 -2
- typed_ffmpeg/utils/__init__.py +1 -0
- typed_ffmpeg/utils/escaping.py +8 -4
- typed_ffmpeg/utils/frozendict.py +31 -1
- typed_ffmpeg/utils/lazy_eval/__init__.py +1 -0
- typed_ffmpeg/utils/lazy_eval/operator.py +75 -27
- typed_ffmpeg/utils/lazy_eval/schema.py +176 -4
- typed_ffmpeg/utils/run.py +2 -0
- typed_ffmpeg/utils/snapshot.py +3 -2
- typed_ffmpeg/utils/typing.py +2 -1
- typed_ffmpeg/utils/view.py +2 -1
- {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/METADATA +1 -1
- typed_ffmpeg_compatible-3.6.dist-info/RECORD +73 -0
- typed_ffmpeg_compatible-3.5.1.dist-info/RECORD +0 -67
- {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/WHEEL +0 -0
- {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/entry_points.txt +0 -0
- {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/licenses/LICENSE +0 -0
- {typed_ffmpeg_compatible-3.5.1.dist-info → typed_ffmpeg_compatible-3.6.dist-info}/top_level.txt +0 -0
typed_ffmpeg/types.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
"""
|
2
|
-
|
2
|
+
Define the various types of options that can be used with FFmpeg.
|
3
|
+
|
3
4
|
These option types can be one of several different categories.
|
4
5
|
The source of these types is defined within the AVOptionType enumeration found in FFmpeg's opt.h header file.
|
5
6
|
"""
|
@@ -29,7 +30,7 @@ Color = str | Default | LazyValue | None
|
|
29
30
|
"""
|
30
31
|
It can be the name of a color as defined below (case insensitive match) or a [0x|#]RRGGBB[AA] sequence, possibly followed by @ and a string representing the alpha component.
|
31
32
|
The alpha component may be a string composed by "0x" followed by an hexadecimal number or a decimal number between 0.0 and 1.0, which represents the opacity value (‘0x00’ or ‘0.0’ means completely transparent, ‘0xff’ or ‘1.0’ completely opaque). If the alpha component is not specified then ‘0xff’ is assumed.
|
32
|
-
The string
|
33
|
+
The string 'random' will result in a random color.
|
33
34
|
|
34
35
|
Note:
|
35
36
|
[Document](https://ffmpeg.org/ffmpeg-utils.html#Color)
|
typed_ffmpeg/utils/__init__.py
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
"""Utility modules for the typed-ffmpeg package."""
|
typed_ffmpeg/utils/escaping.py
CHANGED
@@ -11,7 +11,7 @@ from typing import Any
|
|
11
11
|
|
12
12
|
|
13
13
|
def escape(text: str | int | float, chars: str = "\\'=:") -> str:
|
14
|
-
"""
|
14
|
+
r"""
|
15
15
|
Escape special characters in a string for use in FFmpeg commands.
|
16
16
|
|
17
17
|
This function adds backslash escaping to specified characters in a string,
|
@@ -34,6 +34,7 @@ def escape(text: str | int | float, chars: str = "\\'=:") -> str:
|
|
34
34
|
# Escape a filter parameter value
|
35
35
|
safe_value = escape("key=value", "=:") # "key\\=value"
|
36
36
|
```
|
37
|
+
|
37
38
|
"""
|
38
39
|
text = str(text)
|
39
40
|
_chars = list(set(chars))
|
@@ -64,9 +65,11 @@ def convert_kwargs_to_cmd_line_args(kwargs: dict[str, Any]) -> list[str]:
|
|
64
65
|
|
65
66
|
Example:
|
66
67
|
```python
|
67
|
-
args = convert_kwargs_to_cmd_line_args(
|
68
|
-
|
69
|
-
|
68
|
+
args = convert_kwargs_to_cmd_line_args({
|
69
|
+
"c:v": "libx264",
|
70
|
+
"crf": 23,
|
71
|
+
"preset": "medium",
|
72
|
+
})
|
70
73
|
# Returns ['-c:v', 'libx264', '-crf', '23', '-preset', 'medium']
|
71
74
|
```
|
72
75
|
|
@@ -74,6 +77,7 @@ def convert_kwargs_to_cmd_line_args(kwargs: dict[str, Any]) -> list[str]:
|
|
74
77
|
If a value is None, only the parameter name is included.
|
75
78
|
If a value is an iterable (but not a string), the parameter is repeated
|
76
79
|
for each value in the iterable.
|
80
|
+
|
77
81
|
"""
|
78
82
|
args = []
|
79
83
|
for k in sorted(kwargs.keys()):
|
typed_ffmpeg/utils/frozendict.py
CHANGED
@@ -29,6 +29,7 @@ class FrozenDict(Mapping[K, V], Generic[K, V]):
|
|
29
29
|
|
30
30
|
Args:
|
31
31
|
data: Dictionary to create a frozen copy of
|
32
|
+
|
32
33
|
"""
|
33
34
|
self._data = dict(data)
|
34
35
|
self._hash: int | None = None # lazy computed
|
@@ -45,6 +46,7 @@ class FrozenDict(Mapping[K, V], Generic[K, V]):
|
|
45
46
|
|
46
47
|
Raises:
|
47
48
|
KeyError: If the key is not found
|
49
|
+
|
48
50
|
"""
|
49
51
|
return self._data[key]
|
50
52
|
|
@@ -54,6 +56,7 @@ class FrozenDict(Mapping[K, V], Generic[K, V]):
|
|
54
56
|
|
55
57
|
Returns:
|
56
58
|
An iterator yielding the dictionary keys
|
59
|
+
|
57
60
|
"""
|
58
61
|
return iter(self._data)
|
59
62
|
|
@@ -63,6 +66,7 @@ class FrozenDict(Mapping[K, V], Generic[K, V]):
|
|
63
66
|
|
64
67
|
Returns:
|
65
68
|
The number of key-value pairs in the dictionary
|
69
|
+
|
66
70
|
"""
|
67
71
|
return len(self._data)
|
68
72
|
|
@@ -72,6 +76,7 @@ class FrozenDict(Mapping[K, V], Generic[K, V]):
|
|
72
76
|
|
73
77
|
Returns:
|
74
78
|
A string representation showing the dictionary contents
|
79
|
+
|
75
80
|
"""
|
76
81
|
return f"FrozenDict({self._data})"
|
77
82
|
|
@@ -87,6 +92,7 @@ class FrozenDict(Mapping[K, V], Generic[K, V]):
|
|
87
92
|
|
88
93
|
Returns:
|
89
94
|
True if the objects are equal, False otherwise
|
95
|
+
|
90
96
|
"""
|
91
97
|
if isinstance(other, Mapping):
|
92
98
|
return dict(self._data) == dict(other)
|
@@ -101,6 +107,7 @@ class FrozenDict(Mapping[K, V], Generic[K, V]):
|
|
101
107
|
|
102
108
|
Returns:
|
103
109
|
An integer hash value
|
110
|
+
|
104
111
|
"""
|
105
112
|
if self._hash is None:
|
106
113
|
# Create a stable hash based on sorted key-value pairs
|
@@ -108,9 +115,29 @@ class FrozenDict(Mapping[K, V], Generic[K, V]):
|
|
108
115
|
return self._hash
|
109
116
|
|
110
117
|
def __or__(self, other: Mapping[Any, Any]) -> dict[Any, Any]:
|
118
|
+
"""
|
119
|
+
Merge this FrozenDict with another mapping using the | operator.
|
120
|
+
|
121
|
+
Args:
|
122
|
+
other: Mapping to merge with
|
123
|
+
|
124
|
+
Returns:
|
125
|
+
A new regular dict containing the merged contents
|
126
|
+
|
127
|
+
"""
|
111
128
|
return dict(self) | dict(other)
|
112
129
|
|
113
130
|
def __ror__(self, other: Mapping[Any, Any]) -> dict[Any, Any]:
|
131
|
+
"""
|
132
|
+
Merge another mapping with this FrozenDict using the | operator.
|
133
|
+
|
134
|
+
Args:
|
135
|
+
other: Mapping to merge with
|
136
|
+
|
137
|
+
Returns:
|
138
|
+
A new regular dict containing the merged contents
|
139
|
+
|
140
|
+
"""
|
114
141
|
return dict(other) | dict(self)
|
115
142
|
|
116
143
|
|
@@ -123,6 +150,7 @@ def merge(*maps: Mapping[Any, Any] | None) -> FrozenDict[Any, Any]:
|
|
123
150
|
|
124
151
|
Returns:
|
125
152
|
A new dictionary containing the merged contents of all input dictionaries
|
153
|
+
|
126
154
|
"""
|
127
155
|
output = {}
|
128
156
|
|
@@ -145,13 +173,14 @@ def exclude(maps: Mapping[Any, Any], exclude: Iterable[Any]) -> FrozenDict[Any,
|
|
145
173
|
|
146
174
|
Returns:
|
147
175
|
A new dictionary with the keys excluded
|
176
|
+
|
148
177
|
"""
|
149
178
|
return FrozenDict({k: v for k, v in maps.items() if k not in exclude})
|
150
179
|
|
151
180
|
|
152
181
|
def rekey(maps: Mapping[Any, Any], rekey: Mapping[Any, Any]) -> FrozenDict[Any, Any]:
|
153
182
|
"""
|
154
|
-
|
183
|
+
Rekey the keys of a dictionary.
|
155
184
|
|
156
185
|
Args:
|
157
186
|
maps: Dictionary to rekey
|
@@ -159,5 +188,6 @@ def rekey(maps: Mapping[Any, Any], rekey: Mapping[Any, Any]) -> FrozenDict[Any,
|
|
159
188
|
|
160
189
|
Returns:
|
161
190
|
A new dictionary with the keys remapped
|
191
|
+
|
162
192
|
"""
|
163
193
|
return FrozenDict({rekey.get(k, k): v for k, v in maps.items()})
|
@@ -0,0 +1 @@
|
|
1
|
+
"""Lazy evaluation utilities for typed-ffmpeg."""
|
@@ -34,6 +34,7 @@ class Add(LazyOperator):
|
|
34
34
|
# Evaluate the expression with specific values
|
35
35
|
result = expr.eval(width=1280, height=720) # Returns 2000
|
36
36
|
```
|
37
|
+
|
37
38
|
"""
|
38
39
|
|
39
40
|
def _eval(self, left: Any, right: Any) -> Any:
|
@@ -46,6 +47,7 @@ class Add(LazyOperator):
|
|
46
47
|
|
47
48
|
Returns:
|
48
49
|
The sum of the left and right operands
|
50
|
+
|
49
51
|
"""
|
50
52
|
return left + right
|
51
53
|
|
@@ -55,122 +57,168 @@ class Add(LazyOperator):
|
|
55
57
|
|
56
58
|
Returns:
|
57
59
|
A string in the format "(left+right)"
|
60
|
+
|
58
61
|
"""
|
59
62
|
return f"({self.left}+{self.right})"
|
60
63
|
|
61
64
|
|
62
65
|
@dataclass(frozen=True, kw_only=True)
|
63
66
|
class Sub(LazyOperator):
|
64
|
-
"""
|
65
|
-
A lazy operator for subtraction.
|
66
|
-
"""
|
67
|
+
"""A lazy operator for subtraction."""
|
67
68
|
|
68
69
|
def _eval(self, left: Any, right: Any) -> Any:
|
69
70
|
return left - right
|
70
71
|
|
71
72
|
def __str__(self) -> str:
|
73
|
+
"""
|
74
|
+
Get a string representation of this subtraction operation.
|
75
|
+
|
76
|
+
Returns:
|
77
|
+
A string in the format "(left-right)"
|
78
|
+
|
79
|
+
"""
|
72
80
|
return f"({self.left}-{self.right})"
|
73
81
|
|
74
82
|
|
75
83
|
@dataclass(frozen=True, kw_only=True)
|
76
84
|
class Mul(LazyOperator):
|
77
|
-
"""
|
78
|
-
A lazy operator for multiplication.
|
79
|
-
"""
|
85
|
+
"""A lazy operator for multiplication."""
|
80
86
|
|
81
87
|
def _eval(self, left: Any, right: Any) -> Any:
|
82
88
|
return left * right
|
83
89
|
|
84
90
|
def __str__(self) -> str:
|
91
|
+
"""
|
92
|
+
Get a string representation of this multiplication operation.
|
93
|
+
|
94
|
+
Returns:
|
95
|
+
A string in the format "(left*right)"
|
96
|
+
|
97
|
+
"""
|
85
98
|
return f"({self.left}*{self.right})"
|
86
99
|
|
87
100
|
|
88
101
|
@dataclass(frozen=True, kw_only=True)
|
89
102
|
class TrueDiv(LazyOperator):
|
90
|
-
"""
|
91
|
-
A lazy operator for true division.
|
92
|
-
"""
|
103
|
+
"""A lazy operator for true division."""
|
93
104
|
|
94
105
|
def _eval(self, left: Any, right: Any) -> Any:
|
95
106
|
return left / right
|
96
107
|
|
97
108
|
def __str__(self) -> str:
|
109
|
+
"""
|
110
|
+
Get a string representation of this division operation.
|
111
|
+
|
112
|
+
Returns:
|
113
|
+
A string in the format "(left/right)"
|
114
|
+
|
115
|
+
"""
|
98
116
|
return f"({self.left}/{self.right})"
|
99
117
|
|
100
118
|
|
101
119
|
@dataclass(frozen=True, kw_only=True)
|
102
120
|
class Pow(LazyOperator):
|
103
|
-
"""
|
104
|
-
A lazy operator for exponentiation.
|
105
|
-
"""
|
121
|
+
"""A lazy operator for exponentiation."""
|
106
122
|
|
107
123
|
def _eval(self, left: Any, right: Any) -> Any:
|
108
124
|
return left**right
|
109
125
|
|
110
126
|
def __str__(self) -> str:
|
127
|
+
"""
|
128
|
+
Get a string representation of this exponentiation operation.
|
129
|
+
|
130
|
+
Returns:
|
131
|
+
A string in the format "(left**right)"
|
132
|
+
|
133
|
+
"""
|
111
134
|
return f"({self.left}**{self.right})"
|
112
135
|
|
113
136
|
|
114
137
|
@dataclass(frozen=True, kw_only=True)
|
115
138
|
class Neg(LazyOperator):
|
116
|
-
"""
|
117
|
-
A lazy operator for negation.
|
118
|
-
"""
|
139
|
+
"""A lazy operator for negation."""
|
119
140
|
|
120
141
|
def _eval(self, left: Any, right: Any) -> Any:
|
121
142
|
return -left
|
122
143
|
|
123
144
|
def __str__(self) -> str:
|
145
|
+
"""
|
146
|
+
Get a string representation of this negation operation.
|
147
|
+
|
148
|
+
Returns:
|
149
|
+
A string in the format "-left"
|
150
|
+
|
151
|
+
"""
|
124
152
|
return f"-{self.left}"
|
125
153
|
|
126
154
|
|
127
155
|
@dataclass(frozen=True, kw_only=True)
|
128
156
|
class Pos(LazyOperator):
|
129
|
-
"""
|
130
|
-
A lazy operator for positive.
|
131
|
-
"""
|
157
|
+
"""A lazy operator for positive."""
|
132
158
|
|
133
159
|
def _eval(self, left: Any, right: Any) -> Any:
|
134
160
|
return +left
|
135
161
|
|
136
162
|
def __str__(self) -> str:
|
163
|
+
"""
|
164
|
+
Get a string representation of this positive operation.
|
165
|
+
|
166
|
+
Returns:
|
167
|
+
A string in the format "+left"
|
168
|
+
|
169
|
+
"""
|
137
170
|
return f"+{self.left}"
|
138
171
|
|
139
172
|
|
140
173
|
@dataclass(frozen=True, kw_only=True)
|
141
174
|
class Abs(LazyOperator):
|
142
|
-
"""
|
143
|
-
A lazy operator for absolute value.
|
144
|
-
"""
|
175
|
+
"""A lazy operator for absolute value."""
|
145
176
|
|
146
177
|
def _eval(self, left: Any, right: Any) -> Any:
|
147
178
|
return abs(left)
|
148
179
|
|
149
180
|
def __str__(self) -> str:
|
181
|
+
"""
|
182
|
+
Get a string representation of this absolute value operation.
|
183
|
+
|
184
|
+
Returns:
|
185
|
+
A string in the format "abs(left)"
|
186
|
+
|
187
|
+
"""
|
150
188
|
return f"abs({self.left})"
|
151
189
|
|
152
190
|
|
153
191
|
@dataclass(frozen=True, kw_only=True)
|
154
192
|
class Mod(LazyOperator):
|
155
|
-
"""
|
156
|
-
A lazy operator for modulo.
|
157
|
-
"""
|
193
|
+
"""A lazy operator for modulo."""
|
158
194
|
|
159
195
|
def _eval(self, left: Any, right: Any) -> Any:
|
160
196
|
return left % right
|
161
197
|
|
162
198
|
def __str__(self) -> str:
|
199
|
+
"""
|
200
|
+
Get a string representation of this modulo operation.
|
201
|
+
|
202
|
+
Returns:
|
203
|
+
A string in the format "(left%right)"
|
204
|
+
|
205
|
+
"""
|
163
206
|
return f"({self.left}%{self.right})"
|
164
207
|
|
165
208
|
|
166
209
|
@dataclass(frozen=True, kw_only=True)
|
167
210
|
class FloorDiv(LazyOperator):
|
168
|
-
"""
|
169
|
-
A lazy operator for floor division.
|
170
|
-
"""
|
211
|
+
"""A lazy operator for floor division."""
|
171
212
|
|
172
213
|
def _eval(self, left: Any, right: Any) -> Any:
|
173
214
|
return left // right
|
174
215
|
|
175
216
|
def __str__(self) -> str:
|
217
|
+
"""
|
218
|
+
Get a string representation of this floor division operation.
|
219
|
+
|
220
|
+
Returns:
|
221
|
+
A string in the format "(left//right)"
|
222
|
+
|
223
|
+
"""
|
176
224
|
return f"({self.left}//{self.right})"
|