typed-ffmpeg-compatible 2.5.0__py3-none-any.whl → 2.6.1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
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