java mp4分割_Java 合并多个MP4视频文件

本文介绍了如何使用Java的isoparser库来合并和剪切MP4视频文件。提供了详细的代码示例,包括合并多个视频和按时间点剪切视频的方法。注意,该方法可能对某些MP4文件不适用,并且仅支持MP4格式。
摘要由CSDN通过智能技术生成

局限性

只支持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 合并视频的资料请关注萬仟网其它相关文章!

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值