-
-
Notifications
You must be signed in to change notification settings - Fork 52
/
_utils.py
99 lines (83 loc) · 3.01 KB
/
_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import os
import sys
import logging
import subprocess
from pkg_resources import resource_filename
from ._definitions import get_platform, FNAME_PER_PLATFORM
logger = logging.getLogger("imageio_ffmpeg")
def get_ffmpeg_exe():
"""
Get the ffmpeg executable file. This can be the binary defined by
the IMAGEIO_FFMPEG_EXE environment variable, the binary distributed
with imageio-ffmpeg, an ffmpeg binary installed with conda, or the
system ffmpeg (in that order). A RuntimeError is raised if no valid
ffmpeg could be found.
"""
# 1. Try environment variable. - Dont test it: the user is explicit here!
exe = os.getenv("IMAGEIO_FFMPEG_EXE", None)
if exe:
return exe
plat = get_platform()
# 2. Try from here
bin_dir = resource_filename("imageio_ffmpeg", "binaries")
exe = os.path.join(bin_dir, FNAME_PER_PLATFORM.get(plat, ""))
if exe and os.path.isfile(exe) and _is_valid_exe(exe):
return exe
# 3. Try binary from conda package
# (installed e.g. via `conda install ffmpeg -c conda-forge`)
if plat.startswith("win"):
exe = os.path.join(sys.prefix, "Library", "bin", "ffmpeg.exe")
else:
exe = os.path.join(sys.prefix, "bin", "ffmpeg")
if exe and os.path.isfile(exe) and _is_valid_exe(exe):
return exe
# 4. Try system ffmpeg command
exe = "ffmpeg"
if _is_valid_exe(exe):
return exe
# Nothing was found
raise RuntimeError(
"No ffmpeg exe could be found. Install ffmpeg on your system, "
"or set the IMAGEIO_FFMPEG_EXE environment variable."
)
def _popen_kwargs(prevent_sigint=False):
startupinfo = None
preexec_fn = None
creationflags = 0
if sys.platform.startswith("win"):
# Stops executable from flashing on Windows (see #22)
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
if prevent_sigint:
# Prevent propagation of sigint (see #4)
# https://stackoverflow.com/questions/5045771
if sys.platform.startswith("win"):
creationflags = 0x00000200
else:
preexec_fn = os.setpgrp # the _pre_exec does not seem to work
return {
"startupinfo": startupinfo,
"creationflags": creationflags,
"preexec_fn": preexec_fn,
}
def _is_valid_exe(exe):
cmd = [exe, "-version"]
try:
with open(os.devnull, "w") as null:
subprocess.check_call(
cmd, stdout=null, stderr=subprocess.STDOUT, **_popen_kwargs()
)
return True
except (OSError, ValueError, subprocess.CalledProcessError):
return False
def get_ffmpeg_version():
"""
Get the version of the used ffmpeg executable (as a string).
"""
exe = get_ffmpeg_exe()
line = subprocess.check_output([exe, "-version"], **_popen_kwargs()).split(
b"\n", 1
)[0]
line = line.decode(errors="ignore").strip()
version = line.split("version", 1)[-1].lstrip().split(" ", 1)[0].strip()
return version