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.
Files changed (35) hide show
  1. typed_ffmpeg/__init__.py +24 -0
  2. typed_ffmpeg/base.py +87 -29
  3. typed_ffmpeg/common/schema.py +281 -3
  4. typed_ffmpeg/common/serialize.py +118 -21
  5. typed_ffmpeg/dag/__init__.py +13 -0
  6. typed_ffmpeg/dag/compile.py +39 -4
  7. typed_ffmpeg/dag/context.py +137 -29
  8. typed_ffmpeg/dag/factory.py +27 -0
  9. typed_ffmpeg/dag/global_runnable/global_args.py +11 -0
  10. typed_ffmpeg/dag/global_runnable/runnable.py +143 -34
  11. typed_ffmpeg/dag/io/_input.py +2 -1
  12. typed_ffmpeg/dag/io/_output.py +2 -1
  13. typed_ffmpeg/dag/nodes.py +402 -67
  14. typed_ffmpeg/dag/schema.py +3 -1
  15. typed_ffmpeg/dag/utils.py +29 -8
  16. typed_ffmpeg/dag/validate.py +83 -20
  17. typed_ffmpeg/exceptions.py +42 -9
  18. typed_ffmpeg/info.py +137 -16
  19. typed_ffmpeg/probe.py +31 -6
  20. typed_ffmpeg/schema.py +32 -5
  21. typed_ffmpeg/streams/channel_layout.py +13 -0
  22. typed_ffmpeg/utils/escaping.py +47 -7
  23. typed_ffmpeg/utils/forzendict.py +108 -0
  24. typed_ffmpeg/utils/lazy_eval/operator.py +43 -1
  25. typed_ffmpeg/utils/lazy_eval/schema.py +122 -6
  26. typed_ffmpeg/utils/run.py +44 -7
  27. typed_ffmpeg/utils/snapshot.py +36 -1
  28. typed_ffmpeg/utils/typing.py +29 -4
  29. typed_ffmpeg/utils/view.py +46 -4
  30. {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.6.4.dist-info}/METADATA +1 -1
  31. typed_ffmpeg_compatible-2.6.4.dist-info/RECORD +48 -0
  32. typed_ffmpeg_compatible-2.6.3.dist-info/RECORD +0 -47
  33. {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.6.4.dist-info}/LICENSE +0 -0
  34. {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.6.4.dist-info}/WHEEL +0 -0
  35. {typed_ffmpeg_compatible-2.6.3.dist-info → typed_ffmpeg_compatible-2.6.4.dist-info}/entry_points.txt +0 -0
@@ -1,3 +1,12 @@
1
+ """
2
+ Execution capabilities for FFmpeg filter graphs.
3
+
4
+ This module provides the GlobalRunable class, which extends GlobalArgs with
5
+ methods for executing FFmpeg commands. It enables compiling filter graphs
6
+ into command-line arguments and running FFmpeg processes both synchronously
7
+ and asynchronously.
8
+ """
9
+
1
10
  from __future__ import annotations
2
11
 
3
12
  import logging
@@ -15,24 +24,57 @@ logger = logging.getLogger(__name__)
15
24
 
16
25
 
17
26
  class GlobalRunable(GlobalArgs):
27
+ """
28
+ Base class that provides execution capabilities for FFmpeg filter graphs.
29
+
30
+ This class extends GlobalArgs with methods for compiling filter graphs into
31
+ FFmpeg command-line arguments and executing FFmpeg processes. It serves as
32
+ a mixin for stream classes that need to be executed as FFmpeg commands.
33
+ """
34
+
18
35
  def merge_outputs(self, *streams: OutputStream) -> GlobalStream:
19
36
  """
20
- Merge multiple output streams into one.
37
+ Merge multiple output streams into a single command.
38
+
39
+ This method allows combining multiple output files into a single FFmpeg
40
+ command, which is more efficient than running separate commands for each
41
+ output. It creates a GlobalNode that includes all the specified output
42
+ streams.
21
43
 
22
44
  Args:
23
- *streams: The output streams to merge.
45
+ *streams: Additional output streams to include in the same command
24
46
 
25
47
  Returns:
26
- The merged output stream.
48
+ A GlobalStream that represents the combined outputs
49
+
50
+ Example:
51
+ ```python
52
+ # Create two output files with one command
53
+ video = ffmpeg.input("input.mp4").video
54
+ output1 = video.output("output1.mp4")
55
+ output2 = video.output("output2.webm")
56
+ merged = output1.merge_outputs(output2)
57
+ merged.run() # Creates both output files with one FFmpeg command
58
+ ```
27
59
  """
28
60
  return self._global_node(*streams).stream()
29
61
 
30
62
  def overwrite_output(self) -> GlobalStream:
