Untitled
unknown
plain_text
a year ago
5.9 kB
6
Indexable
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaMuxer;
import android.view.Surface;
import java.io.IOException;
import java.nio.ByteBuffer;
public class VideoProcessor {
private String inputPath;
private String outputPath;
public VideoProcessor(String inputPath, String outputPath) {
this.inputPath = inputPath;
this.outputPath = outputPath;
}
public void processVideo() {
try {
// Setup decoder
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(inputPath);
int videoTrackIndex = selectVideoTrack(extractor);
extractor.selectTrack(videoTrackIndex);
MediaFormat format = extractor.getTrackFormat(videoTrackIndex);
int width = format.getInteger(MediaFormat.KEY_WIDTH);
int height = format.getInteger(MediaFormat.KEY_HEIGHT);
MediaCodec decoder = MediaCodec.createDecoderByType(format.getString(MediaFormat.KEY_MIME));
Surface inputSurface = setupDecoder(decoder, format);
// Setup encoder
MediaCodec encoder = setupEncoder(width, height);
Surface outputSurface = encoder.createInputSurface();
// Setup muxer for output file
MediaMuxer muxer = new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
// Setup EGL for OpenGL rendering
EGLHelper eglHelper = new EGLHelper(outputSurface);
OpenGLRenderer renderer = new OpenGLRenderer();
// Start decoder and encoder
decoder.start();
encoder.start();
// Configure the muxer with video format
int videoTrackIndexForMuxer = muxer.addTrack(encoder.getOutputFormat());
muxer.start();
// Process frames
processFrames(extractor, decoder, encoder, muxer, eglHelper, renderer, videoTrackIndexForMuxer);
// Stop muxer and codecs
muxer.stop();
muxer.release();
decoder.stop();
decoder.release();
encoder.stop();
encoder.release();
} catch (Exception e) {
e.printStackTrace();
}
}
private Surface setupDecoder(MediaCodec decoder, MediaFormat format) {
Surface surface = MediaCodec.createPersistentInputSurface();
decoder.configure(format, surface, null, 0);
return surface;
}
private MediaCodec setupEncoder(int width, int height) throws IOException {
MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height);
format.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
MediaCodec encoder = MediaCodec.createEncoderByType("video/avc");
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
return encoder;
}
private void processFrames(MediaExtractor extractor, MediaCodec decoder, MediaCodec encoder,
MediaMuxer muxer, EGLHelper eglHelper, OpenGLRenderer renderer,
int videoTrackIndexForMuxer) {
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
boolean endOfStream = false;
while (!endOfStream) {
// Feed input to decoder
int inputIndex = decoder.dequeueInputBuffer(10000);
if (inputIndex >= 0) {
ByteBuffer inputBuffer = decoder.getInputBuffer(inputIndex);
int size = extractor.readSampleData(inputBuffer, 0);
if (size < 0) {
decoder.queueInputBuffer(inputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
endOfStream = true;
} else {
decoder.queueInputBuffer(inputIndex, 0, size, extractor.getSampleTime(), 0);
extractor.advance();
}
}
// Process decoder output
int outputIndex = decoder.dequeueOutputBuffer(bufferInfo, 10000);
if (outputIndex >= 0) {
eglHelper.makeCurrent();
renderer.drawFrame(eglHelper.getTextureId());
eglHelper.swapBuffers();
// Encoder
int encoderInputIndex = encoder.dequeueInputBuffer(10000);
if (encoderInputIndex >= 0) {
ByteBuffer encoderInputBuffer = encoder.getInputBuffer(encoderInputIndex);
encoderInputBuffer.clear();
encoder.queueInputBuffer(encoderInputIndex, 0, bufferInfo.size, bufferInfo.presentationTimeUs, 0);
}
// Encoder output
int encoderOutputIndex = encoder.dequeueOutputBuffer(bufferInfo, 10000);
if (encoderOutputIndex >= 0) {
muxer.writeSampleData(videoTrackIndexForMuxer, encoder.getOutputBuffer(encoderOutputIndex), bufferInfo);
encoder.releaseOutputBuffer(encoderOutputIndex, false);
}
decoder.releaseOutputBuffer(outputIndex, true);
}
}
}
private int selectVideoTrack(MediaExtractor extractor) {
for (int i = 0; i < extractor.getTrackCount(); i++) {
MediaFormat format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("video/")) {
return i;
}
}
throw new IllegalArgumentException("No video track found");
}
}Editor is loading...
Leave a Comment