/*** mp4处理公共类* Created by lxy on 17-4-21.*/public classMp4ParseUtil {
/***对Mp4文件集合进行追加合并(按照顺序一个一个拼接起来)**@parammp4PathList[输入]Mp4文件路径的集合(支持m4a)(不支持wav)*@paramoutPutPath[输出]结果文件全部名称包含后缀(比如.mp4)*@throwsIOException格式不支持等情况抛出异常*/public static voidappendMp4List(List mp4PathList, String outPutPath){
try{
List mp4MovieList = newArrayList<>();// Movie对象集合[输入]for(String mp4Path : mp4PathList) {//将每个文件路径都构建成一个Movie对象mp4MovieList.add(MovieCreator.build(mp4Path));
}
List audioTracks = newLinkedList<>();//音频通道集合List videoTracks = newLinkedList<>();//视频通道集合for(Movie mp4Movie : mp4MovieList) {//对Movie对象集合进行循环for(Track inMovieTrack : mp4Movie.getTracks()) {
if("soun".equals(inMovieTrack.getHandler())) {//从Movie对象中取出音频通道audioTracks.add(inMovieTrack);
}
if("vide".equals(inMovieTrack.getHandler())) {//从Movie对象中取出视频通道videoTracks.add(inMovieTrack);
}
}
}
Movie resultMovie = newMovie();//结果Movie对象[输出]if(!audioTracks.isEmpty()) {//将所有音频通道追加合并resultMovie.addTrack(newAppendTrack(audioTracks.toArray(newTrack[audioTracks.size()])));
}
if(!videoTracks.isEmpty()) {//将所有视频通道追加合并resultMovie.addTrack(newAppendTrack(videoTracks.toArray(newTrack[videoTracks.size()])));
}
Container outContainer = newDefaultMp4Builder().build(resultMovie);//将结果Movie对象封装进容器FileChannel fileChannel = newRandomAccessFile(String.format(outPutPath), "rw").getChannel();
outContainer.writeContainer(fileChannel);//将容器内容写入磁盘fileChannel.close();
}catch(Exception e){
e.printStackTrace();
}
}
/***对AAC文件集合进行追加合并(按照顺序一个一个拼接起来)**@paramaacPathList[输入]AAC文件路径的集合(不支持wav)*@paramoutPutPath[输出]结果文件全部名称包含后缀(比如.aac)*@throwsIOException格式不支持等情况抛出异常*/public static voidappendAacList(List aacPathList, String outPutPath){
try{
List audioTracks = newLinkedList<>();//音频通道集合for(inti = 0; i < aacPathList.size(); i++) {//将每个文件路径都构建成一个AACTrackImpl对象audioTracks.add(newAACTrackImpl(newFileDataSourceImpl(aacPathList.get(i))));
}
Movie resultMovie = newMovie();//结果Movie对象[输出]if(!audioTracks.isEmpty()) {//将所有音频通道追加合并resultMovie.addTrack(newAppendTrack(audioTracks.toArray(newTrack[audioTracks.size()])));
}
Container outContainer = newDefaultMp4Builder().build(resultMovie);//将结果Movie对象封装进容器FileChannel fileChannel = newRandomAccessFile(String.format(outPutPath), "rw").getChannel();
outContainer.writeContainer(fileChannel);//将容器内容写入磁盘fileChannel.close();
}catch(Exception e){
e.printStackTrace();
}
}
private staticList moviesList= newArrayList<>();
private staticList videoTracks= newArrayList<>();
private staticList audioTracks= newArrayList<>();
//将两个mp4视频进行拼接public static voidappendMp4(List mMp4List,String outputpath){
try{
for(inti=0;i
Movie movie=MovieCreator.build(mMp4List.get(i));
moviesList.add(movie);
}
} catch(IOException e) {
e.printStackTrace();
}
for(Movie m : moviesList) {
for(Track t : m.getTracks()) {
if(t.getHandler().equals("soun")) {
audioTracks.add(t);
}
if(t.getHandler().equals("vide")) {
videoTracks.add(t);
}
}
}
Movie result = newMovie();
try{
if(audioTracks.size() > 0) {
result.addTrack(newAppendTrack(audioTracks.toArray(newTrack[audioTracks.size()])));
}
if(videoTracks.size() > 0) {
result.addTrack(newAppendTrack(videoTracks.toArray(newTrack[videoTracks.size()])));
}
} catch(IOException e) {
e.printStackTrace();
}
Container out = newDefaultMp4Builder().build(result);
try{
FileChannel fc = newFileOutputStream(newFile(outputpath)).getChannel();
out.writeContainer(fc);
fc.close();
} catch(Exception e) {
e.printStackTrace();
}
moviesList.clear();
}
/***将AAC和MP4进行混合[替换了视频的音轨]**@paramaacPath.aac*@parammp4Path.mp4*@paramoutPath.mp4*/public static booleanmuxAacMp4(String aacPath, String mp4Path, String outPath) {
booleanflag=false;
try{
AACTrackImpl aacTrack = newAACTrackImpl(newFileDataSourceImpl(aacPath));
Movie videoMovie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取视频的单纯视频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(videoTracks);//视频部分resultMovie.addTrack(aacTrack);//音频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
flag=true;
Log.e("update_tag","merge finish");
} catch(Exception e) {
e.printStackTrace();
flag=false;
}
returnflag;
}
/***将M4A和MP4进行混合[替换了视频的音轨]**@paramm4aPath.m4a[同样可以使用.mp4]*@parammp4Path.mp4*@paramoutPath.mp4*/public static voidmuxM4AMp4(String m4aPath, String mp4Path, String outPath) throwsIOException {
Movie audioMovie = MovieCreator.build(m4aPath);
Track audioTracks = null;//获取视频的单纯音频部分for(Track audioMovieTrack : audioMovie.getTracks()) {
if("soun".equals(audioMovieTrack.getHandler())) {
audioTracks = audioMovieTrack;
}
}
Movie videoMovie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取视频的单纯视频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(videoTracks);//视频部分resultMovie.addTrack(audioTracks);//音频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}
/***分离mp4视频的音频部分,只保留视频部分**@parammp4Path.mp4*@paramoutPath.mp4*/public static voidsplitMp4(String mp4Path, String outPath){
try{
Movie videoMovie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取视频的单纯视频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(videoTracks);//视频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
/***分离mp4的视频部分,只保留音频部分**@parammp4Path.mp4*@paramoutPath.aac*/public static voidsplitAac(String mp4Path, String outPath){
try{
Movie videoMovie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取音频的单纯视频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("soun".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(videoTracks);//音频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
/***分离mp4视频的音频部分,只保留视频部分**@parammp4Path.mp4*@parammp4OutPathmp4视频输出路径*@paramaacOutPathaac视频输出路径*/public static voidsplitVideo(String mp4Path, String mp4OutPath,String aacOutPath){
try{
Movie videoMovie = MovieCreator.build(mp4Path);
Track videTracks = null;//获取视频的单纯视频部分Track sounTracks = null;//获取视频的单纯音频部分for(Track videoMovieTrack : videoMovie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videTracks = videoMovieTrack;
}
if("soun".equals(videoMovieTrack.getHandler())) {
sounTracks = videoMovieTrack;
}
}
Movie videMovie = newMovie();
videMovie.addTrack(videTracks);//视频部分Movie sounMovie = newMovie();
sounMovie.addTrack(sounTracks);//音频部分//视频部分Container videout = newDefaultMp4Builder().build(videMovie);
FileOutputStream videfos = newFileOutputStream(newFile(mp4OutPath));
videout.writeContainer(videfos.getChannel());
videfos.close();
//音频部分Container sounout = newDefaultMp4Builder().build(sounMovie);
FileOutputStream sounfos = newFileOutputStream(newFile(aacOutPath));
sounout.writeContainer(sounfos.getChannel());
sounfos.close();
}catch(Exception e){
e.printStackTrace();
}
}
/***对Mp4添加字幕**@parammp4Path.mp4添加字幕之前*@paramoutPath.mp4添加字幕之后*/public static voidaddSubtitles(String mp4Path, String outPath) throwsIOException {
Movie videoMovie = MovieCreator.build(mp4Path);
TextTrackImpl subTitleEng = newTextTrackImpl();//实例化文本通道对象subTitleEng.getTrackMetaData().setLanguage("eng");//设置元数据(语言)subTitleEng.getSubs().add(newTextTrackImpl.Line(0, 1000, "Five"));//参数时间毫秒值subTitleEng.getSubs().add(newTextTrackImpl.Line(1000, 2000, "Four"));
subTitleEng.getSubs().add(newTextTrackImpl.Line(2000, 3000, "Three"));
subTitleEng.getSubs().add(newTextTrackImpl.Line(3000, 4000, "Two"));
subTitleEng.getSubs().add(newTextTrackImpl.Line(4000, 5000, "one"));
subTitleEng.getSubs().add(newTextTrackImpl.Line(5001, 5002, " "));//省略去测试videoMovie.addTrack(subTitleEng);//将字幕通道添加进视频Movie对象中Container out = newDefaultMp4Builder().build(videoMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}
/***将MP4切割**@parammp4Path.mp4*@paramfromSample起始位置 不是传入的秒数*@paramtoSample结束位置 不是传入的秒数*@paramoutPath.mp4*/public static voidcropMp4(String mp4Path, longfromSample, longtoSample, String outPath){
try{
Movie mp4Movie = MovieCreator.build(mp4Path);
Track videoTracks = null;//获取视频的单纯视频部分for(Track videoMovieTrack : mp4Movie.getTracks()) {
if("vide".equals(videoMovieTrack.getHandler())) {
videoTracks = videoMovieTrack;
}
}
Track audioTracks = null;//获取视频的单纯音频部分for(Track audioMovieTrack : mp4Movie.getTracks()) {
if("soun".equals(audioMovieTrack.getHandler())) {
audioTracks = audioMovieTrack;
}
}
Movie resultMovie = newMovie();
resultMovie.addTrack(newAppendTrack(newCroppedTrack(videoTracks, fromSample, toSample)));//视频部分resultMovie.addTrack(newAppendTrack(newCroppedTrack(audioTracks, fromSample, toSample)));//音频部分Container out = newDefaultMp4Builder().build(resultMovie);
FileOutputStream fos = newFileOutputStream(newFile(outPath));
out.writeContainer(fos.getChannel());
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
}