www in docker support
This commit is contained in:
parent
539a848e95
commit
c227fce036
2145 changed files with 399596 additions and 58 deletions
|
|
@ -0,0 +1,179 @@
|
|||
package org.jcodec.movtool;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
import org.jcodec.common.io.SeekableByteChannel;
|
||||
import org.jcodec.containers.mp4.MP4Util;
|
||||
import org.jcodec.containers.mp4.boxes.Box;
|
||||
import org.jcodec.containers.mp4.boxes.ClipRegionBox;
|
||||
import org.jcodec.containers.mp4.boxes.LoadSettingsBox;
|
||||
import org.jcodec.containers.mp4.boxes.MovieBox;
|
||||
import org.jcodec.containers.mp4.boxes.NodeBox;
|
||||
import org.jcodec.containers.mp4.boxes.SampleSizesBox;
|
||||
import org.jcodec.containers.mp4.boxes.SoundMediaHeaderBox;
|
||||
import org.jcodec.containers.mp4.boxes.TrackHeaderBox;
|
||||
import org.jcodec.containers.mp4.boxes.TrakBox;
|
||||
import org.jcodec.containers.mp4.boxes.VideoMediaHeaderBox;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class Paste {
|
||||
long[] tv;
|
||||
|
||||
public static void main1(String[] args) throws Exception {
|
||||
if (args.length < 2) {
|
||||
System.out.println("Syntax: paste <to movie> <from movie> [second]");
|
||||
System.exit(-1);
|
||||
}
|
||||
File toFile = new File(args[0]);
|
||||
SeekableByteChannel to = null;
|
||||
SeekableByteChannel from = null;
|
||||
SeekableByteChannel out = null;
|
||||
try {
|
||||
File outFile = new File(toFile.getParentFile(), toFile.getName().replaceAll("\\.mov$", "") + ".paste.mov");
|
||||
Platform.deleteFile(outFile);
|
||||
out = NIOUtils.writableChannel(outFile);
|
||||
to = NIOUtils.writableChannel(toFile);
|
||||
File fromFile = new File(args[1]);
|
||||
from = NIOUtils.readableChannel(fromFile);
|
||||
MP4Util.Movie toMov = MP4Util.createRefFullMovie(to, "file://" + toFile.getCanonicalPath());
|
||||
MP4Util.Movie fromMov = MP4Util.createRefFullMovie(from, "file://" + fromFile.getCanonicalPath());
|
||||
new Strip().strip(fromMov.getMoov());
|
||||
if (args.length > 2) {
|
||||
new Paste().paste(toMov.getMoov(), fromMov.getMoov(), Double.parseDouble(args[2]));
|
||||
} else {
|
||||
new Paste().addToMovie(toMov.getMoov(), fromMov.getMoov());
|
||||
}
|
||||
MP4Util.writeFullMovie(out, toMov);
|
||||
} finally {
|
||||
if (to != null)
|
||||
to.close();
|
||||
if (from != null)
|
||||
from.close();
|
||||
if (out != null)
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void paste(MovieBox to, MovieBox from, double sec) {
|
||||
TrakBox videoTrack = to.getVideoTrack();
|
||||
if (videoTrack != null && videoTrack.getTimescale() != to.getTimescale())
|
||||
to.fixTimescale(videoTrack.getTimescale());
|
||||
long displayTv = (long)((double)to.getTimescale() * sec);
|
||||
Util.forceEditListMov(to);
|
||||
Util.forceEditListMov(from);
|
||||
TrakBox[] fromTracks = from.getTracks();
|
||||
TrakBox[] toTracks = to.getTracks();
|
||||
int[][] matches = findMatches(fromTracks, toTracks);
|
||||
for (int j = 0; j < (matches[0]).length; j++) {
|
||||
TrakBox localTrack = to.importTrack(from, fromTracks[j]);
|
||||
if (matches[0][j] != -1) {
|
||||
Util.insertTo(to, toTracks[matches[0][j]], localTrack, displayTv);
|
||||
} else {
|
||||
to.appendTrack(localTrack);
|
||||
Util.shift(to, localTrack, displayTv);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < (matches[1]).length; i++) {
|
||||
if (matches[1][i] == -1)
|
||||
Util.spread(to, toTracks[i], displayTv, to.rescale(from.getDuration(), (long)from.getTimescale()));
|
||||
}
|
||||
to.updateDuration();
|
||||
}
|
||||
|
||||
public void addToMovie(MovieBox to, MovieBox from) {
|
||||
TrakBox[] tracks = from.getTracks();
|
||||
for (int i = 0; i < tracks.length; i++) {
|
||||
TrakBox track = tracks[i];
|
||||
to.appendTrack(to.importTrack(from, track));
|
||||
}
|
||||
}
|
||||
|
||||
private long getFrameTv(TrakBox videoTrack, int frame) {
|
||||
if (this.tv == null)
|
||||
this.tv = Util.getTimevalues(videoTrack);
|
||||
return this.tv[frame];
|
||||
}
|
||||
|
||||
private int[][] findMatches(TrakBox[] fromTracks, TrakBox[] toTracks) {
|
||||
int[] f2t = new int[fromTracks.length];
|
||||
int[] t2f = new int[toTracks.length];
|
||||
Arrays.fill(f2t, -1);
|
||||
Arrays.fill(t2f, -1);
|
||||
for (int i = 0; i < fromTracks.length; i++) {
|
||||
if (f2t[i] == -1)
|
||||
for (int j = 0; j < toTracks.length; j++) {
|
||||
if (t2f[j] == -1)
|
||||
if (matches(fromTracks[i], toTracks[j])) {
|
||||
f2t[i] = j;
|
||||
t2f[j] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new int[][] { f2t, t2f };
|
||||
}
|
||||
|
||||
private boolean matches(TrakBox trakBox1, TrakBox trakBox2) {
|
||||
return (trakBox1.getHandlerType().equals(trakBox2.getHandlerType()) && matchHeaders(trakBox1, trakBox2) &&
|
||||
matchSampleSizes(trakBox1, trakBox2) && matchMediaHeader(trakBox1, trakBox2) &&
|
||||
matchClip(trakBox1, trakBox2) && matchLoad(trakBox1, trakBox2));
|
||||
}
|
||||
|
||||
private boolean matchSampleSizes(TrakBox trakBox1, TrakBox trakBox2) {
|
||||
SampleSizesBox stsz1 = NodeBox.<SampleSizesBox>findFirstPath(trakBox1, SampleSizesBox.class, Box.path("mdia.minf.stbl.stsz"));
|
||||
SampleSizesBox stsz2 = NodeBox.<SampleSizesBox>findFirstPath(trakBox1, SampleSizesBox.class, Box.path("mdia.minf.stbl.stsz"));
|
||||
return (stsz1.getDefaultSize() == stsz2.getDefaultSize());
|
||||
}
|
||||
|
||||
private boolean matchMediaHeader(TrakBox trakBox1, TrakBox trakBox2) {
|
||||
VideoMediaHeaderBox vmhd1 = NodeBox.<VideoMediaHeaderBox>findFirstPath(trakBox1, VideoMediaHeaderBox.class, Box.path("mdia.minf.vmhd"));
|
||||
VideoMediaHeaderBox vmhd2 = NodeBox.<VideoMediaHeaderBox>findFirstPath(trakBox2, VideoMediaHeaderBox.class, Box.path("mdia.minf.vmhd"));
|
||||
if ((vmhd1 != null && vmhd2 == null) || (vmhd1 == null && vmhd2 != null))
|
||||
return false;
|
||||
if (vmhd1 != null && vmhd2 != null)
|
||||
return (vmhd1.getGraphicsMode() == vmhd2.getGraphicsMode() && vmhd1.getbOpColor() == vmhd2.getbOpColor() &&
|
||||
vmhd1.getgOpColor() == vmhd2.getgOpColor() && vmhd1.getrOpColor() == vmhd2.getrOpColor());
|
||||
SoundMediaHeaderBox smhd1 = NodeBox.<SoundMediaHeaderBox>findFirstPath(trakBox1, SoundMediaHeaderBox.class, Box.path("mdia.minf.smhd"));
|
||||
SoundMediaHeaderBox smhd2 = NodeBox.<SoundMediaHeaderBox>findFirstPath(trakBox2, SoundMediaHeaderBox.class, Box.path("mdia.minf.smhd"));
|
||||
if ((smhd1 == null && smhd2 != null) || (smhd1 != null && smhd2 == null))
|
||||
return false;
|
||||
if (smhd1 != null && smhd2 != null)
|
||||
return (smhd1.getBalance() == smhd1.getBalance());
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean matchHeaders(TrakBox trakBox1, TrakBox trakBox2) {
|
||||
TrackHeaderBox th1 = trakBox1.getTrackHeader();
|
||||
TrackHeaderBox th2 = trakBox2.getTrackHeader();
|
||||
return (("vide".equals(trakBox1.getHandlerType()) && Platform.arrayEqualsInt(th1.getMatrix(), th2.getMatrix()) &&
|
||||
th1.getLayer() == th2.getLayer() && th1.getWidth() == th2.getWidth() && th1.getHeight() ==
|
||||
th2.getHeight()) || ("soun"
|
||||
.equals(trakBox1.getHandlerType()) && th1.getVolume() == th2.getVolume()) || "tmcd"
|
||||
.equals(trakBox1.getHandlerType()));
|
||||
}
|
||||
|
||||
private boolean matchLoad(TrakBox trakBox1, TrakBox trakBox2) {
|
||||
LoadSettingsBox load1 = NodeBox.<LoadSettingsBox>findFirst(trakBox1, LoadSettingsBox.class, "load");
|
||||
LoadSettingsBox load2 = NodeBox.<LoadSettingsBox>findFirst(trakBox2, LoadSettingsBox.class, "load");
|
||||
if (load1 != null && load2 != null)
|
||||
return (load1.getPreloadStartTime() == load2.getPreloadStartTime() &&
|
||||
load1.getPreloadDuration() == load2.getPreloadDuration() &&
|
||||
load1.getPreloadFlags() == load2.getPreloadFlags() &&
|
||||
load1.getDefaultHints() == load2.getDefaultHints());
|
||||
if (load1 == null && load2 == null)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean matchClip(TrakBox trakBox1, TrakBox trakBox2) {
|
||||
ClipRegionBox crgn1 = NodeBox.<ClipRegionBox>findFirstPath(trakBox1, ClipRegionBox.class, Box.path("clip.crgn"));
|
||||
ClipRegionBox crgn2 = NodeBox.<ClipRegionBox>findFirstPath(trakBox2, ClipRegionBox.class, Box.path("clip.crgn"));
|
||||
if (crgn1 != null && crgn2 != null)
|
||||
return (crgn1.getRgnSize() == crgn2.getRgnSize() && crgn1.getX() == crgn2.getX() && crgn1.getY() == crgn2.getY() &&
|
||||
crgn1.getWidth() == crgn2.getWidth() && crgn1.getHeight() == crgn2.getHeight());
|
||||
if (crgn1 == null && crgn2 == null)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue