ffmpeg-python-helper 2.0.0__tar.gz → 3.0.0__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ffmpeg-python-helper
3
- Version: 2.0.0
3
+ Version: 3.0.0
4
4
  Summary: A Python wrapper for FFMPEG that provides a simple, intuitive API for common video processing tasks including format conversion, GIF creation, and video trimming.
5
5
  Author: marjon
6
6
  Author-email: marjon <marjongodito@gmanmi.com>
@@ -16,7 +16,8 @@ A Python wrapper for FFMPEG that provides a simple, intuitive API for common vid
16
16
  - 🔧 **Easy FFMPEG Integration** - Automatically detects FFMPEG installation
17
17
  - 🎥 **Video Processing** - Reformat videos between formats
18
18
  - 🎞️ **GIF Creation** - Convert videos to optimized GIFs with customizable settings
19
- - 🧠 **In-Memory Processing** - Process video data directly from bytes without temporary files
19
+ - 🎵 **Audio Extraction** - Extract audio tracks from videos without re-encoding
20
+ - 🧠 **In-Memory Processing** - Process video/audio data directly from bytes without temporary files
20
21
  - ✂️ **Video Trimming** - Trim videos with precise start time and duration control
21
22
  - 🐍 **Pythonic API** - Clean, object-oriented interface with proper error handling
22
23
  - 📁 **File Validation** - Automatic input file existence checking
@@ -57,12 +58,13 @@ output = ffmpeg.reformat("input.mp4", "output.avi")
57
58
  print(output.decode())
58
59
 
59
60
  # Create a GIF from video
60
- output = ffmpeg.gif("video.mp4", "animation.gif", fps=15, scale=480)
61
- print(output.decode())
61
+ ffmpeg.gif("video.mp4", "animation.gif", fps=15, scale=480)
62
62
 
63
63
  # Trim a video
64
- output = ffmpeg.trim("video.mp4", "short_clip.mp4", start=10.5, duration=5.0)
65
- print(output.decode())
64
+ ffmpeg.trim("video.mp4", "short_clip.mp4", start=10.5, duration=5.0)
65
+
66
+ # Extract audio from video
67
+ ffmpeg.extract_audio("video.mp4", "audio.m4a")
66
68
 
67
69
  # Create GIF from in-memory video data
68
70
  with open("video.mp4", "rb") as f:
@@ -70,6 +72,16 @@ with open("video.mp4", "rb") as f:
70
72
  gif_data = ffmpeg.gifs(video_data, fps=15, scale=480)
71
73
  with open("memory.gif", "wb") as f:
72
74
  f.write(gif_data)
