[wip] Fix loading YAML config from another directory

Bugs: FFmpeg writes to file named "-"
pull/357/head
nyanpasu64 2018-08-27 04:48:35 -07:00
rodzic 590aad12ba
commit ba17f64618
7 zmienionych plików z 48 dodań i 35 usunięć

Wyświetl plik

@ -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)

Wyświetl plik

@ -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()

Wyświetl plik

@ -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

Wyświetl plik

@ -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)

Wyświetl plik

@ -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()

Wyświetl plik

@ -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

Wyświetl plik

@ -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()