ffmpeg-python-helper 3.0.0__py3-none-any.whl → 3.2.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.
- ffmpeg_python_helper/__init__.py +3 -1
- ffmpeg_python_helper/ffmpeg_api.py +61 -4
- ffmpeg_python_helper/ffprobe_api.py +169 -0
- {ffmpeg_python_helper-3.0.0.dist-info → ffmpeg_python_helper-3.2.0.dist-info}/METADATA +163 -2
- ffmpeg_python_helper-3.2.0.dist-info/RECORD +8 -0
- ffmpeg_python_helper-3.0.0.dist-info/RECORD +0 -7
- {ffmpeg_python_helper-3.0.0.dist-info → ffmpeg_python_helper-3.2.0.dist-info}/WHEEL +0 -0
- {ffmpeg_python_helper-3.0.0.dist-info → ffmpeg_python_helper-3.2.0.dist-info}/entry_points.txt +0 -0
ffmpeg_python_helper/__init__.py
CHANGED
|
@@ -366,7 +366,10 @@ in your system PATH.
|
|
|
366
366
|
def trims(self, input_bytes: bytes,
|
|
367
367
|
start: float = 0,
|
|
368
368
|
duration: float | None = None,
|
|
369
|
-
format_type: str = "mp4"
|
|
369
|
+
format_type: str = "mp4",
|
|
370
|
+
v_encoder : str = "libx264",
|
|
371
|
+
a_encoder : str = "aac"
|
|
372
|
+
) -> bytes:
|
|
370
373
|
"""
|
|
371
374
|
Trim video data from bytes (in-memory processing).
|
|
372
375
|
|
|
@@ -422,9 +425,9 @@ in your system PATH.
|
|
|
422
425
|
|
|
423
426
|
if format_type == 'mp4':
|
|
424
427
|
args.extend([
|
|
425
|
-
"-c:v",
|
|
428
|
+
"-c:v", v_encoder,
|
|
426
429
|
"-pix_fmt", "yuv420p",
|
|
427
|
-
"-c:a",
|
|
430
|
+
"-c:a", a_encoder,
|
|
428
431
|
"-movflags", "frag_keyframe+empty_moov"
|
|
429
432
|
])
|
|
430
433
|
|
|
@@ -523,4 +526,58 @@ in your system PATH.
|
|
|
523
526
|
"pipe:1"
|
|
524
527
|
]
|
|
525
528
|
|
|
526
|
-
return self.execute(*args, input_data=input_bytes)[0]
|
|
529
|
+
return self.execute(*args, input_data=input_bytes)[0]
|
|
530
|
+
|
|
531
|
+
def compress_file(self,
|
|
532
|
+
input_file : str,
|
|
533
|
+
output_file : str,
|
|
534
|
+
crf: int = 28,
|
|
535
|
+
v_encoder : str = "libx264",
|
|
536
|
+
a_encoder : str = "aac" ,
|
|
537
|
+
px_format : str = "yuv420p"):
|
|
538
|
+
|
|
539
|
+
args = [
|
|
540
|
+
"-i", input_file,
|
|
541
|
+
"-c:v", v_encoder,
|
|
542
|
+
"-crf", str(crf),
|
|
543
|
+
"-pix_fmt", px_format,
|
|
544
|
+
"-c:a", a_encoder,
|
|
545
|
+
"-movflags", "faststart",
|
|
546
|
+
output_file,
|
|
547
|
+
]
|
|
548
|
+
|
|
549
|
+
self.execute(*args)
|
|
550
|
+
|
|
551
|
+
def compress_byte(self,
|
|
552
|
+
input_data : bytes,
|
|
553
|
+
crf: int = 28,
|
|
554
|
+
v_encoder : str = "libx264",
|
|
555
|
+
a_encoder : str = "aac" ,
|
|
556
|
+
px_format : str = "yuv420p"
|
|
557
|
+
):
|
|
558
|
+
args = [
|
|
559
|
+
"-i", "pipe:0",
|
|
560
|
+
"-c:v", v_encoder,
|
|
561
|
+
"-crf", str(crf),
|
|
562
|
+
"-pix_fmt", px_format,
|
|
563
|
+
"-c:a", a_encoder,
|
|
564
|
+
"-movflags", "frag_keyframe+empty_moov",
|
|
565
|
+
"-f", "mp4",
|
|
566
|
+
"pipe:1"
|
|
567
|
+
]
|
|
568
|
+
|
|
569
|
+
return self.execute(*args, input_data=input_data)[0]
|
|
570
|
+
|
|
571
|
+
def verify(self, input_file : str) -> tuple[bool, str]:
|
|
572
|
+
args = [
|
|
573
|
+
"-v", "error",
|
|
574
|
+
"-i", input_file,
|
|
575
|
+
"-f", "null",
|
|
576
|
+
"-"
|
|
577
|
+
]
|
|
578
|
+
|
|
579
|
+
try:
|
|
580
|
+
self.execute(*args)
|
|
581
|
+
return True, ""
|
|
582
|
+
except RuntimeError as e:
|
|
583
|
+
return False, str(e)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FFProbe:
|
|
6
|
+
"""
|
|
7
|
+
A Python wrapper for FFProbe (FFMPEG's multimedia stream analyzer) that provides
|
|
8
|
+
video metadata analysis capabilities.
|
|
9
|
+
|
|
10
|
+
This class automatically detects FFProbe installation in the system PATH
|
|
11
|
+
and provides methods for extracting video metadata, analyzing video properties,
|
|
12
|
+
and checking video characteristics.
|
|
13
|
+
|
|
14
|
+
Example:
|
|
15
|
+
>>> from ffmpeg_python_helper import FFProbe
|
|
16
|
+
>>> ffprobe = FFProbe()
|
|
17
|
+
>>> # Check if video is short enough for social media
|
|
18
|
+
>>> if ffprobe.is_max_length("video.mp4", max_length=5.0):
|
|
19
|
+
... print("Video is perfect for Instagram Reels!")
|
|
20
|
+
>>> # Get video metadata
|
|
21
|
+
>>> import json
|
|
22
|
+
>>> stdout, stderr = ffprobe.execute("-v", "quiet", "-print_format", "json",
|
|
23
|
+
... "-show_format", "-show_streams", "video.mp4")
|
|
24
|
+
>>> metadata = json.loads(stdout.decode())
|
|
25
|
+
>>> print(f"Video duration: {metadata['format']['duration']} seconds")
|
|
26
|
+
>>> print(f"Video dimensions: {metadata['streams'][0]['width']}x{metadata['streams'][0]['height']}")
|
|
27
|
+
|
|
28
|
+
Attributes:
|
|
29
|
+
executable (str): The path to the FFProbe executable found in the system PATH.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self) -> None:
|
|
33
|
+
"""
|
|
34
|
+
Initialize a new FFProbe instance.
|
|
35
|
+
|
|
36
|
+
Automatically searches for FFProbe in the system PATH.
|
|
37
|
+
|
|
38
|
+
Raises:
|
|
39
|
+
FileNotFoundError: If FFProbe is not found in the system PATH.
|
|
40
|
+
|
|
41
|
+
Example:
|
|
42
|
+
>>> try:
|
|
43
|
+
... ffprobe = FFProbe()
|
|
44
|
+
... print(f"FFProbe found at: {ffprobe.executable}")
|
|
45
|
+
... except FileNotFoundError as e:
|
|
46
|
+
... print(f"FFProbe not found: {e}")
|
|
47
|
+
"""
|
|
48
|
+
import shutil
|
|
49
|
+
self.executable = shutil.which('ffprobe')
|
|
50
|
+
|
|
51
|
+
if self.executable is None:
|
|
52
|
+
raise FileNotFoundError("""
|
|
53
|
+
FFProbe is not installed or could not be found in PATH.
|
|
54
|
+
Please install FFmpeg and make sure it is available
|
|
55
|
+
in your system PATH.
|
|
56
|
+
""")
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def api(cls) -> "FFProbe":
|
|
60
|
+
"""
|
|
61
|
+
Factory method that returns a new FFProbe instance.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
FFProbe: A new instance of the FFProbe class.
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
>>> ffprobe = FFProbe.api()
|
|
68
|
+
>>> ffprobe.execute("-version")
|
|
69
|
+
"""
|
|
70
|
+
return cls()
|
|
71
|
+
|
|
72
|
+
def execute(self, *args: str, input_data: bytes | None = None) -> tuple[bytes, bytes]:
|
|
73
|
+
"""
|
|
74
|
+
Execute raw FFProbe commands with the given arguments.
|
|
75
|
+
|
|
76
|
+
This method allows you to run any FFProbe command directly,
|
|
77
|
+
providing maximum flexibility for metadata analysis operations
|
|
78
|
+
not covered by the built-in methods.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
*args: FFProbe command-line arguments as strings.
|
|
82
|
+
input_data: Optional bytes to send to FFProbe's stdin. Useful for
|
|
83
|
+
analyzing data directly without intermediate files.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
tuple[bytes, bytes]: A tuple containing (stdout, stderr) from FFProbe
|
|
87
|
+
as bytes objects.
|
|
88
|
+
|
|
89
|
+
Raises:
|
|
90
|
+
FileNotFoundError: If FFProbe executable is not found.
|
|
91
|
+
RuntimeError: If FFProbe command returns a non-zero exit code.
|
|
92
|
+
|
|
93
|
+
Example:
|
|
94
|
+
>>> stdout, stderr = ffprobe.execute("-version")
|
|
95
|
+
>>> print(stdout.decode())
|
|
96
|
+
|
|
97
|
+
>>> # Get video metadata in JSON format
|
|
98
|
+
>>> stdout, stderr = ffprobe.execute("-v", "quiet", "-print_format", "json",
|
|
99
|
+
... "-show_format", "-show_streams", "video.mp4")
|
|
100
|
+
>>> import json
|
|
101
|
+
>>> metadata = json.loads(stdout.decode())
|
|
102
|
+
>>> print(f"Video duration: {metadata['format']['duration']} seconds")
|
|
103
|
+
|
|
104
|
+
>>> # Get video dimensions
|
|
105
|
+
>>> stdout, stderr = ffprobe.execute("-v", "error", "-select_streams", "v:0",
|
|
106
|
+
... "-show_entries", "stream=width,height",
|
|
107
|
+
... "-of", "csv=p=0", "video.mp4")
|
|
108
|
+
>>> print(f"Video dimensions: {stdout.decode().strip()}")
|
|
109
|
+
"""
|
|
110
|
+
if self.executable:
|
|
111
|
+
result = subprocess.run(
|
|
112
|
+
[self.executable, *args],
|
|
113
|
+
input=input_data,
|
|
114
|
+
stdout=subprocess.PIPE,
|
|
115
|
+
stderr=subprocess.PIPE,
|
|
116
|
+
check=False,
|
|
117
|
+
text=True
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
if result.returncode != 0:
|
|
121
|
+
raise RuntimeError(
|
|
122
|
+
result.stderr.decode(errors="replace")
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
return result.stdout, result.stderr
|
|
126
|
+
|
|
127
|
+
raise FileNotFoundError("""
|
|
128
|
+
No ffprobe executable found.
|
|
129
|
+
|
|
130
|
+
Please Install FFmpeg (which includes ffprobe) first.
|
|
131
|
+
""")
|
|
132
|
+
|
|
133
|
+
def is_max_length(self, input_file : str, max_length : float = 5.0) -> bool:
|
|
134
|
+
"""
|
|
135
|
+
Check if a video file's duration is less than or equal to a specified maximum length.
|
|
136
|
+
|
|
137
|
+
Args:
|
|
138
|
+
input_file: Path to the input video file
|
|
139
|
+
max_length: Maximum allowed duration in seconds (default: 5.0)
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
bool: True if video duration ≤ max_length, False otherwise
|
|
143
|
+
|
|
144
|
+
Raises:
|
|
145
|
+
FileNotFoundError: If input file doesn't exist
|
|
146
|
+
RuntimeError: If FFProbe command fails
|
|
147
|
+
|
|
148
|
+
Example:
|
|
149
|
+
>>> if ffprobe.is_max_length("video.mp4", max_length=10.0):
|
|
150
|
+
... print("Video is short enough for social media upload")
|
|
151
|
+
... else:
|
|
152
|
+
... print("Video is too long, needs trimming")
|
|
153
|
+
"""
|
|
154
|
+
args = [
|
|
155
|
+
"-v", "error",
|
|
156
|
+
"-select_streams", "v:0",
|
|
157
|
+
"-show_entries", "stream=duration",
|
|
158
|
+
"-of", "default=noprint_wrappers=1:nokey=1",
|
|
159
|
+
input_file,
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
stdout, stderr = self.execute(*args)
|
|
163
|
+
|
|
164
|
+
duration = float(stdout.strip())
|
|
165
|
+
|
|
166
|
+
return duration <= max_length
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: ffmpeg-python-helper
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.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
|
-
Author-email: marjon <
|
|
6
|
+
Author-email: marjon <petmalu.marjon@gmail.com>
|
|
7
7
|
Requires-Python: >=3.14
|
|
8
8
|
Description-Content-Type: text/markdown
|
|
9
9
|
|
|
@@ -19,6 +19,7 @@ A Python wrapper for FFMPEG that provides a simple, intuitive API for common vid
|
|
|
19
19
|
- 🎵 **Audio Extraction** - Extract audio tracks from videos without re-encoding
|
|
20
20
|
- 🧠 **In-Memory Processing** - Process video/audio data directly from bytes without temporary files
|
|
21
21
|
- ✂️ **Video Trimming** - Trim videos with precise start time and duration control
|
|
22
|
+
- 🔍 **Video Metadata Analysis** - Extract video information and metadata using FFProbe
|
|
22
23
|
- 🐍 **Pythonic API** - Clean, object-oriented interface with proper error handling
|
|
23
24
|
- 📁 **File Validation** - Automatic input file existence checking
|
|
24
25
|
|
|
@@ -82,6 +83,26 @@ with open("trimmed.mp4", "wb") as f:
|
|
|
82
83
|
audio_data = ffmpeg.extract_audios(video_data, output_format="m4a")
|
|
83
84
|
with open("audio.m4a", "wb") as f:
|
|
84
85
|
f.write(audio_data)
|
|
86
|
+
|
|
87
|
+
# Analyze video metadata with FFProbe
|
|
88
|
+
from ffmpeg_python_helper import FFProbe
|
|
89
|
+
import json
|
|
90
|
+
|
|
91
|
+
ffprobe = FFProbe()
|
|
92
|
+
print(f"FFProbe executable found at: {ffprobe.executable}")
|
|
93
|
+
|
|
94
|
+
# Check if video is short enough for social media
|
|
95
|
+
if ffprobe.is_max_length("video.mp4", max_length=5.0):
|
|
96
|
+
print("Video is perfect for Instagram Reels!")
|
|
97
|
+
else:
|
|
98
|
+
print("Video needs trimming for short-form content")
|
|
99
|
+
|
|
100
|
+
# Get detailed video metadata
|
|
101
|
+
stdout, stderr = ffprobe.execute("-v", "quiet", "-print_format", "json",
|
|
102
|
+
"-show_format", "-show_streams", "video.mp4")
|
|
103
|
+
metadata = json.loads(stdout.decode())
|
|
104
|
+
print(f"Video duration: {metadata['format']['duration']} seconds")
|
|
105
|
+
print(f"Video dimensions: {metadata['streams'][0]['width']}x{metadata['streams'][0]['height']}")
|
|
85
106
|
```
|
|
86
107
|
|
|
87
108
|
## API Reference
|
|
@@ -231,6 +252,100 @@ output = ffmpeg.trim("video.mp4", "ending.mp4", start=10)
|
|
|
231
252
|
print(output.decode())
|
|
232
253
|
```
|
|
233
254
|
|
|
255
|
+
### `FFProbe` Class
|
|
256
|
+
|
|
257
|
+
A Python wrapper for FFProbe (the FFMPEG multimedia stream analyzer) that provides video metadata analysis capabilities.
|
|
258
|
+
|
|
259
|
+
#### Constructor
|
|
260
|
+
```python
|
|
261
|
+
FFProbe()
|
|
262
|
+
```
|
|
263
|
+
Creates a new FFProbe instance. Automatically searches for FFProbe in the system PATH.
|
|
264
|
+
- **Raises**: `FileNotFoundError` if FFProbe is not found in PATH
|
|
265
|
+
|
|
266
|
+
#### Properties
|
|
267
|
+
- `executable` (str): The path to the FFProbe executable found in the system
|
|
268
|
+
|
|
269
|
+
#### Class Methods
|
|
270
|
+
```python
|
|
271
|
+
@classmethod
|
|
272
|
+
def api(cls) -> "FFProbe"
|
|
273
|
+
```
|
|
274
|
+
Factory method that returns a new FFProbe instance.
|
|
275
|
+
- **Returns**: `FFProbe` instance
|
|
276
|
+
|
|
277
|
+
**Example:**
|
|
278
|
+
```python
|
|
279
|
+
ffprobe = FFProbe.api()
|
|
280
|
+
print(f"FFProbe executable found at: {ffprobe.executable}")
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
#### Instance Methods
|
|
284
|
+
|
|
285
|
+
##### `execute(*args: str, input_data: bytes | None = None) -> tuple[bytes, bytes]`
|
|
286
|
+
Execute raw FFProbe commands with the given arguments.
|
|
287
|
+
|
|
288
|
+
**Parameters:**
|
|
289
|
+
- `*args` (str): FFProbe command-line arguments as strings
|
|
290
|
+
- `input_data` (bytes | None, optional): Optional bytes to send to FFProbe's stdin
|
|
291
|
+
|
|
292
|
+
**Returns:**
|
|
293
|
+
- `tuple[bytes, bytes]`: A tuple containing (stdout, stderr) as bytes
|
|
294
|
+
|
|
295
|
+
**Raises:**
|
|
296
|
+
- `FileNotFoundError`: If FFProbe executable is not found
|
|
297
|
+
- `RuntimeError`: If FFProbe command returns a non-zero exit code
|
|
298
|
+
|
|
299
|
+
**Example:**
|
|
300
|
+
```python
|
|
301
|
+
# Get FFProbe version
|
|
302
|
+
stdout, stderr = ffprobe.execute("-version")
|
|
303
|
+
print(stdout.decode())
|
|
304
|
+
|
|
305
|
+
# Get video metadata in JSON format
|
|
306
|
+
stdout, stderr = ffprobe.execute("-v", "quiet", "-print_format", "json",
|
|
307
|
+
"-show_format", "-show_streams", "video.mp4")
|
|
308
|
+
metadata = json.loads(stdout.decode())
|
|
309
|
+
print(f"Video duration: {metadata['format']['duration']} seconds")
|
|
310
|
+
|
|
311
|
+
# Get video dimensions
|
|
312
|
+
stdout, stderr = ffprobe.execute("-v", "error", "-select_streams", "v:0",
|
|
313
|
+
"-show_entries", "stream=width,height",
|
|
314
|
+
"-of", "csv=p=0", "video.mp4")
|
|
315
|
+
print(f"Video dimensions: {stdout.decode().strip()}")
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
##### `is_max_length(input_file: str, max_length: float = 5.0) -> bool`
|
|
319
|
+
Check if a video file's duration is less than or equal to a specified maximum length.
|
|
320
|
+
|
|
321
|
+
**Parameters:**
|
|
322
|
+
- `input_file` (str): Path to the input video file
|
|
323
|
+
- `max_length` (float, optional): Maximum allowed duration in seconds (default: 5.0)
|
|
324
|
+
|
|
325
|
+
**Returns:**
|
|
326
|
+
- `bool`: `True` if video duration ≤ max_length, `False` otherwise
|
|
327
|
+
|
|
328
|
+
**Raises:**
|
|
329
|
+
- `FileNotFoundError`: If input file doesn't exist
|
|
330
|
+
- `RuntimeError`: If FFProbe command fails
|
|
331
|
+
|
|
332
|
+
**Example:**
|
|
333
|
+
```python
|
|
334
|
+
# Check if video is shorter than 10 seconds
|
|
335
|
+
if ffprobe.is_max_length("video.mp4", max_length=10.0):
|
|
336
|
+
print("Video is short enough for social media upload")
|
|
337
|
+
else:
|
|
338
|
+
print("Video is too long, needs trimming")
|
|
339
|
+
|
|
340
|
+
# Check multiple videos for length compliance
|
|
341
|
+
videos = ["clip1.mp4", "clip2.mp4", "clip3.mp4"]
|
|
342
|
+
for video in videos:
|
|
343
|
+
if ffprobe.is_max_length(video, max_length=5.0):
|
|
344
|
+
print(f"{video}: OK (≤ 5 seconds)")
|
|
345
|
+
else:
|
|
346
|
+
print(f"{video}: Too long (> 5 seconds)")
|
|
347
|
+
```
|
|
348
|
+
|
|
234
349
|
## Advanced Usage
|
|
235
350
|
|
|
236
351
|
### Custom FFMPEG Commands
|
|
@@ -248,6 +363,52 @@ ffmpeg.execute("-i", "video.mp4", "-i", "watermark.png",
|
|
|
248
363
|
ffmpeg.execute("-i", "input.mp4", "-b:v", "1M", "output.mp4")
|
|
249
364
|
```
|
|
250
365
|
|
|
366
|
+
### Advanced FFProbe Usage
|
|
367
|
+
FFProbe provides powerful video metadata analysis capabilities:
|
|
368
|
+
|
|
369
|
+
```python
|
|
370
|
+
from ffmpeg_python_helper import FFProbe
|
|
371
|
+
import json
|
|
372
|
+
|
|
373
|
+
ffprobe = FFProbe()
|
|
374
|
+
|
|
375
|
+
# Get multiple video metadata properties at once
|
|
376
|
+
stdout, stderr = ffprobe.execute(
|
|
377
|
+
"-v", "error",
|
|
378
|
+
"-select_streams", "v:0",
|
|
379
|
+
"-show_entries", "stream=width,height,duration,bit_rate,codec_name",
|
|
380
|
+
"-of", "json",
|
|
381
|
+
"video.mp4"
|
|
382
|
+
)
|
|
383
|
+
video_info = json.loads(stdout.decode())
|
|
384
|
+
print(f"Video codec: {video_info['streams'][0]['codec_name']}")
|
|
385
|
+
print(f"Video bitrate: {video_info['streams'][0]['bit_rate']} bps")
|
|
386
|
+
|
|
387
|
+
# Check frame rate
|
|
388
|
+
stdout, stderr = ffprobe.execute(
|
|
389
|
+
"-v", "error",
|
|
390
|
+
"-select_streams", "v:0",
|
|
391
|
+
"-show_entries", "stream=r_frame_rate",
|
|
392
|
+
"-of", "default=noprint_wrappers=1:nokey=1",
|
|
393
|
+
"video.mp4"
|
|
394
|
+
)
|
|
395
|
+
print(f"Frame rate: {stdout.decode().strip()}")
|
|
396
|
+
|
|
397
|
+
# Get audio stream information
|
|
398
|
+
stdout, stderr = ffprobe.execute(
|
|
399
|
+
"-v", "error",
|
|
400
|
+
"-select_streams", "a:0",
|
|
401
|
+
"-show_entries", "stream=codec_name,channels,sample_rate",
|
|
402
|
+
"-of", "json",
|
|
403
|
+
"video.mp4"
|
|
404
|
+
)
|
|
405
|
+
audio_info = json.loads(stdout.decode())
|
|
406
|
+
if audio_info['streams']:
|
|
407
|
+
print(f"Audio codec: {audio_info['streams'][0]['codec_name']}")
|
|
408
|
+
print(f"Audio channels: {audio_info['streams'][0]['channels']}")
|
|
409
|
+
print(f"Sample rate: {audio_info['streams'][0]['sample_rate']} Hz")
|
|
410
|
+
```
|
|
411
|
+
|
|
251
412
|
### Error Handling
|
|
252
413
|
```python
|
|
253
414
|
from ffmpeg_python_helper import FFMPEG
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
ffmpeg_python_helper/__init__.py,sha256=CUCXwvcuMPz1WzZRSTyKJeEXkSq8YXN7rvOc8jWTWrk,2248
|
|
2
|
+
ffmpeg_python_helper/ffmpeg_api.py,sha256=y4oRbF3piYWD1dgGdni5o27jyBgrGMdFuD4g8VPkJJw,20143
|
|
3
|
+
ffmpeg_python_helper/ffprobe_api.py,sha256=cv3pC7ongB5eMCaYsdKB2mtxklfV3QrxuWUZEoG2kB4,6178
|
|
4
|
+
ffmpeg_python_helper/pipe_helper.py,sha256=fmEQwKNWuRU78bdTuS2-UIYWF8YcXjdHuR--FR8EDNw,4202
|
|
5
|
+
ffmpeg_python_helper-3.2.0.dist-info/WHEEL,sha256=y6e-a5KI2W-qDAJKfh9Xr81bin8NgUdfWgz3VSXXpe4,80
|
|
6
|
+
ffmpeg_python_helper-3.2.0.dist-info/entry_points.txt,sha256=M9t-tNA-GePbZIBMosX7vgLqg88pjImAYzSQ_fErZzA,68
|
|
7
|
+
ffmpeg_python_helper-3.2.0.dist-info/METADATA,sha256=U8BlSYF_8cfuhirdr-C70GuQkJKhgKOWKOuCQpqvgRQ,15196
|
|
8
|
+
ffmpeg_python_helper-3.2.0.dist-info/RECORD,,
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
ffmpeg_python_helper/__init__.py,sha256=aPK2SEFdtbeRyoCz_FOn0ZF35cpPhHBSFUsqd2T7DVk,2200
|
|
2
|
-
ffmpeg_python_helper/ffmpeg_api.py,sha256=UTDZ8JdizWjLdU0xfFhwiwDbUBiZ7H9a5vA7aydFoOs,18513
|
|
3
|
-
ffmpeg_python_helper/pipe_helper.py,sha256=fmEQwKNWuRU78bdTuS2-UIYWF8YcXjdHuR--FR8EDNw,4202
|
|
4
|
-
ffmpeg_python_helper-3.0.0.dist-info/WHEEL,sha256=y6e-a5KI2W-qDAJKfh9Xr81bin8NgUdfWgz3VSXXpe4,80
|
|
5
|
-
ffmpeg_python_helper-3.0.0.dist-info/entry_points.txt,sha256=M9t-tNA-GePbZIBMosX7vgLqg88pjImAYzSQ_fErZzA,68
|
|
6
|
-
ffmpeg_python_helper-3.0.0.dist-info/METADATA,sha256=2JO6yyaV-D2d152tFRE5IHd2hdR7gu2BmeELUy3e93s,10007
|
|
7
|
-
ffmpeg_python_helper-3.0.0.dist-info/RECORD,,
|
|
File without changes
|
{ffmpeg_python_helper-3.0.0.dist-info → ffmpeg_python_helper-3.2.0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|