From 02a598ed2e08c0fa1451e87370610bba66088f1e Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Tue, 15 Dec 2020 13:37:49 -0500 Subject: [PATCH] compose overlay filter using StringBuilder --- .../java/jvcl/operation/OverlayOperation.java | 4 +- .../java/jvcl/operation/exec/OverlayExec.java | 38 +++++++++++++++---- src/main/java/jvcl/service/Toolbox.java | 8 +++- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/main/java/jvcl/operation/OverlayOperation.java b/src/main/java/jvcl/operation/OverlayOperation.java index 67438dd..4d53d73 100644 --- a/src/main/java/jvcl/operation/OverlayOperation.java +++ b/src/main/java/jvcl/operation/OverlayOperation.java @@ -22,12 +22,12 @@ public class OverlayOperation extends JOperation { @Getter @Setter private OverlayConfig overlay; @Getter @Setter private String start; - public BigDecimal getStartSeconds(Map ctx, JsEngine js) { + public BigDecimal getStartTime(Map ctx, JsEngine js) { return empty(start) ? BigDecimal.ZERO : getDuration(eval(start, ctx, js)); } @Getter @Setter private String end; - public BigDecimal getEndSeconds(Map ctx, JsEngine js) { + public BigDecimal getEndTime(Map ctx, JsEngine js) { return empty(end) ? BigDecimal.ZERO : getDuration(eval(end, ctx, js)); } diff --git a/src/main/java/jvcl/operation/exec/OverlayExec.java b/src/main/java/jvcl/operation/exec/OverlayExec.java index 2725a4b..9f7a878 100644 --- a/src/main/java/jvcl/operation/exec/OverlayExec.java +++ b/src/main/java/jvcl/operation/exec/OverlayExec.java @@ -9,6 +9,7 @@ import lombok.extern.slf4j.Slf4j; import org.cobbzilla.util.javascript.StandardJsEngine; import java.io.File; +import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; @@ -24,9 +25,9 @@ public class OverlayExec extends ExecBase { public static final String OVERLAY_TEMPLATE = "ffmpeg -i {{{source.path}}} -vf \"" + " movie={{{overlay.path}}}:seek_point=0 [ovl]; " - + " [ovl] setpts=PTS-STARTPTS, scale=160x160 [ovl2] ; " - + " [main][ovl2] overlay=enable=between(t\\,15\\,20):x=160:y=120\" " - + "{{{output.path}}}"; + + " [ovl] setpts=PTS-STARTPTS{{#exists width}}, scale={{width}}x{{height}}{{/exists}} [ovl2] ; " + + " [main][ovl2] overlay={{{overlayFilterConfig}}}" + + "\" {{{output.path}}}"; @Override public void operate(OverlayOperation op, Toolbox toolbox, AssetManager assetManager) { final JAsset source = assetManager.resolve(op.getSource()); @@ -48,10 +49,14 @@ public class OverlayExec extends ExecBase { ctx.put("ffmpeg", toolbox.getFfmpeg()); ctx.put("source", source); ctx.put("overlay", overlaySource); + + ctx.put("mainStart", op.getStartTime(ctx, js)); + ctx.put("mainEnd", op.getEndTime(ctx, js)); + + final String overlayFilter = buildOverlayFilter(op, source, overlay, ctx, js); + ctx.put("overlayFilterConfig", overlayFilter); ctx.put("output", output); - ctx.put("offset", op.getStartSeconds(ctx, js)); - ctx.put("overlayStart", overlay.getStartTime(ctx, js)); - if (overlay.hasEndTime()) ctx.put("overlayEnd", overlay.getEndTime(ctx, js)); + if (overlay.hasWidth()) { final String width = overlay.getWidth(ctx, js); ctx.put("width", width); @@ -68,8 +73,6 @@ public class OverlayExec extends ExecBase { ctx.put("width", width); } } - if (overlay.hasX()) ctx.put("x", overlay.getX(ctx, js)); - if (overlay.hasY()) ctx.put("y", overlay.getY(ctx, js)); final String script = renderScript(toolbox, ctx, OVERLAY_TEMPLATE); @@ -79,4 +82,23 @@ public class OverlayExec extends ExecBase { assetManager.addOperationAsset(output); } + private String buildOverlayFilter(OverlayOperation op, JAsset source, OverlayOperation.OverlayConfig overlay, Map ctx, StandardJsEngine js) { + // enable=between(t\,15\,20):x=160:y=120 + final StringBuilder b = new StringBuilder(); + final BigDecimal startTime = overlay.getStartTime(ctx, js); + if (overlay.hasEndTime()) { + final BigDecimal endTime = overlay.getEndTime(ctx, js); + b.append("enable=between(t\\,").append(startTime).append("\\,").append(endTime).append(")"); + } else if (startTime.intValue() > 0) { + b.append("enable=gte(t\\,").append(startTime).append(")"); + } + + if (overlay.hasX() && overlay.hasY()) { + if (b.length() > 0) b.append(":"); + b.append("x=").append(overlay.getX(ctx, js)).append(":y=").append(overlay.getY(ctx, js)); + } + + return b.toString(); + } + } diff --git a/src/main/java/jvcl/service/Toolbox.java b/src/main/java/jvcl/service/Toolbox.java index 471eb3c..3f0fc35 100644 --- a/src/main/java/jvcl/service/Toolbox.java +++ b/src/main/java/jvcl/service/Toolbox.java @@ -37,8 +37,12 @@ public class Toolbox { public static String eval(String val, Map ctx, JsEngine js) { final Map jsCtx = Toolbox.jsContext(ctx); - final Object result = js.evaluate(val, jsCtx); - return result == null ? null : result.toString(); + try { + final Object result = js.evaluate(val, jsCtx); + return result == null ? null : result.toString(); + } catch (Exception e) { + return die("eval: error evaluating: '"+val+"': "+shortError(e)); + } } public static BigDecimal getDuration(String t) {