75
+
76
+ # Trim video in memory
77
+ trimmed_data = ffmpeg.trims(video_data, start=0, duration=30)
78
+ with open("trimmed.mp4", "wb") as f:
79
+ f.write(trimmed_data)
80
+
81
+ # Extract audio in memory
82
+ audio_data = ffmpeg.extract_audios(video_data, output_format="m4a")
83
+ with open("audio.m4a", "wb") as f:
84
+ f.write(audio_data)
73
85
  ```
74
86
 
75
87
  ## API Reference
@@ -7,7 +7,8 @@ A Python wrapper for FFMPEG that provides a simple, intuitive API for common vid
7
7
  - 🔧 **Easy FFMPEG Integration** - Automatically detects FFMPEG installation
8
8
  - 🎥 **Video Processing** - Reformat videos between formats
9
9
  - 🎞️ **GIF Creation** - Convert videos to optimized GIFs with customizable settings
10
- - 🧠 **In-Memory Processing** - Process video data directly from bytes without temporary files
10
+ - 🎵 **Audio Extraction** - Extract audio tracks from videos without re-encoding
11
+ - 🧠 **In-Memory Processing** - Process video/audio data directly from bytes without temporary files
11
12
  - ✂️ **Video Trimming** - Trim videos with precise start time and duration control
12
13
  - 🐍 **Pythonic API** - Clean, object-oriented interface with proper error handling
13
14
  - 📁 **File Validation** - Automatic input file existence checking
@@ -48,12 +49,13 @@ output = ffmpeg.reformat("input.mp4", "output.avi")
48
49
  print(output.decode())
49
50
 
50
51
  # Create a GIF from video
51
- output = ffmpeg.gif("video.mp4", "animation.gif", fps=15, scale=480)
52
- print(output.decode())
52
+ ffmpeg.gif("video.mp4", "animation.gif", fps=15, scale=480)
53
53
 
54
54
  # Trim a video
55
- output = ffmpeg.trim("video.mp4", "short_clip.mp4", start=10.5, duration=5.0)
56
- print(output.decode())
55
+ ffmpeg.trim("video.mp4", "short_clip.mp4", start=10.5, duration=5.0)
56
+
57
+ # Extract audio from video
58
+ ffmpeg.extract_audio("video.mp4", "audio.m4a")
57
59
 
58
60
  # Create GIF from in-memory video data
59
61
  with open("video.mp4", "rb") as f:
@@ -61,6 +63,16 @@ with open("video.mp4", "rb") as f:
61
63
  gif_data = ffmpeg.gifs(video_data, fps=15, scale=480)
62
64
  with open("memory.gif", "wb") as f:
63
65
  f.write(gif_data)
66
+
67
+ # Trim video in memory
68
+ trimmed_data = ffmpeg.trims(video_data, start=0, duration=30)
69
+ with open("trimmed.mp4", "wb") as f:
70
+ f.write(trimmed_data)
71
+
72
+ # Extract audio in memory
73
+ audio_data = ffmpeg.extract_audios(video_data, output_format="m4a")
74
+ with open("audio.m4a", "wb") as f:
75
+ f.write(audio_data)
64
76
  ```
65
77
 
66
78
  ## API Reference
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ffmpeg-python-helper"
3
- version = "2.0.0"
3
+ version = "3.0.0"
4
4
  description = "A Python wrapper for FFMPEG that provides a simple, intuitive API for common video processing tasks including format conversion, GIF creation, and video trimming."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.14"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ffmpeg-python-helper"
3
- version = "2.0.0"
3
+ version = "3.0.0"
4
4
  description = "A Python wrapper for FFMPEG that provides a simple, intuitive API for common video processing tasks including format conversion, GIF creation, and video trimming."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -2,29 +2,45 @@
2
2
  FFMPEG Python Helper - A Python wrapper for FFMPEG video processing.
3
3
 
4
4
  This package provides a simple, intuitive API for common video processing tasks
5
- including format conversion, GIF creation, video trimming, and in-memory processing.
5
+ including format conversion, GIF creation, video trimming, audio extraction,
6
+ in-memory processing, and data pipeline utilities.
6
7
 
7
8
  Example:
8
- >>> from ffmpeg_python_helper import FFMPEG
9
+ >>> from ffmpeg_python_helper import FFMPEG, Pipe
9
10
  >>> ffmpeg = FFMPEG()
10
11
  >>> ffmpeg.reformat("input.mp4", "output.avi")
11
12
  >>> ffmpeg.gif("video.mp4", "animation.gif", fps=15, scale=480)
12
13
  >>> ffmpeg.trim("video.mp4", "short_clip.mp4", start=10.5, duration=5.0)
14
+ >>> ffmpeg.extract_audio("video.mp4", "audio.m4a")
13
15
  >>>
14
16
  >>> # In-memory processing
15
17
  >>> with open("video.mp4", "rb") as f:
16
18
  ... video_data = f.read()
17
19
  >>> gif_data = ffmpeg.gifs(video_data, fps=15, scale=480)
