Android Sdk Cut/Trim Video File

Android sdk cut/trim video file

You can do this with my mp4parser library. Have a look at the ShortenExample it does exactly what the name suggests.
Since the library cannot re-encode the video it can only cut the video at I-frames. So the points in time where you can make a cut are quite coarse.

On Android 4.1 you can access the hardware codecs via MediaCodec API which could be an option (but I haven't seen any example of that yet)

Trim Video Functionality in an android App

Take a look over here: https://software.intel.com/en-us/articles/intel-inde-media-pack-for-android-tutorials-running-samples

It has a sample of cutting a video which you can use in your application by downloading and including their Starter Edition pack. It's completely free but you'd have to register through and can be used in Android Studio, Eclipse and many other IDEs.

Open source example codes that includes the java files to trim/cut your video into segments. You can even compress the videos which can be done by standard Android SDK as well.

https://github.com/INDExOS/media-for-mobile/tree/master/Android/samples/apps/src/com/intel/inde/mp/samples

How to trim video with MediaCodec

After lots of digging, I found this snippet

  /**
* @param srcPath the path of source video file.
* @param dstPath the path of destination video file.
* @param startMs starting time in milliseconds for trimming. Set to
* negative if starting from beginning.
* @param endMs end time for trimming in milliseconds. Set to negative if
* no trimming at the end.
* @param useAudio true if keep the audio track from the source.
* @param useVideo true if keep the video track from the source.
* @throws IOException
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static void genVideoUsingMuxer(String srcPath, String dstPath,
int startMs, int endMs, boolean useAudio, boolean
useVideo)
throws IOException {
// Set up MediaExtractor to read from the source.
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(srcPath);
int trackCount = extractor.getTrackCount();
// Set up MediaMuxer for the destination.
MediaMuxer muxer;
muxer = new MediaMuxer(dstPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// Set up the tracks and retrieve the max buffer size for selected
// tracks.
HashMap<Integer, Integer> indexMap = new HashMap<>(trackCount);
int bufferSize = -1;
for (int i = 0; i < trackCount; i++) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
boolean selectCurrentTrack = false;
if (mime.startsWith("audio/") && useAudio) {
selectCurrentTrack = true;
} else if (mime.startsWith("video/") && useVideo) {
selectCurrentTrack = true;
}
if (selectCurrentTrack) {
extractor.selectTrack(i);
int dstIndex = muxer.addTrack(format);
indexMap.put(i, dstIndex);
if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
int newSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
bufferSize = newSize > bufferSize ? newSize : bufferSize;
}
}
}
if (bufferSize < 0) {
bufferSize = DEFAULT_BUFFER_SIZE;
}
// Set up the orientation and starting time for extractor.
MediaMetadataRetriever retrieverSrc = new MediaMetadataRetriever();
retrieverSrc.setDataSource(srcPath);
String degreesString = retrieverSrc.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
if (degreesString != null) {
int degrees = Integer.parseInt(degreesString);
if (degrees >= 0) {
muxer.setOrientationHint(degrees);
}
}
if (startMs > 0) {
extractor.seekTo(startMs * 1000, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
}
// Copy the samples from MediaExtractor to MediaMuxer. We will loop
// for copying each sample and stop when we get to the end of the source
// file or exceed the end time of the trimming.
int offset = 0;
int trackIndex = -1;
ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize);
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
try {
muxer.start();
while (true) {
bufferInfo.offset = offset;
bufferInfo.size = extractor.readSampleData(dstBuf, offset);
if (bufferInfo.size < 0) {
InstabugSDKLogger.d(TAG, "Saw input EOS.");
bufferInfo.size = 0;
break;
} else {
bufferInfo.presentationTimeUs = extractor.getSampleTime();
if (endMs > 0 && bufferInfo.presentationTimeUs > (endMs * 1000)) {
InstabugSDKLogger.d(TAG, "The current sample is over the trim end time.");
break;
} else {
bufferInfo.flags = extractor.getSampleFlags();
trackIndex = extractor.getSampleTrackIndex();
muxer.writeSampleData(indexMap.get(trackIndex), dstBuf,
bufferInfo);
extractor.advance();
}
}
}
muxer.stop();

//deleting the old file
File file = new File(srcPath);
file.delete();
} catch (IllegalStateException e) {
// Swallow the exception due to malformed source.
InstabugSDKLogger.w(TAG, "The source video file is malformed");
} finally {
muxer.release();
}
return;
}

EDIT: just to name the source for this. It's from the gallery app of Google, which allows to trim videos, in a file called "VideoUtils":
https://android.googlesource.com/platform/packages/apps/Gallery2/+/634248d/src/com/android/gallery3d/app/VideoUtils.java

The missing code is:

private static final String LOGTAG = "VideoUtils";
private static final int DEFAULT_BUFFER_SIZE = 1 * 1024 * 1024;


Related Topics



Leave a reply



Submit