Browse Source

rename JFileExtension -> JStreamType, fix remove-track handling of data/other tracks

master
Jonathan Cobb 3 years ago
parent
commit
6888bb502f
21 changed files with 111 additions and 97 deletions
  1. +4
    -1
      docs/jvc_js.md
  2. +2
    -2
      src/main/java/jvc/model/JAsset.java
  3. +3
    -3
      src/main/java/jvc/model/JFormat.java
  4. +4
    -3
      src/main/java/jvc/model/JStreamType.java
  5. +10
    -10
      src/main/java/jvc/model/info/JMediaInfo.java
  6. +11
    -10
      src/main/java/jvc/model/info/JTrackType.java
  7. +4
    -1
      src/main/java/jvc/model/js/JAssetJs.java
  8. +3
    -3
      src/main/java/jvc/model/operation/JMultiOperationContext.java
  9. +3
    -3
      src/main/java/jvc/model/operation/JMultiSourceOperation.java
  10. +2
    -2
      src/main/java/jvc/model/operation/JOperationContextBase.java
  11. +3
    -3
      src/main/java/jvc/model/operation/JSingleOperationContext.java
  12. +9
    -9
      src/main/java/jvc/model/operation/JSingleSourceOperation.java
  13. +8
    -8
      src/main/java/jvc/operation/RemoveTrackOperation.java
  14. +3
    -3
      src/main/java/jvc/operation/exec/ConcatExec.java
  15. +3
    -3
      src/main/java/jvc/operation/exec/ExecBase.java
  16. +3
    -3
      src/main/java/jvc/operation/exec/KenBurnsExec.java
  17. +3
    -3
      src/main/java/jvc/operation/exec/MergeAudioExec.java
  18. +3
    -3
      src/main/java/jvc/operation/exec/OverlayExec.java
  19. +12
    -6
      src/main/java/jvc/operation/exec/SingleOrMultiSourceExecBase.java
  20. +7
    -7
      src/main/java/jvc/operation/exec/SplitExec.java
  21. +11
    -11
      src/main/java/jvc/service/AssetManager.java

+ 4
- 1
docs/jvc_js.md View File

@@ -68,7 +68,10 @@ Ratio of width / height (video or image).
Sampling rate in Hz (audio). Sampling rate in Hz (audio).


#### `tracks` #### `tracks`
An array of the tracks in a video. Only includes audio and video tracks.
An array of the A/V tracks in a video. Only includes audio and video tracks.

#### `allTracks`
An array of **all** the tracks in a video. Includes subtitles/data/other tracks.


#### `audioTracks` #### `audioTracks`
An array of the audio tracks in a video. An array of the audio tracks in a video.


+ 2
- 2
src/main/java/jvc/model/JAsset.java View File