31
63
  """
32
- Overwrite output files without asking (ffmpeg `-y` option)
64
+ Set the FFmpeg command to overwrite output files without asking.
65
+
66
+ This method adds the `-y` option to the FFmpeg command, which causes
67
+ FFmpeg to overwrite output files without prompting for confirmation.
68
+ It's equivalent to calling `global_args(y=True)`.
33
69
 
34
70
  Returns:
35
- the output stream
71
+ A GlobalStream with the overwrite option enabled
72
+
73
+ Example:
74
+ ```python
75
+ # Overwrite output file if it already exists
76
+ ffmpeg.input("input.mp4").output("output.mp4").overwrite_output().run()
77
+ ```
36
78
  """
37
79
  return self._global_node(y=True).stream()
38
80
 
@@ -43,15 +85,31 @@ class GlobalRunable(GlobalArgs):
43
85
  auto_fix: bool = True,
44
86
  ) -> list[str]:
45
87
  """
46
- Build command-line for invoking ffmpeg.
88
+ Build command-line arguments for invoking FFmpeg.
89
+
90
+ This method converts the filter graph into a list of command-line
91
+ arguments that can be passed to subprocess functions or executed
92
+ directly. It handles the FFmpeg executable name, overwrite options,
93
+ and automatic fixing of the filter graph.
47
94
 
48
95
  Args:
49
- cmd: the command to invoke ffmpeg
50
- overwrite_output: whether to overwrite output files without asking
51
- auto_fix: whether to automatically fix the stream
96
+ cmd: The FFmpeg executable name or path, or a list containing
97
+ the executable and initial arguments
98
+ overwrite_output: If True, add the -y option to overwrite output files
99
+ If False, add the -n option to never overwrite
100
+ If None (default), use the current settings
101
+ auto_fix: Whether to automatically fix issues in the filter graph,
102
+ such as adding split filters for reused streams
52
103
 
53
104
  Returns:
54
- the command-line
105
+ A list of strings representing the complete FFmpeg command
106
+
107
+ Example:
108
+ ```python
109
+ # Get the command-line arguments for a filter graph
110
+ args = ffmpeg.input("input.mp4").output("output.mp4").compile()
111
+ # Result: ['ffmpeg', '-i', 'input.mp4', 'output.mp4']
112
+ ```
55
113
  """
56
114
  from ..compile import compile
57
115
 
@@ -72,15 +130,29 @@ class GlobalRunable(GlobalArgs):
72
130
  auto_fix: bool = True,
73
131
  ) -> str:
74
132
  """
75
- Build command-line for invoking ffmpeg.
133
+ Build a command-line string for invoking FFmpeg.
134
+
135
+ This method is similar to compile(), but returns a single string with
136
+ proper escaping instead of a list of arguments. This is useful for
137
+ logging or displaying the command to users.
76
138
 
77
139
  Args:
78
- cmd: the command to invoke ffmpeg
79
- overwrite_output: whether to overwrite output files without asking
80
- auto_fix: whether to automatically fix the stream
140
+ cmd: The FFmpeg executable name or path, or a list containing
141
+ the executable and initial arguments
142
+ overwrite_output: If True, add the -y option to overwrite output files
143
+ If False, add the -n option to never overwrite
144
+ If None (default), use the current settings
145
+ auto_fix: Whether to automatically fix issues in the filter graph
81
146
 
82
147
  Returns:
83
- the command-line
148
+ A string representing the complete FFmpeg command with proper escaping
149
+
150
+ Example:
151
+ ```python
152
+ # Get a command-line string for a filter graph
153
+ cmd_str = ffmpeg.input("input.mp4").output("output.mp4").compile_line()
154
+ # Result: 'ffmpeg -i input.mp4 output.mp4'
155
+ ```
84
156
  """
85
157
  return command_line(
86
158
  self.compile(cmd, overwrite_output=overwrite_output, auto_fix=auto_fix)
@@ -97,19 +169,34 @@ class GlobalRunable(GlobalArgs):
97
169
  auto_fix: bool = True,
98
170
  ) -> subprocess.Popen[bytes]:
