Skip to content

Commit 1f45330

Browse files
committed
Moved _exec() from ffmpegprocess to path
1 parent 1c95e69 commit 1f45330

7 files changed

Lines changed: 70 additions & 67 deletions

File tree

src/ffmpegio/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757

5858
__version__ = "0.4.3"
5959

60-
ffmpeg_info = ffmpegprocess.versions
60+
ffmpeg_info = path.versions
6161
set_path = path.find
6262
get_path = path.where
6363
is_ready = path.found

src/ffmpegio/devices.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
2-
from ffmpegio.ffmpegprocess import _exec, PIPE, DEVNULL
2+
from ffmpegio.path import _exec
3+
from subprocess import PIPE, DEVNULL
34
from . import plugins
45
import re
56

src/ffmpegio/ffmpegprocess.py

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
2020
"""
2121

22-
import logging, re, shlex
22+
import logging, re
2323
from os import path, devnull
2424
from threading import Thread
2525
import subprocess as sp
@@ -182,52 +182,6 @@ def iswritable(f):
182182
return sp_run(args, stdin=inpipe, stdout=outpipe, stderr=errpipe, **sp_kwargs)
183183

184184

185-
def _exec(args, **other_run_args):
186-
'''just run ffmpeg without bells-n-whistles
187-
188-
:param args: FFmpeg command arguments without `ffmpeg`
189-
:type args: str or Sequence[str]
190-
:param **other_run_args: subprocess.run() options
191-
:type **other_run_args: dict
192-
'''
193-
if isinstance(args, str):
194-
args = shlex.split(args)
195-
return sp.run((get_ffmpeg(), *args), **other_run_args)
196-
197-
198-
def versions():
199-
"""Get FFmpeg version and configuration information
200-
201-
:return: versions of ffmpeg and its av libraries as well as build configuration
202-
:rtype: dict
203-
204-
================== ==== =========================================
205-
key type description
206-
================== ==== =========================================
207-
'version' str FFmpeg version
208-
'configuration' list list of build configuration options
209-
'library_versions' dict version numbers of dependent av libraries
210-
================== ==== =========================================
211-
212-
"""
213-
s = _exec(
214-
["-version"], stdout=PIPE, universal_newlines=True, encoding="utf-8"
215-
).stdout.splitlines()
216-
v = dict(version=re.match(r"ffmpeg version (\S+)", s[0])[1])
217-
i = 2 if s[1].startswith("built with") else 1
218-
if s[i].startswith("configuration:"):
219-
v["configuration"] = sorted([m[1] for m in re.finditer(r"\s--(\S+)", s[i])])
220-
i += 1
221-
lv = None
222-
for l in s[i:]:
223-
m = re.match(r"(\S+)\s+(.+?) /", l)
224-
if m:
225-
if lv is None:
226-
lv = v["library_versions"] = {}
227-
lv[m[1]] = m[2].replace(" ", "")
228-
return v
229-
230-
231185
def monitor_process(proc, on_exit=None):
232186
"""thread function to monitor subprocess termination
233187

src/ffmpegio/path.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from os import path as _path, name as _os_name
22
from shutil import which
33
from subprocess import run, PIPE
4-
import re
4+
import re, shlex, subprocess as sp
55
from packaging.version import Version
66

77
from . import plugins
@@ -107,3 +107,49 @@ def find(ffmpeg_path=None, ffprobe_path=None):
107107
if res is None:
108108
raise RuntimeError("Failed to auto-detect ffmpeg and ffprobe executable.")
109109
FFMPEG_BIN, FFPROBE_BIN = res
110+
111+
112+
def _exec(args, **other_run_args):
113+
"""just run ffmpeg without bells-n-whistles
114+
115+
:param args: FFmpeg command arguments without `ffmpeg`
116+
:type args: str or Sequence[str]
117+
:param **other_run_args: subprocess.run() options
118+
:type **other_run_args: dict
119+
"""
120+
if isinstance(args, str):
121+
args = shlex.split(args)
122+
return sp.run((where(), *args), **other_run_args)
123+
124+
125+
def versions():
126+
"""Get FFmpeg version and configuration information
127+
128+
:return: versions of ffmpeg and its av libraries as well as build configuration
129+
:rtype: dict
130+
131+
================== ==== =========================================
132+
key type description
133+
================== ==== =========================================
134+
'version' str FFmpeg version
135+
'configuration' list list of build configuration options
136+
'library_versions' dict version numbers of dependent av libraries
137+
================== ==== =========================================
138+
139+
"""
140+
s = _exec(
141+
["-version"], stdout=PIPE, universal_newlines=True, encoding="utf-8"
142+
).stdout.splitlines()
143+
v = dict(version=re.match(r"ffmpeg version (\S+)", s[0])[1])
144+
i = 2 if s[1].startswith("built with") else 1
145+
if s[i].startswith("configuration:"):
146+
v["configuration"] = sorted([m[1] for m in re.finditer(r"\s--(\S+)", s[i])])
147+
i += 1
148+
lv = None
149+
for l in s[i:]:
150+
m = re.match(r"(\S+)\s+(.+?) /", l)
151+
if m:
152+
if lv is None:
153+
lv = v["library_versions"] = {}
154+
lv[m[1]] = m[2].replace(" ", "")
155+
return v

src/ffmpegio/plugins/devices/dshow.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
""" DirectShow device"""
22

33
from copy import deepcopy
4+
from subprocess import PIPE
45
from ffmpegio import path
5-
from ffmpegio.ffmpegprocess import run
66
import re, logging
77
from packaging.version import Version
88

@@ -21,12 +21,18 @@ def _rescan():
2121

2222
global DSHOW_DEVICES
2323

24-
logs = run(
25-
{
26-
"inputs": [("dummy", {"f": "dshow", "list_devices": True})],
27-
"global_options": {"loglevel": "repeat+info"},
28-
},
29-
capture_log=True,
24+
logs = path._exec(
25+
[
26+
"-f",
27+
"dshow",
28+
"-list_devices",
29+
"true",
30+
"-i",
31+
"dummy",
32+
"-loglevel",
33+
"repeat+info",
34+
],
35+
stderr=PIPE,
3036
universal_newlines=True,
3137
).stderr
3238

@@ -149,12 +155,9 @@ def _list_options(dev_type, spec):
149155
is_video = dev["media_type"] == "video"
150156

151157
url = f'{dev["media_type"]}={dev["name"]}'
152-
logs = run(
153-
{
154-
"inputs": [(url, {"f": "dshow", "list_options": True})],
155-
"global_options": {"loglevel": "repeat+info"},
156-
},
157-
capture_log=True,
158+
logs = path._exec(
159+
["-f", "dshow", "-list_options", "true", "-i", url, "-loglevel", "repeat+info"],
160+
stderr=PIPE,
158161
universal_newlines=True,
159162
).stderr
160163

tests/test_ffmpegprocess.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@
44
# logging.basicConfig(level=logging.DEBUG)
55

66

7-
def test_versions():
8-
assert "version" in ffmpegprocess.versions()
9-
10-
117
def test_run_help():
128
ffmpegprocess.run({"global_options": {"help": None}})
139

tests/test_path.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ def test_found():
3131
def test_where():
3232
assert path.where() is not None # assuming ffmpeg is found
3333

34+
def test_versions():
35+
assert "version" in path.versions()
36+
3437

3538
if __name__ == "__main__":
3639
test_find()

0 commit comments

Comments
 (0)