以下是我的代码:
import androID.app.ProgressDialog;import androID.content.Context;import androID.os.Handler;import androID.os.Message;import androID.util.Log;import androID.Widget.Toast;import com.coremedia.iso.Isofile;import com.coremedia.iso.Boxes.TimetoSampleBox;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.CroppedTrack;import java.io.file;import java.io.fileinputStream;import java.io.fileNotFoundException;import java.io.fileOutputStream;import java.io.IOException;import java.nio.channels.fileChannel;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.linkedList;import java.util.List;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import uk.org.humanfocus.hfi.Beans.TrimPoint;import uk.org.humanfocus.hfi.Utils.Constants;import uk.org.humanfocus.hfi.Utils.SimpleThreadFactory;import uk.org.humanfocus.hfi.Utils.Ut;/** * Shortens/Crops a track */public class ShortenExample { private static final String TAG = "ShortenExample"; private final Context mCxt; private ExecutorService mThreadExecutor = null; private SimpleInvalIDationHandler mHandler; private ProgressDialog mProgressDialog; String filePath; ArrayList<TrimPoint> mTrimPoints; int vIDeolength; ArrayList<String> trimVIDeos; private class SimpleInvalIDationHandler extends Handler { @OverrIDe public voID handleMessage(final Message msg) { switch (msg.what) { case R.ID.shorten: mProgressDialog.dismiss(); if (msg.arg1 == 0) Toast.makeText(mCxt,mCxt.getString(R.string.message_error) + " " + (String) msg.obj,Toast.LENGTH_LONG).show(); else Toast.makeText(mCxt,mCxt.getString(R.string.message_shortened) + " " + (String) msg.obj,Toast.LENGTH_LONG).show(); break; } } } public ShortenExample(Context context) { mCxt = context; mHandler = new SimpleInvalIDationHandler(); //mProgressDialog = new ProgressDialog(mCxt); //mProgressDialog.setMessage("Wait Saving.."); //mProgressDialog.setCancelable(false); } public voID shorten(String filePath,ArrayList<TrimPoint> trimPoints,int endTime) { trimVIDeos = new ArrayList<String>(); this.filePath = filePath; this.vIDeolength = endTime; this.mTrimPoints = trimPoints; Log.d(Constants.TAG,"End Time: "+endTime+" Trim Points: "+mTrimPoints.size()); for (int i=0;i<trimPoints.size();i++){ TrimPoint point = trimPoints.get(i); int start=0; int end = 0; if(point.getTime()-5<0){ start = 0; }else{ start = point.getTime()-5; } if(point.getTime()+5>vIDeolength){ end = vIDeolength-1; }else { end = point.getTime() + 5; } Log.d(Constants.TAG,"Clip: "+start+" : "+end); doShorten(start,end); } Log.d(Constants.TAG,"Done: "+trimVIDeos.size()); } private voID doShorten(final int _startTime,final int _endTime) { //mProgressDialog = Ut.ShowWaitDialog(mCxt,0); //mProgressDialog.show(); if(mThreadExecutor == null) mThreadExecutor = Executors.newSingleThreadExecutor(new SimpleThreadFactory("doShorten")); //this.mThreadExecutor.execute(new Runnable() { // public voID run() { try { file folder = Ut.getTestMp4ParserVIDeosDir(mCxt); //file folder = new file(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),"HFVIDeos"+file.separator+"TEMP"); //Log.d(Constants.TAG,folder.toString()); if (!folder.exists()) { Log.d(TAG,"Failed to create directory"); } //MovIE movIE = new MovIECreator().build(new RandomAccessfile("/home/sannIEs/suckerpunch-distantplanet_h1080p/suckerpunch-distantplanet_h1080p.mov","r").getChannel());// MovIE movIE = MovIECreator.build(new fileinputStream("/home/sannIEs/CSI.S13E02.HDTV.x264-Lol.mp4").getChannel()); MovIE movIE = MovIECreator.build(new fileinputStream(new file(filePath)).getChannel()); //Log.d(Constants.TAG,"MovIE: "+movIE.toString()); List<Track> tracks = movIE.getTracks(); movIE.setTracks(new linkedList<Track>()); // remove all tracks we will create new tracks from the old double startTime = _startTime; double endTime = _endTime;//(double) getDuration(tracks.get(0)) / tracks.get(0).getTrackMetaData().getTimescale(); 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."); } startTime = correctTimetoSyncSample(track,startTime,false); endTime = correctTimetoSyncSample(track,endTime,true); timeCorrected = true; } } for (Track track : tracks) { long currentSample = 0; double currentTime = 0; long startSample = -1; long endSample = -1; for (int i = 0; i < track.getDeCodingTimeEntrIEs().size(); i++) { TimetoSampleBox.Entry entry = track.getDeCodingTimeEntrIEs().get(i); for (int j = 0; j < entry.getCount(); j++) { // entry.getDelta() is the amount of time the current sample covers. if (currentTime <= startTime) { // current sample is still before the new starttime startSample = currentSample; } if (currentTime <= endTime) { // current sample is after the new start time and still before the new endtime endSample = currentSample; } else { // current sample is after the end of the cropped vIDeo break; } currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale(); currentSample++; } } movIE.addTrack(new CroppedTrack(track,startSample,endSample)); } long start1 = System.currentTimeMillis(); Isofile out = new DefaultMp4Builder().build(movIE); long start2 = System.currentTimeMillis();// fileOutputStream fos = new fileOutputStream(String.format("output-%f-%f.mp4",endTime)); String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String filename = folder.getPath() + file.separator + String.format("TMP4_APP_OUT-%f-%f",endTime) + "_" + timeStamp + ".mp4"; trimVIDeos.add(filename); fileOutputStream fos = new fileOutputStream(filename); fileChannel fc = fos.getChannel(); out.getBox(fc); fc.close(); fos.close(); long start3 = System.currentTimeMillis(); System.err.println("Building Isofile took : " + (start2 - start1) + "ms"); System.err.println("Writing Isofile took : " + (start3 - start2) + "ms"); System.err.println("Writing Isofile speed : " + (new file(String.format("TMP4_APP_OUT-%f-%f",endTime)).length() / (start3 - start2) / 1000) + "MB/s"); Message.obtain(mHandler,R.ID.shorten,1,filename).sendToTarget(); } catch (fileNotFoundException e) { Message.obtain(mHandler,e.getMessage()).sendToTarget(); e.printstacktrace(); } catch (IOException e) { Message.obtain(mHandler,e.getMessage()).sendToTarget(); e.printstacktrace(); } //mProgressDialog.dismiss(); // } //}); } protected static long getDuration(Track track) { long duration = 0; for (TimetoSampleBox.Entry entry : track.getDeCodingTimeEntrIEs()) { duration += entry.getCount() * entry.getDelta(); } return duration; } 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.getDeCodingTimeEntrIEs().size(); i++) { TimetoSampleBox.Entry entry = track.getDeCodingTimeEntrIEs().get(i); for (int j = 0; j < entry.getCount(); j++) { 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) entry.getDelta() / (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]; }}解决方法 问题只出现在模拟器中.当我们在模拟器中录制视频时,它会记录实际时间的秒数.代码在实际设备上工作正常. 总结
以上是内存溢出为你收集整理的android – 使用mp4parser Library从电影中剪切多个剪辑的问题全部内容,希望文章能够帮你解决android – 使用mp4parser Library从电影中剪切多个剪辑的问题所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)