局限性
只支持mp4文件
经过尝试对于一些mp4文件分割不了
依赖
com.googlecode.mp4parser
isoparser
1.1.22
工具类
package com.example.demo;
import com.coremedia.iso.boxes.container;
import com.googlecode.mp4parser.authoring.movie;
import com.googlecode.mp4parser.authoring.track;
import com.googlecode.mp4parser.authoring.builder.defaultmp4builder;
import com.googlecode.mp4parser.authoring.container.mp4.moviecreator;
import com.googlecode.mp4parser.authoring.tracks.appendtrack;
import com.googlecode.mp4parser.authoring.tracks.croppedtrack;
import java.io.file;
import java.io.fileoutputstream;
import java.io.ioexception;
import java.nio.channels.filechannel;
import java.util.arraylist;
import java.util.arrays;
import java.util.linkedlist;
import java.util.list;
public class mp4parserutils {
/**
* 合并视频
*
* @param videolist: 所有视频地址集合
* @param mergevideofile: 目标文件
* @return
*/
public static string mergevideo(list videolist, file mergevideofile) {
fileoutputstream fos = null;
filechannel fc = null;
try {
list sourcemovies = new arraylist<>();
for (string video : videolist) {
sourcemovies.add(moviecreator.build(video));
}
list videotracks = new linkedlist<>();
list audiotracks = new linkedlist<>();
for (movie movie : sourcemovies) {
for (track track : movie.gettracks()) {
if ("soun".equals(track.gethandler())) {
audiotracks.add(track);
}
if ("vide".equals(track.gethandler())) {
videotracks.add(track);
}
}
}
movie mergemovie = new movie();
if (audiotracks.size() > 0) {
mergemovie.addtrack(new appendtrack(audiotracks.toarray(new track[audiotracks.size()])));
}
if (videotracks.size() > 0) {
mergemovie.addtrack(new appendtrack(videotracks.toarray(new track[videotracks.size()])));
}
container out = new defaultmp4builder().build(mergemovie);
fos = new fileoutputstream(mergevideofile);
fc = fos.getchannel();
out.writecontainer(fc);
fc.close();
fos.close();
return mergevideofile.getabsolutepath();
} catch (exception e) {
e.printstacktrace();
} finally {
if (fc != null) {
try {
fc.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (ioexception e) {
e.printstacktrace();
}
}
}
return null;
}
/**
* 剪切视频
* @param srcvideopath
* @param dstvideopath
* @param times
* @throws ioexception
*/
public static void cutvideo(string srcvideopath, string dstvideopath, double[] times) throws ioexception {
int dstvideonumber = times.length / 2;
string[] dstvideopathes = new string[dstvideonumber];
for (int i = 0; i < dstvideonumber; i++) {
dstvideopathes[i] = dstvideopath + "cutoutput-" + i + ".mp4";
}
int timescount = 0;
for (int idst = 0; idst < dstvideopathes.length; idst++) {
//movie movie = new moviecreator().build(new randomaccessfile("/home/sannies/suckerpunch-distantplanet_h1080p/suckerpunch-distantplanet_h1080p.mov", "r").getchannel());
movie movie = moviecreator.build(srcvideopath);
list tracks = movie.gettracks();
movie.settracks(new linkedlist());
// remove all tracks we will create new tracks from the old
double starttime1 = times[timescount];
double endtime1 = times[timescount + 1];
timescount = timescount + 2;
boolean timecorrected = false;
// here we try to find a track that has sync samples. since we can only start decoding
// at such a sample we should make sure that the start of the new fragment is exactly
// such a frame
for (track track : tracks) {
if (track.getsyncsamples() != null && track.getsyncsamples().length > 0) {
if (timecorrected) {
// this exception here could be a false positive in case we have multiple tracks
// with sync samples at exactly the same positions. e.g. a single movie containing
// multiple qualities of the same video (microsoft smooth streaming file)
throw new runtimeexception("the starttime has already been corrected by another track with syncsample. not supported.");
}
starttime1 = correcttimetosyncsample(track, starttime1, false);
endtime1 = correcttimetosyncsample(track, endtime1, true);
timecorrected = true;
}
}
for (track track : tracks) {
long currentsample = 0;
double currenttime = 0;
double lasttime = -1;
long startsample1 = -1;
long endsample1 = -1;
for (int i = 0; i < track.getsampledurations().length; i++) {
long delta = track.getsampledurations()[i];
if (currenttime > lasttime && currenttime <= starttime1) {
// current sample is still before the new starttime
startsample1 = currentsample;
}
if (currenttime > lasttime && currenttime <= endtime1) {
// current sample is after the new start time and still before the new endtime
endsample1 = currentsample;
}
lasttime = currenttime;
currenttime += (double) delta / (double) track.gettrackmetadata().gettimescale();
currentsample++;
}
//movie.addtrack(new appendtrack(new clippedtrack(track, startsample1, endsample1), new clippedtrack(track, startsample2, endsample2)));
movie.addtrack(new croppedtrack(track, startsample1, endsample1));
}
long start1 = system.currenttimemillis();
container out = new defaultmp4builder().build(movie);
long start2 = system.currenttimemillis();
fileoutputstream fos = new fileoutputstream(string.format(dstvideopathes[idst]));
filechannel fc = fos.getchannel();
out.writecontainer(fc);
fc.close();
fos.close();
long start3 = system.currenttimemillis();
}
}
private static double correcttimetosyncsample(track track, double cuthere, boolean next) {
double[] timeofsyncsamples = new double[track.getsyncsamples().length];
long currentsample = 0;
double currenttime = 0;
for (int i = 0; i < track.getsampledurations().length; i++) {
long delta = track.getsampledurations()[i];
if (arrays.binarysearch(track.getsyncsamples(), currentsample + 1) >= 0) {
// samples always start with 1 but we start with zero therefore +1
timeofsyncsamples[arrays.binarysearch(track.getsyncsamples(), currentsample + 1)] = currenttime;
}
currenttime += (double) delta / (double) track.gettrackmetadata().gettimescale();
currentsample++;
}
double previous = 0;
for (double timeofsyncsample : timeofsyncsamples) {
if (timeofsyncsample > cuthere) {
if (next) {
return timeofsyncsample;
} else {
return previous;
}
}
previous = timeofsyncsample;
}
return timeofsyncsamples[timeofsyncsamples.length - 1];
}
}
以上就是java 合并多个mp4视频文件的详细内容,更多关于java 合并视频的资料请关注萬仟网其它相关文章!
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!