typed-ffmpeg-compatible 2.5.0__py3-none-any.whl → 2.6.1__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/info.py ADDED
@@ -0,0 +1,167 @@
1
+ import logging
2
+ import subprocess
3
+ from dataclasses import dataclass
4
+ from enum import Flag, auto
5
+
6
+ from .exceptions import FFMpegExecuteError
7
+ from .utils.run import command_line
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+
12
+ class CodecFlags(Flag):
13
+ video = auto()
14
+ audio = auto()
15
+ subtitle = auto()
16
+ frame_level_multithreading = auto()
17
+ slice_level_multithreading = auto()
18
+ experimental = auto()
19
+ draw_horiz_band = auto()
20
+ direct_rendering_method_1 = auto()
21
+
22
+
23
+ @dataclass(frozen=True)
24
+ class Codec:
25
+ name: str
26
+ flags: CodecFlags
27
+ description: str
28
+
29
+
30
+ def parse_codec_flags(flags: str) -> CodecFlags:
31
+ flags_enum = CodecFlags(0)
32
+ if flags[0] == "V":
33
+ flags_enum |= CodecFlags.video
34
+ if flags[0] == "A":
35
+ flags_enum |= CodecFlags.audio
36
+ if flags[0] == "S":
37
+ flags_enum |= CodecFlags.subtitle
38
+ if flags[1] == "F":
39
+ flags_enum |= CodecFlags.frame_level_multithreading
40
+ if flags[2] == "S":
41
+ flags_enum |= CodecFlags.slice_level_multithreading
42
+ if flags[3] == "X":
43
+ flags_enum |= CodecFlags.experimental
44
+ if flags[4] == "B":
45
+ flags_enum |= CodecFlags.draw_horiz_band
46
+ if flags[5] == "D":
47
+ flags_enum |= CodecFlags.direct_rendering_method_1
48
+ return flags_enum
49
+
50
+
51
+ def get_codecs() -> tuple[Codec, ...]:
52
+ args = ["ffmpeg", "-hide_banner", "-codecs"]
53
+ logger.info("Running ffmpeg command: %s", command_line(args))
54
+ p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
55
+ out, err = p.communicate()
56
+
57
+ retcode = p.poll()
58
+ if p.returncode != 0:
59
+ raise FFMpegExecuteError(
60
+ retcode=retcode, cmd=command_line(args), stdout=out, stderr=err
61
+ )
62
+
63
+ codecs = out.decode("utf-8")
64
+ codecs_lines = codecs.strip().split("\n")
65
+ # Skip header lines until we find the separator
66
+ for i, line in enumerate(codecs_lines):
67
+ if line.startswith(" ------"):
68
+ codecs_lines = codecs_lines[i + 1 :]
69
+ break
70
+ return tuple(
71
+ Codec(
72
+ name=parts[1],
73
+ flags=parse_codec_flags(parts[0]),
74
+ description=parts[2],
75
+ )
76
+ for line in codecs_lines
77
+ for parts in [line.split(None, 3)]
78
+ )
79
+
80
+
81
+ class CoderFlags(Flag):
82
+ video = auto()
83
+ audio = auto()
84
+ subtitle = auto()
85
+ frame_level_multithreading = auto()
86
+ slice_level_multithreading = auto()
87
+ experimental = auto()
88
+ draw_horiz_band = auto()
89
+ direct_rendering_method_1 = auto()
90
+
91
+
92
+ def parse_coder_flags(flags: str) -> CoderFlags:
93
+ flags_enum = CoderFlags(0)
94
+ if flags[0] == "V":
95
+ flags_enum |= CoderFlags.video
96
+ if flags[0] == "A":
97
+ flags_enum |= CoderFlags.audio
98
+ if flags[0] == "S":
99
+ flags_enum |= CoderFlags.subtitle
100
+ if flags[1] == "F":
101
+ flags_enum |= CoderFlags.frame_level_multithreading
102
+ if flags[2] == "S":
103
+ flags_enum |= CoderFlags.slice_level_multithreading
104
+ if flags[3] == "X":
105
+ flags_enum |= CoderFlags.experimental
106
+ if flags[4] == "B":
107
+ flags_enum |= CoderFlags.draw_horiz_band
108
+ if flags[5] == "D":
109
+ flags_enum |= CoderFlags.direct_rendering_method_1
110
+ return flags_enum
111
+
112
+
113
+ @dataclass
114
+ class Coder:
115
+ name: str
116
+ flags: CoderFlags
117
+ description: str
118
+
119
+
120
+ def get_coders(codes: str) -> tuple[Coder, ...]:
121
+ codecs_lines = codes.strip().split("\n")
122
+ # Skip header lines until we find the separator
123
+ for i, line in enumerate(codecs_lines):
124
+ if line.startswith(" ------"):
125
+ codecs_lines = codecs_lines[i + 1 :]
126
+ break
127
+ return tuple(
128
+ Coder(
129
+ name=parts[1],
130
+ flags=parse_coder_flags(parts[0]),
131
+ description=parts[2],
132
+ )
133
+ for line in codecs_lines
134
+ for parts in [line.split(None, 3)]
135
+ )
136
+
137
+
138
+ def get_decoders() -> tuple[Coder, ...]:
139
+ args = ["ffmpeg", "-hide_banner", "-decoders"]
140
+ logger.info("Running ffmpeg command: %s", command_line(args))
141
+ p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
142
+ out, err = p.communicate()
143
+
144
+ retcode = p.poll()
145
+ if p.returncode != 0:
146
+ raise FFMpegExecuteError(
147
+ retcode=retcode, cmd=command_line(args), stdout=out, stderr=err
148
+ )
149
+
150
+ decoders = out.decode("utf-8")
151
+ return get_coders(decoders)
152
+
153
+
154
+ def get_encoders() -> tuple[Coder, ...]:
155
+ args = ["ffmpeg", "-hide_banner", "-encoders"]
156
+ logger.info("Running ffmpeg command: %s", command_line(args))
157
+ p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
158
+ out, err = p.communicate()
159
+
160
+ retcode = p.poll()
161
+ if p.returncode != 0:
162
+ raise FFMpegExecuteError(
163
+ retcode=retcode, cmd=command_line(args), stdout=out, stderr=err
164
+ )
165
+
166
+ encoders = out.decode("utf-8")
167
+ return get_coders(encoders)
typed_ffmpeg/probe.py CHANGED
@@ -11,7 +11,12 @@ from .utils.run import command_line
11
11
  logger = logging.getLogger(__name__)
