Explorar el Código

add support for spec-level variables

master
Jonathan Cobb hace 3 años
padre
commit
98c47671d9
Se han modificado 12 ficheros con 60 adiciones y 21 borrados
  1. +2
    -0
      src/main/java/jvc/model/JSpec.java
  2. +11
    -5
      src/main/java/jvc/model/JsObjectView.java
  3. +6
    -3
      src/main/java/jvc/model/operation/JOperation.java
  4. +1
    -0
      src/main/java/jvc/operation/exec/AdjustSpeedExec.java
  5. +25
    -2
      src/main/java/jvc/operation/exec/ExecBase.java
  6. +1
    -1
      src/main/java/jvc/operation/exec/KenBurnsExec.java
  7. +1
    -1
      src/main/java/jvc/operation/exec/OverlayExec.java
  8. +1
    -1
      src/main/java/jvc/operation/exec/SingleOrMultiSourceExecBase.java
  9. +1
    -1
      src/main/java/jvc/operation/exec/SplitExec.java
  10. +3
    -3
      src/main/java/jvc/service/JvcEngine.java
  11. +0
    -2
      src/test/resources/tests/test_overlay.jvc
  12. +8
    -2
      src/test/resources/tests/test_scale.jvc

+ 2
- 0
src/main/java/jvc/model/JSpec.java Ver fichero

@@ -5,10 +5,12 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.cobbzilla.util.collection.NameAndValue;

