@@ -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. | ||||
@@ -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) { | ||||
@@ -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()); | |||||
} | } | ||||
} | } |
@@ -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()); |
@@ -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() { | ||||
@@ -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; } | ||||
@@ -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: | ||||
@@ -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; | ||||
} | } | ||||
} | } |
@@ -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); | |||||
} | } | ||||
} | } |
@@ -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; | ||||
@@ -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; | ||||
} | } | ||||
@@ -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(); | |||||
} | } | ||||
} | } |
@@ -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) { | ||||
@@ -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)); | ||||
@@ -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); | ||||
@@ -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)); | ||||
@@ -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); | ||||
@@ -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)); | ||||
@@ -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)); | ||||
@@ -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()); | |||||
} | } | ||||
} | } |
@@ -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 () { | ||||