Skip to content

Commit 4d75c2b

Browse files
randompersona1slhck
authored andcommitted
Enable passing environment to subprocess.Popen
Consumers can pass an environment dict to subprocess.Popen uses by using the context manager ffmpeg_env. Thread safety is ensured by contextvars.ContextVar.
1 parent 352d809 commit 4d75c2b

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

src/ffmpeg_normalize/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import importlib.metadata
22

3+
from ._cmd_utils import ffmpeg_env
34
from ._errors import FFmpegNormalizeError
45
from ._ffmpeg_normalize import FFmpegNormalize
56
from ._media_file import MediaFile
@@ -17,5 +18,6 @@
1718
"VideoStream",
1819
"SubtitleStream",
1920
"MediaStream",
21+
"ffmpeg_env",
2022
"__version__",
2123
]

src/ffmpeg_normalize/_cmd_utils.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from __future__ import annotations
22

3+
import contextvars
34
import logging
45
import os
56
import re
67
import shlex
78
import subprocess
9+
from contextlib import contextmanager
810
from shutil import which
911
from typing import Any, Iterator
1012

@@ -14,6 +16,30 @@
1416

1517
_logger = logging.getLogger(__name__)
1618

19+
_ffmpeg_env_var: contextvars.ContextVar[dict[str, str] | None] = contextvars.ContextVar(
20+
"ffmpeg_env", default=None
21+
)
22+
23+
24+
@contextmanager
25+
def ffmpeg_env(env: dict[str, str] | None) -> Iterator[None]:
26+
"""
27+
Temporarily set the environment for subprocess.Popen.
28+
29+
Args:
30+
env: Environment dict to pass to subprocess.Popen.
31+
"""
32+
token = _ffmpeg_env_var.set(env)
33+
try:
34+
yield
35+
finally:
36+
_ffmpeg_env_var.reset(token)
37+
38+
39+
def _get_ffmpeg_env() -> dict[str, str] | None:
40+
return _ffmpeg_env_var.get()
41+
42+
1743
DUR_REGEX = re.compile(
1844
r"Duration: (?P<hour>\d{2}):(?P<min>\d{2}):(?P<sec>\d{2})\.(?P<ms>\d{2})"
1945
)
@@ -76,7 +102,9 @@ def run_ffmpeg_command(self, cmd: list[str]) -> Iterator[float]:
76102
# wrapper for 'ffmpeg-progress-yield'
77103
_logger.debug(f"Running command: {shlex.join(cmd)}")
78104
with FfmpegProgress(cmd, dry_run=self.dry) as ff:
79-
yield from ff.run_command_with_progress()
105+
yield from ff.run_command_with_progress(
106+
popen_kwargs={"env": _get_ffmpeg_env()}
107+
)
80108

81109
self.output = ff.stderr
82110

@@ -107,6 +135,7 @@ def run_command(self, cmd: list[str]) -> CommandRunner:
107135
stdout=subprocess.PIPE,
108136
stderr=subprocess.PIPE,
109137
universal_newlines=False,
138+
env=_get_ffmpeg_env(),
110139
)
111140

112141
stdout_bytes, stderr_bytes = p.communicate()

0 commit comments

Comments
 (0)