@NoArgsConstructor @Accessors(chain=true)
public class JSpec {

@Getter @Setter private NameAndValue[] vars;
@Getter @Setter private JAsset[] assets;
@Getter @Setter private JOperation[] operations;
@Getter @Setter private JArtifact[] artifacts;


+ 11
- 5
src/main/java/jvc/model/JsObjectView.java Ver fichero

@@ -1,10 +1,12 @@
package jvc.model;

import jvc.model.js.JAssetJs;

import java.util.Collection;
import java.util.stream.Collectors;

import static java.util.Collections.emptyList;
import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.util.daemon.ZillaRuntime.*;

public interface JsObjectView {

@@ -16,13 +18,17 @@ public interface JsObjectView {
&& (((Collection) value).iterator().next() instanceof JsObjectView);
}

static <T extends JsObjectView> Collection<T> toJs(Collection<T> values) {
static <T extends JsObjectView> Collection<JAssetJs> toJs(Collection<T> values) {
if (empty(values)) {
return emptyList();
} else {
return values.stream()
.map(v -> (T) v.toJs())
.collect(Collectors.toList());
try {
return values.stream()
.map(v -> (JAssetJs) v.toJs())
.collect(Collectors.toList());
} catch (Exception e) {
return die("toJs: "+shortError(e));
}
}
}



+ 6
- 3
src/main/java/jvc/model/operation/JOperation.java Ver fichero

@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.JsonNode;
import jvc.model.JAsset;
import jvc.model.JSpec;
import jvc.operation.exec.ExecBase;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -50,9 +51,11 @@ public abstract class JOperation {
return hashOf(operation, json(this), sources, args);
}

private static final Map<Class<? extends JOperation>, ExecBase<?>> execMap = new HashMap<>();
public <OP extends JOperation> ExecBase<OP> getExec() {
return (ExecBase<OP>) execMap.computeIfAbsent(getClass(), c -> instantiate(getOperationExecClass(getClass())));
private static final Map<String, ExecBase<?>> execMap = new HashMap<>();
public <OP extends JOperation> ExecBase<OP> getExec(JSpec spec) {
final String cacheKey = hashOf(getClass().getName(), spec.getVars());
return (ExecBase<OP>) execMap.computeIfAbsent(cacheKey,
c -> ((ExecBase<?>) instantiate(getOperationExecClass(getClass()))).setSpec(spec));
}

public String shortString() { return safeShellArg(operation+"_"+sha256_hex(json(this))); }


+ 1
- 0
src/main/java/jvc/operation/exec/AdjustSpeedExec.java Ver fichero

@@ -1,5 +1,6 @@
package jvc.operation.exec;

import jvc.model.JSpec;
import jvc.model.operation.JSingleOperationContext;
import jvc.operation.AdjustSpeedOperation;
import lombok.extern.slf4j.Slf4j;


+ 25
- 2
src/main/java/jvc/operation/exec/ExecBase.java Ver fichero

@@ -1,11 +1,16 @@
package jvc.operation.exec;

import jvc.model.JAsset;
import jvc.model.JSpec;
import jvc.model.JStreamType;
import jvc.model.operation.JOperation;
import jvc.service.AssetManager;
import jvc.service.Toolbox;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.cobbzilla.util.collection.NameAndValue;
import org.cobbzilla.util.handlebars.HandlebarsUtil;

import java.io.File;
@@ -15,13 +20,22 @@ import java.util.Map;

import static jvc.service.Toolbox.jsContext;
import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.util.io.FileUtil.abs;
import static org.cobbzilla.util.io.FileUtil.basename;
import static org.cobbzilla.util.system.CommandShell.execScript;

@Slf4j
@Slf4j @Accessors(chain=true)
public abstract class ExecBase<OP extends JOperation> {

@Getter @Setter private JSpec spec;

public NameAndValue[] getVars () {
return spec == null || empty(spec.getVars())
? NameAndValue.EMPTY_ARRAY
: spec.getVars();
}

public abstract Map<String, Object> operate(OP operation, Toolbox toolbox, AssetManager assetManager);

protected String renderScript(Toolbox toolbox, Map<String, Object> ctx, String template) {
@@ -43,10 +57,19 @@ public abstract class ExecBase<OP extends JOperation> {
}
}

protected Map<String, Object> initialContext(Toolbox toolbox, JAsset source) {
protected Map<String, Object> initialContext(Toolbox toolbox, JAsset source, NameAndValue[] vars) {
final Map<String, Object> ctx = new HashMap<>();
ctx.put("ffmpeg", toolbox.getFfmpeg());
ctx.put("source", source);
if (!empty(vars)) {
for (NameAndValue var : vars) {
final String name = var.getName();
if (ctx.containsKey(name)) {
log.warn("initialContext: spec variable "+ name +" will mask existing value: "+ctx.get(name));
}
ctx.put(name, var.getValue());
}
}
return ctx;
}



+ 1
- 1
src/main/java/jvc/operation/exec/KenBurnsExec.java Ver fichero

@@ -57,7 +57,7 @@ public class KenBurnsExec extends ExecBase<KenBurnsOperation> {
output.setPath(abs(path));

final JsEngine js = toolbox.getJs();
final Map<String, Object> ctx = initialContext(toolbox, source);
final Map<String, Object> ctx = initialContext(toolbox, source, getVars());
ctx.put("output", output);
ctx.put("width", op.getWidth(ctx, js));
ctx.put("height", op.getHeight(ctx, js));


+ 1
- 1
src/main/java/jvc/operation/exec/OverlayExec.java Ver fichero

@@ -40,7 +40,7 @@ public class OverlayExec extends ExecBase<OverlayOperation> {
output.setPath(abs(path));

final JsEngine js = toolbox.getJs();
final Map<String, Object> ctx = initialContext(toolbox, source);
final Map<String, Object> ctx = initialContext(toolbox, source, getVars());
ctx.put("overlay", overlaySource);

ctx.put("mainStart", op.getStartTime(ctx, js));


+ 1
- 1
src/main/java/jvc/operation/exec/SingleOrMultiSourceExecBase.java Ver fichero

@@ -22,7 +22,7 @@ public abstract class SingleOrMultiSourceExecBase<OP extends JSingleSourceOperat
final JAsset source = opCtx.source;
final JAsset output = opCtx.output;
final JStreamType streamType = opCtx.streamType;
final Map<String, Object> ctx = initialContext(toolbox, source);
final Map<String, Object> ctx = initialContext(toolbox, source, getVars());
addCommandContext(op, opCtx, ctx);
return operate(op, toolbox, assetManager, source, output, streamType, ctx);
}


+ 1
- 1
src/main/java/jvc/operation/exec/SplitExec.java Ver fichero

@@ -31,7 +31,7 @@ public class SplitExec extends ExecBase<SplitOperation> {
final JStreamType streamType = opCtx.streamType;

final JsEngine js = toolbox.getJs();
final Map<String, Object> ctx = initialContext(toolbox, source);
final Map<String, Object> ctx = initialContext(toolbox, source, getVars());

assetManager.addOperationArrayAsset(output);
final BigDecimal incr = op.getIntervalIncr(ctx, js);


+ 3
- 3
src/main/java/jvc/service/JvcEngine.java Ver fichero

@@ -31,15 +31,15 @@ public class JvcEngine {

public void runSpec(JSpec spec) {
Arrays.stream(spec.getAssets()).forEach(assetManager::defineAsset);
Arrays.stream(spec.getOperations()).forEach(this::runOp);
Arrays.stream(spec.getOperations()).forEach(op -> runOp(spec, op));
}

private void runOp(JOperation op) {
private void runOp(JSpec spec, JOperation op) {

final ExecBase<JOperation> exec = op
.setExecIndex(completed.size())
.setNoExec(noExec)
.getExec();
.getExec(spec);

final Map<String, Object> ctx = exec.operate(op, toolbox, assetManager);
if (ctx == null) {


+ 0
- 2
src/test/resources/tests/test_overlay.jvc Ver fichero

@@ -42,8 +42,6 @@
"operation": "overlay", // name of the operation
"creates": {
"name": "overlay1", // name of the output asset
"width": "1920", // output width in pixels. default is source width
"height": "1024", // output height in pixes. default is source height
"dest": "src/test/resources/outputs/overlay/"
},
"source": "v1", // main video asset


+ 8
- 2
src/test/resources/tests/test_scale.jvc Ver fichero

@@ -1,4 +1,8 @@
{
"vars": [
{"name": "out_width", "value": "1024"},
{"name": "out_height", "value": "768"}
],
"assets": [
// wildcard matches multiple files, vid1_splits becomes a "list" asset. resolution is 320x240
{ "name": "vid1_splits", "path": "src/test/resources/outputs/vid1_splits_*.mp4" }
@@ -8,8 +12,10 @@
"operation": "scale", // name of the operation
"creates": "scaled_test1", // output asset name
"source": "vid1_splits[3]", // scale this source asset
"width": "1024", // width of scaled asset. if omitted and height is present, width will be proportional
"height": "768", // height of scaled asset. if omitted and width is present, height will be proportional
"width": "out_width", // width of scaled asset. if omitted and height is present, width will be proportional
// here we reference the `out_width` variable defined above in the `vars` array
"height": "out_height", // height of scaled asset. if omitted and width is present, height will be proportional
// here we reference the `out_height` variable defined above in the `vars` array
"validate": [{
"comment": "expect output resolution of 1024x768",
"test": "output.width === 1024 && output.height === 768"


Cargando…
Cancelar
Guardar