20
+ >>> trimmed_data = ffmpeg.trims(video_data, start=0, duration=30)
21
+ >>> audio_data = ffmpeg.extract_audios(video_data, output_format="m4a")
22
+ >>>
23
+ >>> # Pipeline processing
24
+ >>> def process_video(data: bytes) -> bytes:
25
+ ... return ffmpeg.trims(data, start=0, duration=30)
26
+ >>>
27
+ >>> def convert_to_gif(data: bytes) -> bytes:
28
+ ... return ffmpeg.gifs(data, fps=15, scale=480)
29
+ >>>
30
+ >>> processed_data = Pipe.pipe_bytes(video_data, process_video, convert_to_gif)
18
31
 
19
32
  For detailed API documentation, see:
20
33
  - FFMPEG class documentation
34
+ - Pipe class documentation
21
35
  - README.md for usage examples and tutorials
22
36
  """
23
37
 
24
38
  from .ffmpeg_api import FFMPEG
39
+ from .pipe_helper import Pipe
25
40
 
26
41
  __all__ = [
27
- 'FFMPEG'
42
+ 'FFMPEG',
43
+ 'Pipe'
28
44
  ]
29
45
 
30
46
  __version__ = "0.1.0"
@@ -8,8 +8,9 @@ class FFMPEG:
8
8
  common video processing tasks.
9
9
 
10
10
  This class automatically detects FFMPEG installation in the system PATH
11
- and provides methods for video conversion, GIF creation, and video trimming.
12
- It supports both file-based operations and in-memory data processing.
11
+ and provides methods for video conversion, GIF creation, video trimming,
12
+ and audio extraction. It supports both file-based operations and
13
+ in-memory data processing.
13
14
 
14
15
  Example:
15
16
  >>> from ffmpeg_python_helper import FFMPEG
@@ -17,11 +18,14 @@ class FFMPEG:
17
18
  >>> ffmpeg.reformat("input.mp4", "output.avi")
18
19
  >>> ffmpeg.gif("video.mp4", "animation.gif", fps=15, scale=480)
19
20
  >>> ffmpeg.trim("video.mp4", "short_clip.mp4", start=10.5, duration=5.0)
21
+ >>> ffmpeg.extract_audio("video.mp4", "audio.m4a")
20
22
  >>>
21
23
  >>> # In-memory processing
22
24
  >>> with open("video.mp4", "rb") as f:
23
25
  ... video_data = f.read()
24
26
  >>> gif_data = ffmpeg.gifs(video_data, fps=15, scale=480)
27
+ >>> trimmed_data = ffmpeg.trims(video_data, start=0, duration=30)
28
+ >>> audio_data = ffmpeg.extract_audios(video_data, output_format="m4a")
25
29
 
26
30
  Attributes:
27
31
  executable (str): The path to the FFMPEG executable found in the system PATH.
@@ -165,7 +169,7 @@ in your system PATH.
165
169
  return stderr
166
170
 
167
171
  def gifs(self,
168
- input_byte: bytes,
172
+ input_bytes: bytes,
169
173
  fps: int = 10,
170
174
  scale: int = 320) -> bytes:
171
175
  """
@@ -217,7 +221,7 @@ in your system PATH.
217
221
  "-vf", filter_graph,
218
222
  "-f", "gif",
219
223
  "pipe:1",
220
- input_data=input_byte
224
+ input_data=input_bytes
221
225
  )
222
226
 
223
227
  return stdout
@@ -227,7 +231,7 @@ in your system PATH.
227
231
  output_file: str,
228
232
  fps: int = 10,
229
233
  scale: int = 320
