typed-ffmpeg-compatible 3.0.0__tar.gz → 3.0.0a0__tar.gz
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_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/PKG-INFO +1 -1
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/pyproject.toml +1 -1
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/compile/compile_cli.py +70 -14
- typed_ffmpeg_compatible-3.0.0a0/src/typed_ffmpeg/compile/compile_json.py +38 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/compile/compile_python.py +4 -4
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/global_runnable/runnable.py +6 -6
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/LICENSE +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/README.md +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/base.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/.gitignore +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/acrossover.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/afir.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/aiir.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/ainterleave.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/amerge.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/amix.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/amovie.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/anequalizer.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/aphasemeter.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/asegment.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/aselect.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/asplit.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/astreamselect.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/bm3d.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/channelsplit.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/concat.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/decimate.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/ebur128.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/extractplanes.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/fieldmatch.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/guided.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/headphone.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/hstack.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/interleave.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/join.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/libplacebo.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/limitdiff.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/mergeplanes.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/mix.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/movie.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/premultiply.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/segment.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/select.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/signature.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/split.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/streamselect.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/unpremultiply.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/vstack.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/xmedian.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/FFMpegFilterManuallyDefined/xstack.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache/list/filters.json +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/schema.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/serialize.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/compile/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/compile/context.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/compile/validate.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/factory.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/global_runnable/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/global_runnable/global_args.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/io/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/io/_input.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/io/_output.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/io/output_args.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/nodes.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/schema.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/utils.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/exceptions.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/filters.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/info.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/probe.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/py.typed +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/schema.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/sources.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/streams/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/streams/audio.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/streams/av.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/streams/channel_layout.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/streams/video.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/types.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/escaping.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/forzendict.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/lazy_eval/__init__.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/lazy_eval/operator.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/lazy_eval/schema.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/run.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/snapshot.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/typing.py +0 -0
- {typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/view.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: typed-ffmpeg-compatible
|
3
|
-
Version: 3.0.
|
3
|
+
Version: 3.0.0a0
|
4
4
|
Summary: Modern Python FFmpeg wrappers offer comprehensive support for complex filters, complete with detailed typing and documentation.
|
5
5
|
Home-page: https://livingbio.github.io/typed-ffmpeg/
|
6
6
|
License: MIT
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "typed-ffmpeg-compatible"
|
3
|
-
version = "3.0.
|
3
|
+
version = "3.0.0a0"
|
4
4
|
description = "Modern Python FFmpeg wrappers offer comprehensive support for complex filters, complete with detailed typing and documentation."
|
5
5
|
authors = ["lucemia <lucemia@gmail.com>"]
|
6
6
|
readme = "README.md"
|
@@ -3,8 +3,15 @@ Compiles FFmpeg filter graphs into command-line arguments.
|
|
3
3
|
|
4
4
|
This module provides functionality to convert the internal DAG (Directed Acyclic Graph)
|
5
5
|
representation of an FFmpeg filter chain into the actual command-line arguments
|
6
|
-
that would be passed to FFmpeg. It
|
7
|
-
|
6
|
+
that would be passed to FFmpeg. It handles the following components:
|
7
|
+
|
8
|
+
1. Global Options: General FFmpeg settings like log level, overwrite flags
|
9
|
+
2. Input Files: Source media files with their specific options
|
10
|
+
3. Filter Graphs: Complex filter chains with proper stream labeling
|
11
|
+
4. Output Files: Destination files with codec and format settings
|
12
|
+
|
13
|
+
The module ensures proper ordering of arguments and handles stream mapping,
|
14
|
+
filter graph syntax, and escaping of special characters in FFmpeg commands.
|
8
15
|
"""
|
9
16
|
|
10
17
|
from __future__ import annotations
|
@@ -15,11 +22,29 @@ from ..exceptions import FFMpegValueError
|
|
15
22
|
from ..schema import Default
|
16
23
|
from ..utils.escaping import escape
|
17
24
|
from ..utils.lazy_eval.schema import LazyValue
|
25
|
+
from ..utils.run import command_line
|
18
26
|
from .context import DAGContext
|
19
27
|
from .validate import validate
|
20
28
|
|
21
29
|
|
22
|
-
def compile(stream: Stream, auto_fix: bool = True) ->
|
30
|
+
def compile(stream: Stream, auto_fix: bool = True) -> str:
|
31
|
+
"""
|
32
|
+
Compile a stream into a command-line string.
|
33
|
+
|
34
|
+
This function takes a Stream object representing an FFmpeg filter graph
|
35
|
+
and converts it into a command-line string that can be passed to FFmpeg.
|
36
|
+
|
37
|
+
Args:
|
38
|
+
stream: The Stream object to compile into a command-line string
|
39
|
+
auto_fix: Whether to automatically fix issues in the stream
|
40
|
+
|
41
|
+
Returns:
|
42
|
+
A command-line string that can be passed to FFmpeg
|
43
|
+
"""
|
44
|
+
return command_line(compile_as_list(stream, auto_fix))
|
45
|
+
|
46
|
+
|
47
|
+
def compile_as_list(stream: Stream, auto_fix: bool = True) -> list[str]:
|
23
48
|
"""
|
24
49
|
Compile a stream into a list of FFmpeg command-line arguments.
|
25
50
|
|
@@ -32,7 +57,8 @@ def compile(stream: Stream, auto_fix: bool = True) -> list[str]:
|
|
32
57
|
4. Output nodes (output files and their options)
|
33
58
|
|
34
59
|
The function validates the graph before compilation to ensure it's properly
|
35
|
-
formed. If auto_fix is enabled, it will attempt to fix common issues
|
60
|
+
formed. If auto_fix is enabled, it will attempt to fix common issues like
|
61
|
+
disconnected nodes or invalid stream mappings.
|
36
62
|
|
37
63
|
Args:
|
38
64
|
stream: The Stream object to compile into arguments
|
@@ -42,6 +68,9 @@ def compile(stream: Stream, auto_fix: bool = True) -> list[str]:
|
|
42
68
|
Returns:
|
43
69
|
A list of strings representing FFmpeg command-line arguments
|
44
70
|
|
71
|
+
Raises:
|
72
|
+
FFMpegValueError: If the stream contains invalid configurations that cannot be fixed
|
73
|
+
|
45
74
|
Example:
|
46
75
|
```python
|
47
76
|
# Create a simple video scaling filter graph
|
@@ -108,6 +137,7 @@ def get_stream_label(stream: Stream, context: DAGContext | None = None) -> str:
|
|
108
137
|
- Multi-output filters: "filterlabel#index"
|
109
138
|
|
110
139
|
Args:
|
140
|
+
stream: The stream to generate a label for
|
111
141
|
context: Optional DAG context for resolving node labels.
|
112
142
|
If not provided, a new context will be built.
|
113
143
|
|
@@ -156,9 +186,12 @@ def get_args_filter_node(node: FilterNode, context: DAGContext) -> list[str]:
|
|
156
186
|
FFmpeg's syntax where input labels are followed by the filter name
|
157
187
|
and parameters, and then output labels.
|
158
188
|
|
189
|
+
The filter string format is:
|
190
|
+
[input_label]filter_name=param1=value1:param2=value2[output_label]
|
191
|
+
|
159
192
|
Args:
|
160
|
-
|
161
|
-
|
193
|
+
node: The FilterNode to generate arguments for
|
194
|
+
context: DAG context for resolving stream labels
|
162
195
|
|
163
196
|
Returns:
|
164
197
|
A list of strings that, when joined, form the filter string
|
@@ -207,9 +240,12 @@ def get_args_input_node(node: InputNode, context: DAGContext) -> list[str]:
|
|
207
240
|
|
208
241
|
This method creates the command-line arguments needed to specify
|
209
242
|
this input file to FFmpeg, including any input-specific options.
|
243
|
+
Options are converted to FFmpeg's command-line format, with boolean
|
244
|
+
options using -option or -nooption syntax.
|
210
245
|
|
211
246
|
Args:
|
212
|
-
|
247
|
+
node: The InputNode to generate arguments for
|
248
|
+
context: DAG context (not used for input nodes)
|
213
249
|
|
214
250
|
Returns:
|
215
251
|
A list of strings representing FFmpeg command-line arguments
|
@@ -237,11 +273,12 @@ def get_args_output_node(node: OutputNode, context: DAGContext) -> list[str]:
|
|
237
273
|
|
238
274
|
This method creates the command-line arguments needed to specify
|
239
275
|
this output file to FFmpeg, including stream mapping and output-specific
|
240
|
-
options like codecs and formats.
|
276
|
+
options like codecs and formats. It handles both direct input streams
|
277
|
+
and filter output streams appropriately.
|
241
278
|
|
242
279
|
Args:
|
243
|
-
|
244
|
-
|
280
|
+
node: The OutputNode to generate arguments for
|
281
|
+
context: DAG context for resolving stream labels
|
245
282
|
|
246
283
|
Returns:
|
247
284
|
A list of strings representing FFmpeg command-line arguments
|
@@ -278,10 +315,12 @@ def get_args_global_node(node: GlobalNode, context: DAGContext) -> list[str]:
|
|
278
315
|
|
279
316
|
This method creates the command-line arguments needed to specify
|
280
317
|
global options to FFmpeg, such as -y for overwrite or -loglevel for
|
281
|
-
controlling log output.
|
318
|
+
controlling log output. Boolean options are converted to -option or
|
319
|
+
-nooption syntax.
|
282
320
|
|
283
321
|
Args:
|
284
|
-
|
322
|
+
node: The GlobalNode to generate arguments for
|
323
|
+
context: DAG context (not used for global options)
|
285
324
|
|
286
325
|
Returns:
|
287
326
|
A list of strings representing FFmpeg command-line arguments
|
@@ -304,7 +343,22 @@ def get_args_global_node(node: GlobalNode, context: DAGContext) -> list[str]:
|
|
304
343
|
|
305
344
|
def get_args(node: Node, context: DAGContext | None = None) -> list[str]:
|
306
345
|
"""
|
307
|
-
Get the arguments for a node.
|
346
|
+
Get the FFmpeg command-line arguments for a specific node.
|
347
|
+
|
348
|
+
This function dispatches to the appropriate argument generation function
|
349
|
+
based on the node type. It handles all node types in the FFmpeg DAG:
|
350
|
+
FilterNode, InputNode, OutputNode, and GlobalNode.
|
351
|
+
|
352
|
+
Args:
|
353
|
+
node: The node to generate arguments for
|
354
|
+
context: Optional DAG context for resolving stream labels.
|
355
|
+
If not provided, a new context will be built.
|
356
|
+
|
357
|
+
Returns:
|
358
|
+
A list of strings representing FFmpeg command-line arguments
|
359
|
+
|
360
|
+
Raises:
|
361
|
+
FFMpegValueError: If the node type is not recognized
|
308
362
|
"""
|
309
363
|
|
310
364
|
context = context or DAGContext.build(node)
|
@@ -330,9 +384,11 @@ def get_node_label(node: Node, context: DAGContext) -> str:
|
|
330
384
|
filter graph notation. The label format depends on the node type:
|
331
385
|
- Input nodes: sequential numbers (0, 1, 2...)
|
332
386
|
- Filter nodes: 's' prefix followed by a number (s0, s1, s2...)
|
387
|
+
- Output nodes: 'out'
|
333
388
|
|
334
389
|
Args:
|
335
|
-
node: The node to get the label for
|
390
|
+
node: The node to get the label for
|
391
|
+
context: DAG context containing node ID mappings
|
336
392
|
|
337
393
|
Returns:
|
338
394
|
The string label for the node
|
@@ -0,0 +1,38 @@
|
|
1
|
+
from ..common.serialize import dumps, loads
|
2
|
+
from ..dag.schema import Stream
|
3
|
+
from .validate import validate
|
4
|
+
|
5
|
+
|
6
|
+
def compile(stream: Stream, auto_fix: bool = True) -> str:
|
7
|
+
"""
|
8
|
+
Compile a stream into a JSON string.
|
9
|
+
|
10
|
+
This function takes a Stream object representing an FFmpeg filter graph
|
11
|
+
and converts it into a JSON string that can be passed to FFmpeg.
|
12
|
+
|
13
|
+
Args:
|
14
|
+
stream: The Stream object to compile into a JSON string
|
15
|
+
auto_fix: Whether to automatically fix issues in the stream
|
16
|
+
|
17
|
+
Returns:
|
18
|
+
A JSON string that can be passed to FFmpeg
|
19
|
+
"""
|
20
|
+
stream = validate(stream, auto_fix=auto_fix)
|
21
|
+
|
22
|
+
return dumps(stream)
|
23
|
+
|
24
|
+
|
25
|
+
def parse(json: str) -> Stream:
|
26
|
+
"""
|
27
|
+
Parse a JSON string into a Stream object.
|
28
|
+
|
29
|
+
This function takes a JSON string that can be passed to FFmpeg
|
30
|
+
and converts it into a Stream object.
|
31
|
+
|
32
|
+
Args:
|
33
|
+
json: The JSON string to parse into a Stream object
|
34
|
+
|
35
|
+
Returns:
|
36
|
+
A Stream object
|
37
|
+
"""
|
38
|
+
return loads(json)
|
@@ -191,7 +191,7 @@ def compile_fluent(code: list[str]) -> list[str]:
|
|
191
191
|
return [f"{k.strip()} = {v.strip()}" for k, v in buffer]
|
192
192
|
|
193
193
|
|
194
|
-
def compile(stream: Stream, auto_fix: bool = True, fluent: bool = True) ->
|
194
|
+
def compile(stream: Stream, auto_fix: bool = True, fluent: bool = True) -> str:
|
195
195
|
"""
|
196
196
|
Compile the python code.
|
197
197
|
|
@@ -295,10 +295,10 @@ def compile(stream: Stream, auto_fix: bool = True, fluent: bool = True) -> list[
|
|
295
295
|
if fluent:
|
296
296
|
code = compile_fluent(code)
|
297
297
|
|
298
|
-
return ["import ffmpeg", *code]
|
298
|
+
return "\n".join(["import ffmpeg", *code])
|
299
299
|
|
300
300
|
|
301
|
-
def parse(code:
|
301
|
+
def parse(code: str) -> Stream:
|
302
302
|
"""
|
303
303
|
Parse the python code.
|
304
304
|
|
@@ -312,7 +312,7 @@ def parse(code: list[str]) -> Stream:
|
|
312
312
|
The parsed stream.
|
313
313
|
"""
|
314
314
|
local_vars: dict[str, Any] = {}
|
315
|
-
exec(
|
315
|
+
exec(code, {}, local_vars)
|
316
316
|
result = local_vars["result"]
|
317
317
|
|
318
318
|
assert isinstance(result, Stream)
|
@@ -81,7 +81,7 @@ class GlobalRunable(GlobalArgs):
|
|
81
81
|
def compile(
|
82
82
|
self,
|
83
83
|
cmd: str | list[str] = "ffmpeg",
|
84
|
-
overwrite_output: bool = None,
|
84
|
+
overwrite_output: bool | None = None,
|
85
85
|
auto_fix: bool = True,
|
86
86
|
) -> list[str]:
|
87
87
|
"""
|
@@ -111,7 +111,7 @@ class GlobalRunable(GlobalArgs):
|
|
111
111
|
# Result: ['ffmpeg', '-i', 'input.mp4', 'output.mp4']
|
112
112
|
```
|
113
113
|
"""
|
114
|
-
from ...compile.compile_cli import
|
114
|
+
from ...compile.compile_cli import compile_as_list
|
115
115
|
|
116
116
|
if isinstance(cmd, str):
|
117
117
|
cmd = [cmd]
|
@@ -121,12 +121,12 @@ class GlobalRunable(GlobalArgs):
|
|
121
121
|
elif overwrite_output is False:
|
122
122
|
return self.global_args(n=True).compile(cmd, auto_fix=auto_fix)
|
123
123
|
|
124
|
-
return cmd +
|
124
|
+
return cmd + compile_as_list(self._global_node().stream(), auto_fix=auto_fix)
|
125
125
|
|
126
126
|
def compile_line(
|
127
127
|
self,
|
128
128
|
cmd: str | list[str] = "ffmpeg",
|
129
|
-
overwrite_output: bool = None,
|
129
|
+
overwrite_output: bool | None = None,
|
130
130
|
auto_fix: bool = True,
|
131
131
|
) -> str:
|
132
132
|
"""
|
@@ -165,7 +165,7 @@ class GlobalRunable(GlobalArgs):
|
|
165
165
|
pipe_stdout: bool = False,
|
166
166
|
pipe_stderr: bool = False,
|
167
167
|
quiet: bool = False,
|
168
|
-
overwrite_output: bool = None,
|
168
|
+
overwrite_output: bool | None = None,
|
169
169
|
auto_fix: bool = True,
|
170
170
|
) -> subprocess.Popen[bytes]:
|
171
171
|
"""
|
@@ -222,7 +222,7 @@ class GlobalRunable(GlobalArgs):
|
|
222
222
|
capture_stderr: bool = False,
|
223
223
|
input: bytes | None = None,
|
224
224
|
quiet: bool = False,
|
225
|
-
overwrite_output: bool = None,
|
225
|
+
overwrite_output: bool | None = None,
|
226
226
|
auto_fix: bool = True,
|
227
227
|
) -> tuple[bytes, bytes]:
|
228
228
|
"""
|
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/cache.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/common/schema.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/__init__.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/factory.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/io/_input.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/io/_output.py
RENAMED
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/nodes.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/schema.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/dag/utils.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/exceptions.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/filters.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/schema.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/sources.py
RENAMED
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/streams/audio.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/streams/av.py
RENAMED
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/streams/video.py
RENAMED
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/__init__.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/escaping.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/run.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/snapshot.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/typing.py
RENAMED
File without changes
|
{typed_ffmpeg_compatible-3.0.0 → typed_ffmpeg_compatible-3.0.0a0}/src/typed_ffmpeg/utils/view.py
RENAMED
File without changes
|