99
171
  """
100
- Run ffmpeg asynchronously.
172
+ Run FFmpeg asynchronously as a subprocess.
173
+
174
+ This method executes the FFmpeg command in a separate process without
175
+ waiting for it to complete. This is useful for long-running operations
176
+ or when you need to interact with the process while it's running.
101
177
 
102
178
  Args:
103
- cmd: the command to invoke ffmpeg
104
- pipe_stdin: whether to pipe stdin
105
- pipe_stdout: whether to pipe stdout
106
- pipe_stderr: whether to pipe stderr
107
- quiet: whether to pipe stderr to stdout
108
- overwrite_output: whether to overwrite output files without asking
109
- auto_fix: whether to automatically fix the stream
179
+ cmd: The FFmpeg executable name or path, or a list containing
180
+ the executable and initial arguments
181
+ pipe_stdin: Whether to create a pipe for writing to the process's stdin
182
+ pipe_stdout: Whether to create a pipe for reading from the process's stdout
183
+ pipe_stderr: Whether to create a pipe for reading from the process's stderr
184
+ quiet: Whether to capture stderr (implies pipe_stderr=True)
185
+ overwrite_output: If True, add the -y option to overwrite output files
186
+ If False, add the -n option to never overwrite
187
+ If None (default), use the current settings
188
+ auto_fix: Whether to automatically fix issues in the filter graph
110
189
 
111
190
  Returns:
112
- the process
191
+ A subprocess.Popen object representing the running FFmpeg process
192
+
193
+ Example:
194
+ ```python
195
+ # Start FFmpeg process and interact with it
196
+ process = ffmpeg.input("input.mp4").output("output.mp4").run_async()
197
+ # Do something while FFmpeg is running
198
+ process.wait() # Wait for completion
199
+ ```
113
200
  """
114
201
 
115
202
  args = self.compile(cmd, overwrite_output=overwrite_output, auto_fix=auto_fix)
@@ -139,20 +226,42 @@ class GlobalRunable(GlobalArgs):
139
226
  auto_fix: bool = True,
140
227
  ) -> tuple[bytes, bytes]:
141
228
  """
142
- Run ffmpeg synchronously.
229
+ Run FFmpeg synchronously and wait for completion.
230
+
231
+ This method executes the FFmpeg command in a separate process and waits
232
+ for it to complete before returning. It's the most common way to run
233
+ FFmpeg commands when you just want to process media files.
143
234
 
144
235
  Args:
145
- cmd: the command to invoke ffmpeg
146
- capture_stdout: whether to capture stdout
147
- capture_stderr: whether to capture stderr
148
- input: the input
149
- quiet: whether to pipe stderr to stdout
150
- overwrite_output: whether to overwrite output files without asking
151
- auto_fix: whether to automatically fix the stream
236
+ cmd: The FFmpeg executable name or path, or a list containing
237
+ the executable and initial arguments
238
+ capture_stdout: Whether to capture and return the process's stdout
239
+ capture_stderr: Whether to capture and return the process's stderr
240
+ input: Optional bytes to write to the process's stdin
241
+ quiet: Whether to suppress output to the console
242
+ overwrite_output: If True, add the -y option to overwrite output files
243
+ If False, add the -n option to never overwrite
244
+ If None (default), use the current settings
245
+ auto_fix: Whether to automatically fix issues in the filter graph
152
246
 
153
247
  Returns:
154
- stdout: he stdout
155
- stderr: the stderr
248
+ A tuple of (stdout_bytes, stderr_bytes), which will be empty bytes
249
+ objects if the respective capture_* parameter is False
250
+
251
+ Raises:
252
+ FFMpegExecuteError: If the FFmpeg process returns a non-zero exit code
253
+
254
+ Example:
255
+ ```python
256
+ # Process a video file
257
+ stdout, stderr = ffmpeg.input("input.mp4").output("output.mp4").run()
258
+
259
+ # Capture FFmpeg's output
260
+ stdout, stderr = (
261
+ ffmpeg.input("input.mp4").output("output.mp4").run(capture_stderr=True)
262
+ )
263
+ print(stderr.decode()) # Print FFmpeg's progress information
264
+ ```
156
265
  """
157
266
 
158
267
  process = self.run_async(
@@ -6,6 +6,7 @@ from typing import Any
6
6
 
7
7
  from ...streams.av import AVStream
8
8
  from ...types import Boolean, Double, Float, Int, String, Time
9
+ from ...utils.forzendict import FrozenDict
9
10
  from ..nodes import InputNode
10
11
 
11
12
 
@@ -195,5 +196,5 @@ def input(
195
196
  }
196
197
 
197
198
  return InputNode(
198
- filename=str(filename), kwargs=tuple((options | (extra_options or {})).items())
199
+ filename=str(filename), kwargs=FrozenDict(options | (extra_options or {}))
199
200
  ).stream()
@@ -5,6 +5,7 @@ from pathlib import Path
5
5
  from typing import Any
6
6
 
7
7
  from ...types import Boolean, Float, Func, Int, Int64, String, Time
8
+ from ...utils.forzendict import FrozenDict
8
9
  from ..nodes import FilterableStream, OutputNode, OutputStream
9
10
 
10
11
 
@@ -318,5 +319,5 @@ def output(
318
319
  return OutputNode(
319
320
  inputs=streams,
320
321
  filename=str(filename),
321
- kwargs=tuple((options | (extra_options or {})).items()),
322
+ kwargs=FrozenDict(options | (extra_options or {})),
322
323
  ).stream()