230
- ) -> bytes:
234
+ ) -> None:
231
235
  """
232
236
  Convert a video file to an optimized GIF.
233
237
 
@@ -241,27 +245,21 @@ in your system PATH.
241
245
  scale: Width of the GIF in pixels. Height is auto-scaled
242
246
  to maintain aspect ratio. Defaults to 320.
243
247
 
244
- Returns:
245
- bytes: FFMPEG output (stdout or stderr) as bytes.
246
-
247
248
  Raises:
248
249
  FileNotFoundError: If input file doesn't exist.
249
250
  RuntimeError: If GIF file was not created successfully.
250
251
 
251
252
  Example:
252
253
  >>> # Create a standard GIF
253
- >>> output = ffmpeg.gif("video.mp4", "output.gif")
254
- >>> print(output.decode())
254
+ >>> ffmpeg.gif("video.mp4", "output.gif")
255
255
 
256
256
  >>> # Create a higher quality GIF with custom settings
257
- >>> output = ffmpeg.gif("video.mp4", "output.gif",
258
- ... fps=15, scale=640)
259
- >>> print(output.decode())
257
+ >>> ffmpeg.gif("video.mp4", "output.gif",
258
+ ... fps=15, scale=640)
260
259
 
261
260
  >>> # Create a small thumbnail GIF
262
- >>> output = ffmpeg.gif("video.mp4", "thumbnail.gif",
263
- ... fps=5, scale=160)
264
- >>> print(output.decode())
261
+ >>> ffmpeg.gif("video.mp4", "thumbnail.gif",
262
+ ... fps=5, scale=160)
265
263
  """
266
264
  input_path = Path(input_file)
267
265
  output_path = Path(output_file)
@@ -279,7 +277,7 @@ in your system PATH.
279
277
  "[s1][p]paletteuse"
280
278
  )
281
279
 
282
- stdout, stderr = self.execute(
280
+ self.execute(
283
281
  "-y",
284
282
  "-i", str(input_path),
285
283
  "-vf", filter_graph,
@@ -291,18 +289,13 @@ in your system PATH.
291
289
  f"GIF was not created: {output_file}"
292
290
  )
293
291
 
294
- if stderr:
295
- return stderr
296
-
297
- return stdout
298
-
299
292
  def trim(
300
293
  self,
301
294
  input_file: str,
302
295
  output_file: str,
303
296
  start: float = 0,
304
297
  duration: float | None = None,
305
- ) -> bytes:
298
+ ) -> None:
306
299
  """
307
300
  Trim a video file.
308
301
 
@@ -316,9 +309,6 @@ in your system PATH.
316
309
  duration: Duration in seconds, or None for remaining video.
317
310
  Defaults to None.
318
311
 
319
- Returns:
320
- bytes: FFMPEG output (stdout or stderr) as bytes.
321
-
322
312
  Raises:
323
313
  FileNotFoundError: If input file doesn't exist.
324
314
  ValueError: If start is negative or duration is non-positive.
@@ -326,24 +316,20 @@ in your system PATH.
326
316
 
327
317
  Example:
328
318
  >>> # Trim from 5 seconds to 10 seconds (5-second clip)
329
- >>> output = ffmpeg.trim("video.mp4", "clip.mp4",
330
- ... start=5, duration=5)
331
- >>> print(output.decode())
319
+ >>> ffmpeg.trim("video.mp4", "clip.mp4",
320
+ ... start=5, duration=5)
332
321
 
333
322
  >>> # Trim from 10 seconds to the end of video
334
- >>> output = ffmpeg.trim("video.mp4", "ending.mp4",
335
- ... start=10)
336
- >>> print(output.decode())
323
+ >>> ffmpeg.trim("video.mp4", "ending.mp4",
324
+ ... start=10)
337
325
 
338
326
  >>> # Trim first 30 seconds of video
339
- >>> output = ffmpeg.trim("video.mp4", "intro.mp4",
340
- ... start=0, duration=30)
341
- >>> print(output.decode())
327
+ >>> ffmpeg.trim("video.mp4", "intro.mp4",
328
+ ... start=0, duration=30)
342
329
 
343
330
  >>> # Trim with floating point precision
344
- >>> output = ffmpeg.trim("video.mp4", "precise.mp4",
345
- ... start=2.5, duration=3.75)
346
- >>> print(output.decode())
331
+ >>> ffmpeg.trim("video.mp4", "precise.mp4",
332
+ ... start=2.5, duration=3.75)
347
333
  """