12
12
 
13
13
 
14
- def probe(filename: str | Path, cmd: str = "ffprobe", timeout: int | None = None, **kwargs: Any) -> dict[str, Any]:
14
+ def probe(
15
+ filename: str | Path,
16
+ cmd: str = "ffprobe",
17
+ timeout: int | None = None,
18
+ **kwargs: Any,
19
+ ) -> dict[str, Any]:
15
20
  """
16
21
  Run ffprobe on the given file and return a JSON representation of the output
17
22
 
@@ -38,6 +43,8 @@ def probe(filename: str | Path, cmd: str = "ffprobe", timeout: int | None = None
38
43
 
39
44
  retcode = p.poll()
40
45
  if p.returncode != 0:
41
- raise FFMpegExecuteError(retcode=retcode, cmd=command_line(args), stdout=out, stderr=err)
46
+ raise FFMpegExecuteError(
47
+ retcode=retcode, cmd=command_line(args), stdout=out, stderr=err
48
+ )
42
49
 
43
50
  return json.loads(out.decode("utf-8"))
typed_ffmpeg/schema.py CHANGED
@@ -2,7 +2,6 @@
2
2
  Defines the basic schema for the ffmpeg command line options.
3
3
  """
4
4
 
5
-
6
5
  from .common.schema import StreamType
7
6
 
8
7