@@ -181,8 +181,8 @@ public class JAsset implements JsObjectView {
@JsonIgnore public String getChannelLayout() { return channelLayout(); } @JsonIgnore public String getChannelLayout() { return channelLayout(); }
public boolean hasChannelLayout() { return channelLayout() != null; } public boolean hasChannelLayout() { return channelLayout() != null; }


public JFileExtension audioExtension() { return hasInfo() ? getInfo().audioExtension() : null; }
@JsonIgnore public JFileExtension getAudioExtension() { return audioExtension(); }
public JStreamType audioExtension() { return hasInfo() ? getInfo().audioExtension() : null; }
@JsonIgnore public JStreamType getAudioExtension() { return audioExtension(); }
public boolean hasAudioExtension() { return audioExtension() != null; } public boolean hasAudioExtension() { return audioExtension() != null; }


public JAsset init(AssetManager assetManager, Toolbox toolbox) { public JAsset init(AssetManager assetManager, Toolbox toolbox) {


+ 3
- 3
src/main/java/jvc/model/JFormat.java View File

@@ -16,15 +16,15 @@ public class JFormat {
@Getter @Setter private Integer width; @Getter @Setter private Integer width;
public boolean hasWidth () { return width != null; } public boolean hasWidth () { return width != null; }


@Getter @Setter private JFileExtension fileExtension;
public boolean hasFileExtension() { return fileExtension != null; }
@Getter @Setter private JStreamType streamType;
public boolean hasFileExtension() { return streamType != null; }


public JFormat(JFormat format) { copy(this, format); } public JFormat(JFormat format) { copy(this, format); }


public void merge(JFormat other) { public void merge(JFormat other) {
if (!hasHeight()) setHeight(other.getHeight()); if (!hasHeight()) setHeight(other.getHeight());
if (!hasWidth()) setWidth(other.getWidth()); if (!hasWidth()) setWidth(other.getWidth());
if (!hasFileExtension()) setFileExtension(other.getFileExtension());
if (!hasFileExtension()) setStreamType(other.getStreamType());
} }


} }

src/main/java/jvc/model/JFileExtension.java → src/main/java/jvc/model/JStreamType.java View File

@@ -10,10 +10,11 @@ import static jvc.model.info.JTrackType.*;
import static org.cobbzilla.util.daemon.ZillaRuntime.die; import static org.cobbzilla.util.daemon.ZillaRuntime.die;


@AllArgsConstructor @Slf4j @AllArgsConstructor @Slf4j
public enum JFileExtension {
public enum JStreamType {


avc (".mp4", video), avc (".mp4", video),
mp4 (".mp4", video), mp4 (".mp4", video),
hevc (".mp4", video),
mkv (".mkv", video), mkv (".mkv", video),
mp3 (".mp3", audio), mp3 (".mp3", audio),
mpeg_audio (".mp3", audio), mpeg_audio (".mp3", audio),
@@ -26,7 +27,7 @@ public enum JFileExtension {
dat (".dat", data), dat (".dat", data),
txt (".txt", data); txt (".txt", data);


@JsonCreator public static JFileExtension fromString(String v) { return valueOf(v.toLowerCase()); }
@JsonCreator public static JStreamType fromString(String v) { return valueOf(v.toLowerCase()); }


public static boolean isValid(String v) { public static boolean isValid(String v) {
try { fromString(v); return true; } catch (Exception ignored) {} try { fromString(v); return true; } catch (Exception ignored) {}
@@ -39,7 +40,7 @@ public enum JFileExtension {
private final JTrackType mediaType; private final JTrackType mediaType;
public JTrackType mediaType() { return mediaType; } public JTrackType mediaType() { return mediaType; }


public static JFileExtension fromTrack(JTrack track) {
public static JStreamType fromTrack(JTrack track) {
if (track.hasFileExtension()) { if (track.hasFileExtension()) {
try { try {
return fromString(track.getFileExtension()); return fromString(track.getFileExtension());

+ 10
- 10
src/main/java/jvc/model/info/JMediaInfo.java View File

@@ -1,6 +1,6 @@
package jvc.model.info; package jvc.model.info;


import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.JFormat; import jvc.model.JFormat;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@@ -65,19 +65,19 @@ public class JMediaInfo {


final JFormat format = new JFormat(); final JFormat format = new JFormat();
if (video != null) { if (video != null) {
format.setFileExtension(video.hasFormat()
? JFileExtension.fromTrack(video)
: JFileExtension.fromString(general.getFileExtension()))
format.setStreamType(video.hasFormat()
? JStreamType.fromTrack(video)
: JStreamType.fromString(general.getFileExtension()))
.setHeight(video.height()) .setHeight(video.height())
.setWidth(video.width()); .setWidth(video.width());


} else if (audio != null) { } else if (audio != null) {
format.setFileExtension(audio.hasFormat()
? JFileExtension.fromTrack(audio)
: JFileExtension.fromString(general.getFileExtension()));
format.setStreamType(audio.hasFormat()
? JStreamType.fromTrack(audio)
: JStreamType.fromString(general.getFileExtension()));


} else if (image != null) { } else if (image != null) {
format.setFileExtension(JFileExtension.fromString(general.getFileExtension()))
format.setStreamType(JStreamType.fromString(general.getFileExtension()))
.setHeight(image.height()) .setHeight(image.height())
.setWidth(image.width()); .setWidth(image.width());


@@ -120,9 +120,9 @@ public class JMediaInfo {
return null; return null;
} }


public JFileExtension audioExtension() {
public JStreamType audioExtension() {
final JTrack audio = firstTrack(JTrackType.audio); final JTrack audio = firstTrack(JTrackType.audio);
return audio == null ? null : JFileExtension.fromTrack(audio);
return audio == null ? null : JStreamType.fromTrack(audio);
} }


public BigDecimal width() { public BigDecimal width() {


+ 11
- 10
src/main/java/jvc/model/info/JTrackType.java View File

@@ -1,24 +1,25 @@
package jvc.model.info; package jvc.model.info;


import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;


@AllArgsConstructor @AllArgsConstructor
public enum JTrackType { public enum JTrackType {


general (null, null),
audio (JFileExtension.flac, "a"),
video (JFileExtension.mp4, "v"),
image (JFileExtension.png, null),
subtitle(JFileExtension.png, "s"),
data (JFileExtension.png, "d"),
other (null, null);
general (null, null),
audio (JStreamType.flac, "a"),
video (JStreamType.mp4, "v"),
image (JStreamType.png, null),
subtitle (JStreamType.sub, "s"),
other (JStreamType.dat, "d"),
data (JStreamType.dat, "d"),
attachment(null, "t");


@JsonCreator public static JTrackType fromString(String val) { return valueOf(val.toLowerCase()); } @JsonCreator public static JTrackType fromString(String val) { return valueOf(val.toLowerCase()); }


private final JFileExtension ext;
public JFileExtension ext() { return ext; }
private final JStreamType streamType;
public JStreamType streamType() { return streamType; }


private final String ffmpegType; private final String ffmpegType;
public String ffmpegType() { return ffmpegType; } public String ffmpegType() { return ffmpegType; }


+ 4
- 1
src/main/java/jvc/model/js/JAssetJs.java View File

@@ -18,6 +18,7 @@ public class JAssetJs {
public Integer height; public Integer height;
public Double aspectRatio; public Double aspectRatio;
public Integer samplingRate; public Integer samplingRate;
public JTrackJs[] allTracks = EMPTY_TRACKS;
public JTrackJs[] tracks = EMPTY_TRACKS; public JTrackJs[] tracks = EMPTY_TRACKS;
public JTrackJs[] videoTracks = EMPTY_TRACKS; public JTrackJs[] videoTracks = EMPTY_TRACKS;
public JTrackJs[] audioTracks = EMPTY_TRACKS; public JTrackJs[] audioTracks = EMPTY_TRACKS;
@@ -40,9 +41,11 @@ public class JAssetJs {
final JMediaInfo info = asset.getInfo(); final JMediaInfo info = asset.getInfo();
for (JTrack track : info.getMedia().getTrack()) { for (JTrack track : info.getMedia().getTrack()) {


final JTrackJs trackJs = new JTrackJs(track.type().name());
allTracks = ArrayUtil.append(allTracks, trackJs);

if (!track.audioOrVideo()) continue; if (!track.audioOrVideo()) continue;


final JTrackJs trackJs = new JTrackJs(track.type().name());
tracks = ArrayUtil.append(tracks, trackJs); tracks = ArrayUtil.append(tracks, trackJs);
switch (track.type()) { switch (track.type()) {
case audio: case audio:


+ 3
- 3
src/main/java/jvc/model/operation/JMultiOperationContext.java View File

@@ -1,7 +1,7 @@
package jvc.model.operation; package jvc.model.operation;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.service.AssetManager; import jvc.service.AssetManager;
import jvc.service.Toolbox; import jvc.service.Toolbox;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@@ -15,10 +15,10 @@ public class JMultiOperationContext extends JOperationContextBase {


public JMultiOperationContext(List<JAsset> sources, public JMultiOperationContext(List<JAsset> sources,
JAsset output, JAsset output,
JFileExtension formatType,
JStreamType streamType,
AssetManager assetManager, AssetManager assetManager,
Toolbox toolbox) { Toolbox toolbox) {
super(output, formatType, assetManager, toolbox);
super(output, streamType, assetManager, toolbox);
this.sources = sources; this.sources = sources;
} }
} }

+ 3
- 3
src/main/java/jvc/model/operation/JMultiSourceOperation.java View File

@@ -1,7 +1,7 @@
package jvc.model.operation; package jvc.model.operation;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.service.AssetManager; import jvc.service.AssetManager;
import jvc.service.Toolbox; import jvc.service.Toolbox;
import lombok.Getter; import lombok.Getter;
@@ -30,8 +30,8 @@ public abstract class JMultiSourceOperation extends JOperation {
output.mergeFormat(sources.get(0).getFormat()); output.mergeFormat(sources.get(0).getFormat());


// set the path, check if output asset already exists // set the path, check if output asset already exists
final JFileExtension formatType = output.getFormat().getFileExtension();
final JStreamType streamType = output.getFormat().getStreamType();


return new JMultiOperationContext(sources, output, formatType, assetManager, toolbox);
return new JMultiOperationContext(sources, output, streamType, assetManager, toolbox);
} }
} }

+ 2
- 2
src/main/java/jvc/model/operation/JOperationContextBase.java View File

@@ -1,7 +1,7 @@
package jvc.model.operation; package jvc.model.operation;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.service.AssetManager; import jvc.service.AssetManager;
import jvc.service.Toolbox; import jvc.service.Toolbox;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@@ -11,7 +11,7 @@ import lombok.NoArgsConstructor;
public class JOperationContextBase { public class JOperationContextBase {


public JAsset output; public JAsset output;
public JFileExtension formatType;
public JStreamType streamType;
public AssetManager assetManager; public AssetManager assetManager;
public Toolbox toolbox; public Toolbox toolbox;




+ 3
- 3
src/main/java/jvc/model/operation/JSingleOperationContext.java View File

@@ -1,7 +1,7 @@
package jvc.model.operation; package jvc.model.operation;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.service.AssetManager; import jvc.service.AssetManager;
import jvc.service.Toolbox; import jvc.service.Toolbox;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@@ -14,10 +14,10 @@ public class JSingleOperationContext extends JOperationContextBase {


public JSingleOperationContext(JAsset source, public JSingleOperationContext(JAsset source,
JAsset output, JAsset output,
JFileExtension formatType,
JStreamType streamType,
AssetManager assetManager, AssetManager assetManager,
Toolbox toolbox) { Toolbox toolbox) {
super(output, formatType, assetManager, toolbox);
super(output, streamType, assetManager, toolbox);
this.source = source; this.source = source;
} }




+ 9
- 9
src/main/java/jvc/model/operation/JSingleSourceOperation.java View File

@@ -1,7 +1,7 @@
package jvc.model.operation; package jvc.model.operation;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.JFormat; import jvc.model.JFormat;
import jvc.model.info.JTrackType; import jvc.model.info.JTrackType;
import jvc.service.AssetManager; import jvc.service.AssetManager;
@@ -27,20 +27,20 @@ public class JSingleSourceOperation extends JOperation {
// ensure output is in the correct format // ensure output is in the correct format
final JFormat format = output.getFormat(); final JFormat format = output.getFormat();
final JTrackType type = outputMediaType(); final JTrackType type = outputMediaType();
if (!format.hasFileExtension() || format.getFileExtension().mediaType() != type) {
final JFileExtension ext = type.ext();
if (ext == null) {
if (!format.hasFileExtension() || format.getStreamType().mediaType() != type) {
final JStreamType streamType = type.streamType();
if (streamType == null) {
return die("getSingleInputContext: no file extension found for output media type: " + type); return die("getSingleInputContext: no file extension found for output media type: " + type);
} }
format.setFileExtension(ext);
format.setStreamType(streamType);
} }
final JFileExtension formatType = getFileExtension(source, output);
final JStreamType streamType = getStreamType(source, output);


return new JSingleOperationContext(source, output, formatType, assetManager, toolbox);
return new JSingleOperationContext(source, output, streamType, assetManager, toolbox);
} }


protected JFileExtension getFileExtension(JAsset source, JAsset output) {
return output.getFormat().getFileExtension();
protected JStreamType getStreamType(JAsset source, JAsset output) {
return output.getFormat().getStreamType();
} }


} }

+ 8
- 8
src/main/java/jvc/operation/RemoveTrackOperation.java View File

@@ -3,7 +3,7 @@ package jvc.operation;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.JFormat; import jvc.model.JFormat;
import jvc.model.JTrackId; import jvc.model.JTrackId;
import jvc.model.info.JMediaInfo; import jvc.model.info.JMediaInfo;
@@ -28,25 +28,25 @@ public class RemoveTrackOperation extends JSingleSourceOperation {
return trackId; return trackId;
} }


@Override protected JFileExtension getFileExtension(JAsset source, JAsset output) {
@Override protected JStreamType getStreamType(JAsset source, JAsset output) {


final JTrackId trackId = getTrackId(); final JTrackId trackId = getTrackId();
final JTrackType trackType = trackId.getType(); final JTrackType trackType = trackId.getType();


// if we are removing all video tracks, the output will be an audio asset // if we are removing all video tracks, the output will be an audio asset
final int trackCount = source.numTracks(trackType); final int trackCount = source.numTracks(trackType);
if (trackCount == 0) return die("getFileExtension: no tracks of type "+ trackType +" found in source: "+source);
if (trackCount == 0) return die("getStreamType: no tracks of type "+ trackType +" found in source: "+source);


if (wouldRemoveAllVideoTracks(trackId, trackCount)) { if (wouldRemoveAllVideoTracks(trackId, trackCount)) {
// find the format of the first audio track // find the format of the first audio track
final JTrack audio = source.firstTrack(JTrackType.audio); final JTrack audio = source.firstTrack(JTrackType.audio);
if (audio == null) return die("getFileExtension: no audio tracks found!");
final JFileExtension ext = JFileExtension.fromTrack(audio);
source.setInfo(new JMediaInfo(source.getInfo(), new JFormat().setFileExtension(ext)));
return ext;
if (audio == null) return die("getStreamType: no audio tracks found!");
final JStreamType streamType = JStreamType.fromTrack(audio);
source.setInfo(new JMediaInfo(source.getInfo(), new JFormat().setStreamType(streamType)));
return streamType;
} }


return super.getFileExtension(source, output);
return super.getStreamType(source, output);
} }


private boolean wouldRemoveAllVideoTracks(JTrackId trackId, int trackCount) { private boolean wouldRemoveAllVideoTracks(JTrackId trackId, int trackCount) {


+ 3
- 3
src/main/java/jvc/operation/exec/ConcatExec.java View File

@@ -1,7 +1,7 @@
package jvc.operation.exec; package jvc.operation.exec;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.operation.JMultiOperationContext; import jvc.model.operation.JMultiOperationContext;
import jvc.operation.ConcatOperation; import jvc.operation.ConcatOperation;
import jvc.service.AssetManager; import jvc.service.AssetManager;
@@ -36,9 +36,9 @@ public class ConcatExec extends ExecBase<ConcatOperation> {
final JMultiOperationContext opCtx = op.getMultiInputContext(assetManager, toolbox); final JMultiOperationContext opCtx = op.getMultiInputContext(assetManager, toolbox);
final List<JAsset> sources = opCtx.sources; final List<JAsset> sources = opCtx.sources;
final JAsset output = opCtx.output; final JAsset output = opCtx.output;
final JFileExtension formatType = opCtx.formatType;
final JStreamType streamType = opCtx.streamType;


final File defaultOutfile = assetManager.assetPath(op, sources, formatType);
final File defaultOutfile = assetManager.assetPath(op, sources, streamType);
final File path = resolveOutputPath(output, defaultOutfile); final File path = resolveOutputPath(output, defaultOutfile);
if (path == null) return null; if (path == null) return null;
output.setPath(abs(path)); output.setPath(abs(path));


+ 3
- 3
src/main/java/jvc/operation/exec/ExecBase.java View File

@@ -1,7 +1,7 @@
package jvc.operation.exec; package jvc.operation.exec;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.operation.JOperation; import jvc.model.operation.JOperation;
import jvc.service.AssetManager; import jvc.service.AssetManager;
import jvc.service.Toolbox; import jvc.service.Toolbox;
@@ -79,8 +79,8 @@ public abstract class ExecBase<OP extends JOperation> {
if (!asset.hasChannelLayout()) return die("createSilence: no channel layout could be determined: "+asset); if (!asset.hasChannelLayout()) return die("createSilence: no channel layout could be determined: "+asset);
ctx.put("channelLayout", asset.channelLayout()); ctx.put("channelLayout", asset.channelLayout());


final JFileExtension ext = asset.audioExtension();
final File silenceFile = assetManager.assetPath(op, asset, ext, new Object[]{duration});
final JStreamType streamType = asset.audioExtension();
final File silenceFile = assetManager.assetPath(op, asset, streamType, new Object[]{duration});
final JAsset silence = new JAsset().setPath(abs(silenceFile)); final JAsset silence = new JAsset().setPath(abs(silenceFile));
ctx.put("silence", silence); ctx.put("silence", silence);




+ 3
- 3
src/main/java/jvc/operation/exec/KenBurnsExec.java View File

@@ -2,7 +2,7 @@ package jvc.operation.exec;




import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.operation.JSingleOperationContext; import jvc.model.operation.JSingleOperationContext;
import jvc.operation.KenBurnsOperation; import jvc.operation.KenBurnsOperation;
import jvc.service.AssetManager; import jvc.service.AssetManager;
@@ -49,9 +49,9 @@ public class KenBurnsExec extends ExecBase<KenBurnsOperation> {
final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox); final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox);
final JAsset source = opCtx.source; final JAsset source = opCtx.source;
final JAsset output = opCtx.output; final JAsset output = opCtx.output;
final JFileExtension formatType = opCtx.formatType;
final JStreamType streamType = opCtx.streamType;


final File defaultOutfile = assetManager.assetPath(op, source, formatType);
final File defaultOutfile = assetManager.assetPath(op, source, streamType);
final File path = resolveOutputPath(output, defaultOutfile); final File path = resolveOutputPath(output, defaultOutfile);
if (path == null) return null; if (path == null) return null;
output.setPath(abs(path)); output.setPath(abs(path));


+ 3
- 3
src/main/java/jvc/operation/exec/MergeAudioExec.java View File

@@ -1,7 +1,7 @@
package jvc.operation.exec; package jvc.operation.exec;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.operation.JSingleOperationContext; import jvc.model.operation.JSingleOperationContext;
import jvc.operation.MergeAudioOperation; import jvc.operation.MergeAudioOperation;
import jvc.service.AssetManager; import jvc.service.AssetManager;
@@ -57,8 +57,8 @@ public class MergeAudioExec extends SingleOrMultiSourceExecBase<MergeAudioOperat
final Map<String, Object> ctx = new HashMap<>(); final Map<String, Object> ctx = new HashMap<>();
ctx.put("ffmpeg", toolbox.getFfmpeg()); ctx.put("ffmpeg", toolbox.getFfmpeg());


final JFileExtension ext = audio.getFormat().getFileExtension();
final JAsset padded = new JAsset().setPath(abs(assetManager.assetPath(op, audio, ext)));
final JStreamType streamType = audio.getFormat().getStreamType();
final JAsset padded = new JAsset().setPath(abs(assetManager.assetPath(op, audio, streamType)));
final String paddedName = basename(padded.getPath()); final String paddedName = basename(padded.getPath());
ctx.put("padded", paddedName); ctx.put("padded", paddedName);




+ 3
- 3
src/main/java/jvc/operation/exec/OverlayExec.java View File

@@ -1,7 +1,7 @@
package jvc.operation.exec; package jvc.operation.exec;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.operation.JSingleOperationContext; import jvc.model.operation.JSingleOperationContext;
import jvc.operation.OverlayOperation; import jvc.operation.OverlayOperation;
import jvc.service.AssetManager; import jvc.service.AssetManager;
@@ -29,12 +29,12 @@ public class OverlayExec extends ExecBase<OverlayOperation> {
final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox); final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox);
final JAsset source = opCtx.source; final JAsset source = opCtx.source;
final JAsset output = opCtx.output; final JAsset output = opCtx.output;
final JFileExtension formatType = opCtx.formatType;
final JStreamType streamType = opCtx.streamType;


final OverlayOperation.OverlayConfig overlay = op.getOverlay(); final OverlayOperation.OverlayConfig overlay = op.getOverlay();
final JAsset overlaySource = assetManager.resolve(overlay.getSource()); final JAsset overlaySource = assetManager.resolve(overlay.getSource());


final File defaultOutfile = assetManager.assetPath(op, source, formatType);
final File defaultOutfile = assetManager.assetPath(op, source, streamType);
final File path = resolveOutputPath(output, defaultOutfile); final File path = resolveOutputPath(output, defaultOutfile);
if (path == null) return null; if (path == null) return null;
output.setPath(abs(path)); output.setPath(abs(path));


+ 12
- 6
src/main/java/jvc/operation/exec/SingleOrMultiSourceExecBase.java View File

@@ -1,7 +1,7 @@
package jvc.operation.exec; package jvc.operation.exec;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.operation.JSingleOperationContext; import jvc.model.operation.JSingleOperationContext;
import jvc.model.operation.JSingleSourceOperation; import jvc.model.operation.JSingleSourceOperation;
import jvc.service.AssetManager; import jvc.service.AssetManager;
@@ -21,15 +21,21 @@ public abstract class SingleOrMultiSourceExecBase<OP extends JSingleSourceOperat
final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox); final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox);
final JAsset source = opCtx.source; final JAsset source = opCtx.source;
final JAsset output = opCtx.output; final JAsset output = opCtx.output;
final JFileExtension formatType = opCtx.formatType;
final JStreamType streamType = opCtx.streamType;
final Map<String, Object> ctx = initialContext(toolbox, source); final Map<String, Object> ctx = initialContext(toolbox, source);
addCommandContext(op, opCtx, ctx); addCommandContext(op, opCtx, ctx);
return operate(op, toolbox, assetManager, source, output, formatType, ctx);
return operate(op, toolbox, assetManager, source, output, streamType, ctx);
} }


protected void addCommandContext(OP op, JSingleOperationContext opCtx, Map<String, Object> ctx) {} protected void addCommandContext(OP op, JSingleOperationContext opCtx, Map<String, Object> ctx) {}


protected Map<String, Object> operate(OP op, Toolbox toolbox, AssetManager assetManager, JAsset source, JAsset output, JFileExtension formatType, Map<String, Object> ctx) {
protected Map<String, Object> operate(OP op,
Toolbox toolbox,
AssetManager assetManager,
JAsset source,
JAsset output,
JStreamType streamType,
Map<String, Object> ctx) {
if (source.hasList()) { if (source.hasList()) {
if (output.hasDest()) { if (output.hasDest()) {
if (!output.destIsDirectory()) die("operate: dest is not a directory: "+output.getDest()); if (!output.destIsDirectory()) die("operate: dest is not a directory: "+output.getDest());
@@ -37,7 +43,7 @@ public abstract class SingleOrMultiSourceExecBase<OP extends JSingleSourceOperat
assetManager.addOperationArrayAsset(output); assetManager.addOperationArrayAsset(output);
for (JAsset asset : source.getList()) { for (JAsset asset : source.getList()) {
final JAsset subOutput = new JAsset(output); final JAsset subOutput = new JAsset(output);
final File defaultOutfile = assetManager.assetPath(op, asset, formatType);
final File defaultOutfile = assetManager.assetPath(op, asset, streamType);
final File outfile; final File outfile;
if (output.hasDest()) { if (output.hasDest()) {
outfile = new File(output.destDirectory(), basename(appendToFileNameBeforeExt(asset.getPath(), "_"+op.shortString()))); outfile = new File(output.destDirectory(), basename(appendToFileNameBeforeExt(asset.getPath(), "_"+op.shortString())));
@@ -54,7 +60,7 @@ public abstract class SingleOrMultiSourceExecBase<OP extends JSingleSourceOperat
assetManager.addOperationAssetSlice(output, subOutput); assetManager.addOperationAssetSlice(output, subOutput);
} }
} else { } else {
final File defaultOutfile = assetManager.assetPath(op, source, formatType);
final File defaultOutfile = assetManager.assetPath(op, source, streamType);
final File path = resolveOutputPath(output, defaultOutfile); final File path = resolveOutputPath(output, defaultOutfile);
if (path == null) return null; if (path == null) return null;
output.setPath(abs(path)); output.setPath(abs(path));


+ 7
- 7
src/main/java/jvc/operation/exec/SplitExec.java View File

@@ -1,7 +1,7 @@
package jvc.operation.exec; package jvc.operation.exec;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.operation.JSingleOperationContext; import jvc.model.operation.JSingleOperationContext;
import jvc.operation.SplitOperation; import jvc.operation.SplitOperation;
import jvc.service.AssetManager; import jvc.service.AssetManager;
@@ -28,7 +28,7 @@ public class SplitExec extends ExecBase<SplitOperation> {
final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox); final JSingleOperationContext opCtx = op.getSingleInputContext(assetManager, toolbox);
final JAsset source = opCtx.source; final JAsset source = opCtx.source;
final JAsset output = opCtx.output; final JAsset output = opCtx.output;
final JFileExtension formatType = opCtx.formatType;
final JStreamType streamType = opCtx.streamType;


final JsEngine js = toolbox.getJs(); final JsEngine js = toolbox.getJs();
final Map<String, Object> ctx = initialContext(toolbox, source); final Map<String, Object> ctx = initialContext(toolbox, source);
@@ -43,16 +43,16 @@ public class SplitExec extends ExecBase<SplitOperation> {
final File outfile; final File outfile;
if (output.hasDest()) { if (output.hasDest()) {
if (!output.destExists()) { if (!output.destExists()) {
outfile = sliceFile(output, formatType, i, incr);
outfile = sliceFile(output, streamType, i, incr);
} else { } else {
if (output.destIsDirectory()) { if (output.destIsDirectory()) {
outfile = sliceFile(output, formatType, i, incr);
outfile = sliceFile(output, streamType, i, incr);
} else { } else {
return die("dest exists and is not a directory: "+output.getDest()); return die("dest exists and is not a directory: "+output.getDest());
} }
} }
} else { } else {
outfile = assetManager.assetPath(op, source, formatType, new Object[]{i, incr});
outfile = assetManager.assetPath(op, source, streamType, new Object[]{i, incr});
} }


final JAsset slice = new JAsset(output, outfile); final JAsset slice = new JAsset(output, outfile);
@@ -81,8 +81,8 @@ public class SplitExec extends ExecBase<SplitOperation> {
return ctx; return ctx;
} }


private File sliceFile(JAsset output, JFileExtension formatType, BigDecimal i, BigDecimal incr) {
return new File(output.destDirectory(), output.getName() + "_" + i + "_" + incr + formatType.ext());
private File sliceFile(JAsset output, JStreamType streamType, BigDecimal i, BigDecimal incr) {
return new File(output.destDirectory(), output.getName() + "_" + i + "_" + incr + streamType.ext());
} }


} }

+ 11
- 11
src/main/java/jvc/service/AssetManager.java View File

@@ -1,7 +1,7 @@
package jvc.service; package jvc.service;


import jvc.model.JAsset; import jvc.model.JAsset;
import jvc.model.JFileExtension;
import jvc.model.JStreamType;
import jvc.model.operation.JOperation; import jvc.model.operation.JOperation;
import lombok.Getter; import lombok.Getter;
import org.cobbzilla.util.handlebars.HandlebarsUtil; import org.cobbzilla.util.handlebars.HandlebarsUtil;
@@ -34,27 +34,27 @@ public class AssetManager {


public File sourcePath(String name) { return new File(scratchDir, OUTFILE_PREFIX + "source." + name); } public File sourcePath(String name) { return new File(scratchDir, OUTFILE_PREFIX + "source." + name); }


public File assetPath(JOperation op, JAsset source, JFileExtension formatType) {
return assetPath(op, source, formatType, null);
public File assetPath(JOperation op, JAsset source, JStreamType streamType) {
return assetPath(op, source, streamType, null);
} }


public File assetPath(JOperation op, JAsset source, JFileExtension formatType, Object[] args) {
return assetPath(op, new JAsset[]{source}, formatType, args);
public File assetPath(JOperation op, JAsset source, JStreamType streamType, Object[] args) {
return assetPath(op, new JAsset[]{source}, streamType, args);
} }


public File assetPath(JOperation op, JAsset[] sources, JFileExtension formatType) {
return assetPath(op, sources, formatType, null);
public File assetPath(JOperation op, JAsset[] sources, JStreamType streamType) {
return assetPath(op, sources, streamType, null);
} }


public File assetPath(JOperation op, List<JAsset> sources, JFileExtension formatType) {
return assetPath(op, sources.toArray(JAsset[]::new), formatType, null);
public File assetPath(JOperation op, List<JAsset> sources, JStreamType streamType) {
return assetPath(op, sources.toArray(JAsset[]::new), streamType, null);
} }


public File assetPath(JOperation op, JAsset[] sources, JFileExtension formatType, Object[] args) {
public File assetPath(JOperation op, JAsset[] sources, JStreamType streamType, Object[] args) {
return new File(scratchDir, OUTFILE_PREFIX return new File(scratchDir, OUTFILE_PREFIX
+ op.hash(sources, args) + op.hash(sources, args)
+ (!empty(args) ? "_" + args[0] + (args.length > 1 ? "_" + args[1] : "") : "") + (!empty(args) ? "_" + args[0] + (args.length > 1 ? "_" + args[1] : "") : "")
+ formatType.ext());
+ streamType.ext());
} }


public Map<String, JAsset> getAssets () { public Map<String, JAsset> getAssets () {


Loading…
Cancel
Save