348
334
  input_path = Path(input_file)
349
335
  output_path = Path(output_file)
@@ -377,4 +363,164 @@ in your system PATH.
377
363
  f"Trimmed video was not created: {output_file}"
378
364
  )
379
365
 
380
- return stdout if stdout else stderr
366
+ def trims(self, input_bytes: bytes,
367
+ start: float = 0,
368
+ duration: float | None = None,
369
+ format_type: str = "mp4") -> bytes:
370
+ """
371
+ Trim video data from bytes (in-memory processing).
372
+
373
+ Extracts a segment from in-memory video data starting at a specified time
374
+ and optionally ending after a specified duration. This method is useful
375
+ when you have video data in memory and want to avoid writing temporary files.
376
+
377
+ Note: For MP4 format, this method uses libx264 video codec and AAC audio codec
378
+ with fragmented MP4 output for better streaming compatibility.
379
+
380
+ Args:
381
+ input_bytes: Video data as bytes to trim.
382
+ start: Start time in seconds. Defaults to 0.
383
+ duration: Duration in seconds, or None for remaining video.
384
+ Defaults to None.
385
+ format_type: Output format (e.g., 'mp4', 'avi', 'mov'). Defaults to 'mp4'.
386
+
387
+ Returns:
388
+ bytes: The trimmed video data as bytes.
389
+
390
+ Raises:
391
+ RuntimeError: If video trimming fails.
392
+
393
+ Example:
394
+ >>> # Read video data from a file
395
+ >>> with open("video.mp4", "rb") as f:
396
+ ... video_data = f.read()
397
+ >>>
398
+ >>> # Trim first 30 seconds in memory
399
+ >>> trimmed_data = ffmpeg.trims(video_data, start=0, duration=30)
400
+ >>>
401
+ >>> # Save the trimmed video
402
+ >>> with open("intro.mp4", "wb") as f:
403
+ ... f.write(trimmed_data)
404
+ >>>
405
+ >>> # Trim with different format
406
+ >>> webm_data = ffmpeg.trims(video_data, start=10, duration=5, format_type="webm")
407
+ >>> with open("clip.webm", "wb") as f:
408
+ ... f.write(webm_data)
409
+ >>>
410
+ >>> # Trim with specific codec settings
411
+ >>> # For non-MP4 formats, FFMPEG will use default codecs
412
+ >>> avi_data = ffmpeg.trims(video_data, start=5, duration=10, format_type="avi")
413
+ """
414
+ args = [
415
+ "-y",
416
+ "-i", "pipe:0",
417
+ "-ss", str(start)
418
+ ]
419
+
420
+ if duration is not None:
421
+ args.extend(["-t", str(duration)])
422
+
423
+ if format_type == 'mp4':
424
+ args.extend([
425
+ "-c:v", "libx264",
426
+ "-pix_fmt", "yuv420p",
427
+ "-c:a", "aac",
428
+ "-movflags", "frag_keyframe+empty_moov"
429
+ ])
430
+
431
+ args.extend([
432
+ "-f", format_type,
433
+ "pipe:1"
434
+ ])
435
+
436
+ stdout, stderr = self.execute(*args, input_data=input_bytes)
437
+
438
+ return stdout
439
+
440
+ def extract_audio(self, input_file: str, output_file: str) -> None:
441
+ """
442
+ Extract audio from a video file.
443
+
444
+ Extracts the audio track from a video file without re-encoding,
445
+ preserving the original audio quality. The output file extension
446
+ should match the audio codec (e.g., .m4a for AAC, .mp3 for MP3,
447
+ .ogg for Vorbis).
448
+
449
+ Args:
450
+ input_file: Path to the input video file.
451
+ output_file: Path for the output audio file.
452
+
453
+ Raises:
454
+ FileNotFoundError: If input file doesn't exist.
455
+ RuntimeError: If audio extraction fails.
456
+
457
+ Example:
458
+ >>> # Extract audio from MP4 video
459
+ >>> ffmpeg.extract_audio("video.mp4", "audio.m4a")
460
+ >>>
461
+ >>> # Extract audio and convert to MP3
462
+ >>> ffmpeg.execute("-i", "video.mp4", "-q:a", "0", "-map", "a", "audio.mp3")
463
+ >>>
464
+ >>> # Extract audio from multiple formats
465
+ >>> ffmpeg.extract_audio("movie.mkv", "audio.m4a")
466
+ >>> ffmpeg.extract_audio("clip.avi", "audio.mp3")
467
+ """
468
+ input_path = Path(input_file)
469
+ output_path = Path(output_file)
470
+
471
+ if not input_path.exists():
472
+ raise FileNotFoundError(
473
+ f"Input file {input_file} was not found."
474
+ )
475
+
476
+ self.execute(
477
+ "-i", str(input_path), # Specifies the input video file.
478
+ "-vn", # Disables the video stream (drops the visual data).
479
+ "-c:a", "copy", # Copies the audio track as-is without re-encoding.
480
+ str(output_path) # Output file. Extension should match audio codec.
481
+ )
482
+
483
+ def extract_audios(self, input_bytes: bytes, output_format: str = "m4a") -> bytes:
484
+ """
485
+ Extract audio from video data (in-memory processing).
486
+
487
+ Extracts the audio track from in-memory video data without re-encoding,
488
+ preserving the original audio quality. This method is useful when you
489
+ have video data in memory and want to avoid writing temporary files.
490
+
491
+ Args:
492
+ input_bytes: Video data as bytes to extract audio from.
493
+ output_format: Audio output format (e.g., 'm4a', 'mp3', 'ogg', 'wav').
494
+ Defaults to 'm4a'.
495
+
496
+ Returns:
497
+ bytes: The extracted audio data as bytes.
498
+
499
+ Raises:
500
+ RuntimeError: If audio extraction fails.
501
+
502
+ Example:
503
+ >>> # Read video data from a file
504
+ >>> with open("video.mp4", "rb") as f:
505
+ ... video_data = f.read()
506
+ >>>
507
+ >>> # Extract audio in memory
508
+ >>> audio_data = ffmpeg.extract_audios(video_data, output_format="m4a")
509
+ >>>
510
+ >>> # Save the extracted audio
511
+ >>> with open("audio.m4a", "wb") as f:
512
+ ... f.write(audio_data)
513
+ >>>
514
+ >>> # Extract audio in different formats
515
+ >>> mp3_data = ffmpeg.extract_audios(video_data, output_format="mp3")
516
+ >>> ogg_data = ffmpeg.extract_audios(video_data, output_format="ogg")
517
+ """
518
+ args = [
519
+ "-i", "pipe:0",
520
+ "-vn",
521
+ "-c:a", "copy",
522
+ "-f", output_format,
523
+ "pipe:1"
524
+ ]
525
+
526
+ return self.execute(*args, input_data=input_bytes)[0]
@@ -0,0 +1,114 @@
1
+ from typing import Callable
2
+
3
+
4
+ class Pipe:
5
+ """
6
+ A utility class for piping bytes through multiple processing functions.
7
+
8
+ This class provides a convenient way to chain multiple byte-processing
9
+ operations together, creating a pipeline that transforms data step by step.
10
+
11
+ Example:
12
+ >>> from ffmpeg_python_helper import FFMPEG, Pipe
13
+ >>> ffmpeg = FFMPEG()
14
+ >>>
15
+ >>> # Define processing functions
16
+ >>> def trim_first_30s(data: bytes) -> bytes:
17
+ ... return ffmpeg.trims(data, start=0, duration=30)
18
+ >>>
19
+ >>> def convert_to_gif(data: bytes) -> bytes:
20
+ ... return ffmpeg.gifs(data, fps=15, scale=480)
21
+ >>>
22
+ >>> def extract_audio(data: bytes) -> bytes:
23
+ ... return ffmpeg.extract_audios(data, output_format="m4a")
24
+ >>>
25
+ >>> # Read video data
26
+ >>> with open("video.mp4", "rb") as f:
27
+ ... video_data = f.read()
28
+ >>>
29
+ >>> # Create a processing pipeline
30
+ >>> # Trim → Convert to GIF → Extract audio
31
+ >>> result = Pipe.pipe_bytes(
32
+ ... video_data,
33
+ ... trim_first_30s,
34
+ ... convert_to_gif,
35
+ ... extract_audio
36
+ ... )
37
+ >>>
38
+ >>> # Save the final result (audio from trimmed GIF-converted video)
39
+ >>> with open("processed_audio.m4a", "wb") as f:
40
+ ... f.write(result)
41
+ """
42
+
43
+ @staticmethod
44
+ def pipe_bytes(initial_value: bytes, *fn: Callable[[bytes], bytes]) -> bytes:
45
+ """
46
+ Pipe bytes through multiple processing functions.
47
+
48
+ This method takes an initial bytes value and passes it through
49
+ a series of functions, using the output of each function as the
50
+ input to the next function in the chain.
51
+
52
+ Args:
53
+ initial_value: The initial bytes to start the pipeline with.
54
+ *fn: One or more callable functions that take bytes as input
55
+ and return bytes as output. Functions are applied in
56
+ the order they are provided.
57
+
58
+ Returns:
59
+ bytes: The final result after passing through all functions.
60
+
61
+ Raises:
62
+ TypeError: If any function is not callable or doesn't accept bytes.
63
+ RuntimeError: If any function in the pipeline fails.
64
+
65
+ Example:
66
+ >>> # Simple pipeline: read, process, save
67
+ >>> def add_header(data: bytes) -> bytes:
68
+ ... return b"HEADER" + data
69
+ >>>
70
+ >>> def add_footer(data: bytes) -> bytes:
71
+ ... return data + b"FOOTER"
72
+ >>>
73
+ >>> def uppercase_data(data: bytes) -> bytes:
74
+ ... return data.upper()
75
+ >>>
76
+ >>> # Create pipeline
77
+ >>> result = Pipe.pipe_bytes(
78
+ ... b"hello world",
79
+ ... add_header,
80
+ ... uppercase_data,
81
+ ... add_footer
82
+ ... )
83
+ >>>
84
+ >>> print(result)
85
+ b'HEADERHELLO WORLD FOOTER'
86
+
87
+ >>> # FFMPEG processing pipeline
88
+ >>> from ffmpeg_python_helper import FFMPEG
89
+ >>> ffmpeg = FFMPEG()
90
+ >>>
91
+ >>> def trim_video(data: bytes) -> bytes:
92
+ ... return ffmpeg.trims(data, start=10, duration=5)
93
+ >>>
94
+ >>> def convert_to_webm(data: bytes) -> bytes:
95
+ ... return ffmpeg.trims(data, format_type="webm") # Re-encode as webm
96
+ >>>
97
+ >>> # Process video through pipeline
98
+ >>> with open("input.mp4", "rb") as f:
99
+ ... video_data = f.read()
100
+ >>>
101
+ >>> processed_data = Pipe.pipe_bytes(
102
+ ... video_data,
103
+ ... trim_video,
104
+ ... convert_to_webm
105
+ ... )
106
+ >>>
107
+ >>> with open("output.webm", "wb") as f:
108
+ ... f.write(processed_data)
109
+ """
110
+ current: bytes = initial_value
111
+ for callable in fn:
112
+ current = callable(current)
113
+
114
+ return current