Android 使用mp4parser进行视频的分割与合并

原创 2016年12月26日 15:16:12

mp4parser 是一个优秀的视频处理框架,下面就教大家使用mp4parser在android上进行视频的分割与合并。


2017年4月10日更新:

我发现该框架还有诸多问题和BUG,比如无法合并不同格式(帧率,分辨率)的视频,最近已改用MediaCodec,如果需要做一些比较复杂的处理,还是推荐使用MediaCodec和FFmpeg,后面有时间我会写一写相关的内容。


FFmpeg框架EpMedia



Github:https://github.com/sannies/mp4parser\


Gradle:

dependencies {
    compile 'com.googlecode.mp4parser:isoparser:1.1.21'
}

视频的分割:

public class VideoClip {
	private String filePath;//视频路径
	private String workingPath;//输出路径
	private String outName;//输出文件名
	private double startTime;//剪切起始时间
	private double endTime;//剪切结束时间

	private void clip() {
		try {
			Movie movie = MovieCreator.build(filePath);

			List<Track> tracks = movie.getTracks();
			movie.setTracks(new LinkedList<Track>());
			//移除旧的通道
			boolean timeCorrected = false;

			//计算剪切时间
			for (Track track : tracks) {
				if (track.getSyncSamples() != null
						&& track.getSyncSamples().length > 0) {
					if (timeCorrected) {
						throw new RuntimeException(
								"The startTime has already been corrected by another track with SyncSample. Not Supported.");
					}
					startTime = VideoHelper.correctTimeToSyncSample(track, startTime, false);
					endTime = VideoHelper.correctTimeToSyncSample(track, endTime, true);
					timeCorrected = true;
				}
			}

			for (Track track : tracks) {
				long currentSample = 0;
				double currentTime = 0;
				double lastTime = 0;
				long startSample1 = -1;
				long endSample1 = -1;

				for (int i = 0; i < track.getSampleDurations().length; i++) {
					long delta = track.getSampleDurations()[i];
					if (currentTime > lastTime && currentTime <= startTime) {
						startSample1 = currentSample;
					}
					if (currentTime > lastTime && currentTime <= endTime) {
						endSample1 = currentSample;
					}
					lastTime = currentTime;
					currentTime += (double) delta
							/ (double) track.getTrackMetaData().getTimescale();
					currentSample++;
				}
				movie.addTrack(new CroppedTrack(track, startSample1, endSample1));// new
			}

			//合成视频mp4
			Container out = new DefaultMp4Builder().build(movie);
			File storagePath = new File(workingPath);
			storagePath.mkdirs();
			FileOutputStream fos = new FileOutputStream(new File(storagePath, outName));
			FileChannel fco = fos.getChannel();
			out.writeContainer(fco);
			fco.close();
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


视频的合并:

public class VideoMerge {

	private String workingPath;//输出文件目录
	private ArrayList<String> videosToMerge;//需要合并的视频的路径集合
	private String outName;//输出的视频名称

	private void merge(){
		int count = videosToMerge.size();
		try {
			Movie[] inMovies = new Movie[count];
			for (int i = 0; i < count; i++) {
				inMovies[i] = MovieCreator.build(videosToMerge.get(i));
			}

			List<Track> videoTracks = new LinkedList<>();
			List<Track> audioTracks = new LinkedList<>();

			//提取所有视频和音频的通道
			for (Movie m : inMovies) {
				for (Track t : m.getTracks()) {
					if (t.getHandler().equals("soun")) {
						audioTracks.add(t);
					}
					if (t.getHandler().equals("vide")) {
						videoTracks.add(t);
					}
					if (t.getHandler().equals("")) {

					}
				}
			}

			//添加通道到新的视频里
			Movie result = new Movie();
			if (audioTracks.size() > 0) {
				result.addTrack(new AppendTrack(audioTracks
						.toArray(new Track[audioTracks.size()])));
			}
			if (videoTracks.size() > 0) {
				result.addTrack(new AppendTrack(videoTracks
						.toArray(new Track[videoTracks.size()])));
			}
			Container mp4file = new DefaultMp4Builder()
					.build(result);


			//开始生产mp4文件
			File storagePath = new File(workingPath);
			storagePath.mkdirs();
			FileOutputStream fos =  new FileOutputStream(new File(storagePath,outName));
			FileChannel fco = fos.getChannel();
			mp4file.writeContainer(fco);
			fco.close();
			fos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

里面用到的VideoHelper:

public class VideoHelper {


	//换算剪切时间
	public 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) {
				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];
	}
}

视频的分割与合并也可以用其他方法例如:ffmpeg,MediaCodec等。


版权声明:本文为博主原创文章,未经博主允许不得转载。

使用mp4parser进行音视频合成

需求:相机录制短视频,支持暂停继续,并配有背景音乐。 由于Android自带的MediaRecorder并不支持视频录制暂停,所以只能录制视频片段,最后录制结束时将之前录制的视频片段合并起来。背景音...
  • brian512
  • brian512
  • 2016年10月26日 19:05
  • 2995

Android Studio使用mp4parser进行视频的分割

Android Studio使用mp4parser进行视频的分割
  • foryou96
  • foryou96
  • 2017年03月20日 20:17
  • 2865

Android mp4parser 视频拼接

最近项目里面要用到视频拼接,参考网上的资料决定采用mp4parser进行视频拼接,github上有mp4parser的源码。mp4parser项目很大,这里只用到了视频拼接的部分。这里我封装了一个My...
  • AmazingUU
  • AmazingUU
  • 2016年07月04日 23:18
  • 3484

AAC、h264、mp4格式合成MP4(android、JAVA)

  • 2014年11月19日 10:53
  • 1.09MB
  • 下载

android视频合成相关整理

1, ffmpeg视频转换: http://blog.csdn.net/gobitan/article/details/22750719 2, 视频合成示例代码:http://blog.csdn.n...
  • u014702999
  • u014702999
  • 2016年02月15日 18:48
  • 3030

Android 视频分离和合成(MediaMuxer和MediaExtractor)

Android 视频的分离和合成这方面的资源网上是少之又少,学习的过程也是各种demo的看,各种demo的实验,各种坑的踩,为了让大家能够android的视频的分离和合成又个了解,写了下面的例子,完整...
  • zhi184816
  • zhi184816
  • 2016年09月12日 15:46
  • 10973

MP4Parser Jar包

  • 2018年01月18日 16:44
  • 995KB
  • 下载

android 音频视频合并

https://code.google.com/p/mp4parser/
  • gaoguoxin2
  • gaoguoxin2
  • 2014年05月04日 09:47
  • 1968

android 视频录制剪切合并

Android 实现视频录制播放 - 丕子李 - 博客频道 - CSDN.NET
  • yue31313
  • yue31313
  • 2016年07月14日 18:41
  • 264

android 音频视频合并

1. 生成mp4 audio 通过录音 生成mp4 audio [java] view plaincopy // -----------------sound proce...
  • sdvch
  • sdvch
  • 2014年08月02日 15:04
  • 15199
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 使用mp4parser进行视频的分割与合并
举报原因:
原因补充:

(最多只允许输入30个字)