kopia lustrzana https://github.com/corrscope/corrscope
[wip] Fix loading YAML config from another directory
Bugs: FFmpeg writes to file named "-"pull/357/head
rodzic
590aad12ba
commit
ba17f64618
|
@ -1,3 +1,4 @@
|
|||
from os.path import abspath
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from ovgenpy.config import register_config, Alias
|
||||
|
@ -42,7 +43,7 @@ class Channel:
|
|||
|
||||
# Create a Wave object.
|
||||
wcfg = _WaveConfig(amplification=ovgen_cfg.amplification * cfg.ampl_ratio)
|
||||
self.wave = Wave(wcfg, cfg.wav_path)
|
||||
self.wave = Wave(wcfg, abspath(cfg.wav_path))
|
||||
|
||||
# Compute subsampling (array stride).
|
||||
tw = coalesce(cfg.trigger_width, ovgen_cfg.trigger_width)
|
||||
|
|
|
@ -86,6 +86,7 @@ def main(
|
|||
|
||||
# Create cfg: Config object.
|
||||
cfg: Config = None
|
||||
cfg_dir: str = None
|
||||
|
||||
wav_list: List[Path] = []
|
||||
for name in files:
|
||||
|
@ -106,6 +107,7 @@ def main(
|
|||
raise click.ClickException(
|
||||
f'When supplying config {path}, you cannot supply other files/folders')
|
||||
cfg = yaml.load(path)
|
||||
cfg_dir = path.parent
|
||||
break
|
||||
|
||||
else:
|
||||
|
@ -136,6 +138,7 @@ def main(
|
|||
# amplification...render=default,
|
||||
outputs=outputs
|
||||
)
|
||||
cfg_dir = '.'
|
||||
|
||||
if show_gui:
|
||||
raise OvgenError('GUI not implemented')
|
||||
|
@ -171,4 +174,4 @@ def main(
|
|||
cProfile.runctx('Ovgen(cfg).play()', globals(), locals(), path)
|
||||
|
||||
else:
|
||||
Ovgen(cfg).play()
|
||||
Ovgen(cfg, cfg_dir).play()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import shlex
|
||||
import subprocess
|
||||
from abc import ABC, abstractmethod
|
||||
from os.path import abspath
|
||||
from typing import TYPE_CHECKING, Type, List, Union
|
||||
|
||||
from ovgenpy.config import register_config
|
||||
|
@ -55,7 +56,7 @@ class _FFmpegCommand:
|
|||
|
||||
self.templates += ffmpeg_input_video(ovgen_cfg) # video
|
||||
if ovgen_cfg.master_audio:
|
||||
audio_path = shlex.quote(ovgen_cfg.master_audio)
|
||||
audio_path = shlex.quote(abspath(ovgen_cfg.master_audio))
|
||||
self.templates.append(f'-ss {ovgen_cfg.begin_time}')
|
||||
self.templates += ffmpeg_input_audio(audio_path) # audio
|
||||
|
||||
|
@ -141,7 +142,7 @@ class FFmpegOutput(PipeOutput):
|
|||
ffmpeg = _FFmpegCommand([FFMPEG, '-y'], ovgen_cfg)
|
||||
ffmpeg.add_output(cfg)
|
||||
ffmpeg.templates.append(cfg.args)
|
||||
self.open(ffmpeg.popen([cfg.path], self.bufsize))
|
||||
self.open(ffmpeg.popen([abspath(cfg.path)], self.bufsize))
|
||||
|
||||
|
||||
# FFplayOutput
|
||||
|
|
|
@ -10,6 +10,7 @@ from ovgenpy.channel import Channel, ChannelConfig
|
|||
from ovgenpy.config import register_config, register_enum, Ignored
|
||||
from ovgenpy.renderer import MatplotlibRenderer, RendererConfig, LayoutConfig
|
||||
from ovgenpy.triggers import ITriggerConfig, CorrelationTriggerConfig, Trigger
|
||||
from ovgenpy.util import pushd
|
||||
from ovgenpy.utils import keyword_dataclasses as dc
|
||||
from ovgenpy.utils.keyword_dataclasses import field
|
||||
from ovgenpy.wave import Wave
|
||||
|
@ -97,8 +98,9 @@ def default_config(**kwargs):
|
|||
|
||||
|
||||
class Ovgen:
|
||||
def __init__(self, cfg: Config):
|
||||
def __init__(self, cfg: Config, cfg_dir: str):
|
||||
self.cfg = cfg
|
||||
self.cfg_dir = cfg_dir
|
||||
self.has_played = False
|
||||
|
||||
if len(self.cfg.channels) == 0:
|
||||
|
@ -110,19 +112,21 @@ class Ovgen:
|
|||
nchan: int
|
||||
|
||||
def _load_channels(self):
|
||||
self.channels = [Channel(ccfg, self.cfg) for ccfg in self.cfg.channels]
|
||||
self.waves = [channel.wave for channel in self.channels]
|
||||
self.triggers = [channel.trigger for channel in self.channels]
|
||||
self.nchan = len(self.channels)
|
||||
with pushd(self.cfg_dir):
|
||||
self.channels = [Channel(ccfg, self.cfg) for ccfg in self.cfg.channels]
|
||||
self.waves = [channel.wave for channel in self.channels]
|
||||
self.triggers = [channel.trigger for channel in self.channels]
|
||||
self.nchan = len(self.channels)
|
||||
|
||||
@contextmanager
|
||||
def _load_outputs(self):
|
||||
with ExitStack() as stack:
|
||||
self.outputs = [
|
||||
stack.enter_context(output_cfg(self.cfg))
|
||||
for output_cfg in self.cfg.outputs
|
||||
]
|
||||
yield
|
||||
with pushd(self.cfg_dir):
|
||||
with ExitStack() as stack:
|
||||
self.outputs = [
|
||||
stack.enter_context(output_cfg(self.cfg))
|
||||
for output_cfg in self.cfg.outputs
|
||||
]
|
||||
yield
|
||||
|
||||
def _load_renderer(self):
|
||||
renderer = MatplotlibRenderer(self.cfg.render, self.cfg.layout, self.nchan)
|
||||
|
|
|
@ -64,7 +64,7 @@ def test_channel_subsampling(
|
|||
assert trigger._subsampling == channel.trigger_subsampling
|
||||
|
||||
# Ensure ovgenpy calls render using channel.window_samp and render_subsampling.
|
||||
ovgen = Ovgen(cfg)
|
||||
ovgen = Ovgen(cfg, '.')
|
||||
renderer = mocker.patch.object(Ovgen, '_load_renderer').return_value
|
||||
ovgen.play()
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import shlex
|
||||
from os.path import abspath
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Callable
|
||||
|
||||
|
@ -13,7 +14,6 @@ from ovgenpy.config import yaml
|
|||
from ovgenpy.ovgenpy import Config, Ovgen
|
||||
from ovgenpy.util import pushd
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import pytest_mock
|
||||
|
||||
|
@ -49,7 +49,8 @@ def player_sink(mocker) -> Callable:
|
|||
call_main(argv)
|
||||
|
||||
Ovgen.assert_called_once()
|
||||
(cfg,), kwargs = Ovgen.call_args
|
||||
args, kwargs = Ovgen.call_args
|
||||
cfg = args[0]
|
||||
|
||||
assert isinstance(cfg, Config)
|
||||
return cfg,
|
||||
|
@ -105,36 +106,39 @@ def test_write_dir(yaml_sink):
|
|||
assert outpath.parent / cfg.master_audio == audio_path
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def Wave(mocker):
|
||||
""" Logs all calls, and returns a real Wave object. """
|
||||
Wave = mocker.spy(ovgenpy.channel, 'Wave')
|
||||
yield Wave
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('Popen')
|
||||
def test_load_yaml_another_dir(yaml_sink, Popen, Wave):
|
||||
""" Loading `another/dir/YAML` should resolve `master_audio`, `channels[].wav_path`,
|
||||
and video `path` from `another/dir`. """
|
||||
def test_load_yaml_another_dir(yaml_sink, mocker, Popen):
|
||||
""" YAML file located in `another/dir` should resolve `master_audio`, `channels[].
|
||||
wav_path`, and video `path` from `another/dir`. """
|
||||
|
||||
with pushd('tests'):
|
||||
arg_str = 'sine440.wav -a sine440.wav -o foo.mp4'
|
||||
subdir = 'tests'
|
||||
wav = 'sine440.wav'
|
||||
mp4 = 'foo.mp4'
|
||||
with pushd(subdir):
|
||||
arg_str = f'{wav} -a {wav} -o {mp4}'
|
||||
cfg, outpath = yaml_sink(arg_str) # type: Config, Path
|
||||
|
||||
cfg.begin_time = 100 # To skip all actual rendering
|
||||
ovgen = Ovgen(cfg, 'tests')
|
||||
|
||||
# Log execution of Ovgen().play()
|
||||
Wave = mocker.spy(ovgenpy.channel, 'Wave')
|
||||
ovgen = Ovgen(cfg, subdir)
|
||||
ovgen.play()
|
||||
|
||||
# Compute absolute paths
|
||||
wav_abs = abspath(f'{subdir}/{wav}')
|
||||
mp4_abs = abspath(f'{subdir}/{mp4}')
|
||||
|
||||
# Test `wave_path`
|
||||
args, kwargs = Wave.call_args
|
||||
cfg, wave_path = args
|
||||
assert wave_path == 'tests/sine440.wav'
|
||||
assert wave_path == wav_abs
|
||||
|
||||
# Test output `master_audio` and video `path`
|
||||
args, kwargs = Popen.call_args
|
||||
argv = args[0]
|
||||
assert argv[-1] == 'tests/foo.mp4'
|
||||
assert '-i tests/sine440.wav' in ' '.join(argv)
|
||||
assert argv[-1] == mp4_abs
|
||||
assert f'-i {wav_abs}' in ' '.join(argv)
|
||||
|
||||
|
||||
# TODO integration test without --audio
|
||||
|
|
|
@ -67,7 +67,7 @@ def test_ovgen_terminate_ffplay(Popen, mocker: 'pytest_mock.MockFixture'):
|
|||
master_audio='tests/sine440.wav',
|
||||
outputs=[FFplayOutputConfig()]
|
||||
)
|
||||
ovgen = Ovgen(cfg)
|
||||
ovgen = Ovgen(cfg, '.')
|
||||
|
||||
render_frame = mocker.patch.object(MatplotlibRenderer, 'render_frame')
|
||||
render_frame.side_effect = DummyException()
|
||||
|
|
Ładowanie…
Reference in New Issue