Untitled
unknown
plain_text
a year ago
11 kB
6
Indexable
public boolean convertVideo(final String sourcePath, String destinationPath, int width, int height, int duration, SlimProgressListener listener) {
this.path = sourcePath;
this.outputPath = destinationPath;
mWidth = width;
mHeight = height;
long endTime = -1;
boolean error = false;
long videoStartTime = -1;
long time = System.currentTimeMillis();
File cacheFile = new File(destinationPath);
File inputFile = new File(path);
if (!inputFile.canRead()) {
return false;
}
MediaExtractor mVideoExtractor = null;
MediaExtractor mAudioExtractor = null;
try {
// video MediaExtractor
mVideoExtractor = new MediaExtractor();
mVideoExtractor.setDataSource(inputFile.toString());
// audio MediaExtractor
mAudioExtractor = new MediaExtractor();
mAudioExtractor.setDataSource(inputFile.toString());
try {
mMuxer = new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
} catch (IOException ioe) {
throw new RuntimeException("MediaMuxer creation failed", ioe);
}
int muxerAudioTrackIndex = 0;
int audioIndex = selectTrack(mAudioExtractor, true);
if (audioIndex >= 0) {
mAudioExtractor.selectTrack(audioIndex);
mAudioExtractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
MediaFormat trackFormat = mAudioExtractor.getTrackFormat(audioIndex);
muxerAudioTrackIndex = mMuxer.addTrack(trackFormat);
}
/**
* mediacodec + surface + opengl
* */
int videoIndex = selectTrack(mVideoExtractor, false);
if (videoIndex >= 0) {
boolean outputDone = false;
boolean inputDone = false;
int videoTrackIndex = MEDIATYPE_NOT_AUDIO_VIDEO;
mVideoExtractor.selectTrack(videoIndex);
mVideoExtractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
MediaFormat inputFormat = mVideoExtractor.getTrackFormat(videoIndex);
/**
** init mediacodec / encoder and decoder
**/
prepareEncoder(inputFormat);
while (!outputDone) {
if (!inputDone) {
boolean eof = false;
int index = mVideoExtractor.getSampleTrackIndex();
if (index == videoIndex) {
int inputBufIndex = mDecoder.dequeueInputBuffer(TIMEOUT_USEC);
if (inputBufIndex >= 0) {
ByteBuffer inputBuf;
inputBuf = mDecoder.getInputBuffer(inputBufIndex);
int chunkSize = mVideoExtractor.readSampleData(inputBuf, 0);
if (chunkSize < 0) {
mDecoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
inputDone = true;
} else {
mDecoder.queueInputBuffer(inputBufIndex, 0, chunkSize, mVideoExtractor.getSampleTime(), 0);
mVideoExtractor.advance();
}
}
} else if (index == -1) {
eof = true;
}
if (eof) {
int inputBufIndex = mDecoder.dequeueInputBuffer(TIMEOUT_USEC);
if (inputBufIndex >= 0) {
mDecoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
inputDone = true;
}
}
}
boolean decoderOutputAvailable = true;
while (decoderOutputAvailable) {
int encoderStatus = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
} else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = mEncoder.getOutputFormat();
if (videoTrackIndex == MEDIATYPE_NOT_AUDIO_VIDEO) {
videoTrackIndex = mMuxer.addTrack(newFormat);
mTrackIndex = videoTrackIndex;
mMuxer.start();
}
} else if (encoderStatus < 0) {
throw new RuntimeException("unexpected result from mEncoder.dequeueOutputBuffer: " + encoderStatus);
} else {
ByteBuffer encodedData;
encodedData = mEncoder.getOutputBuffer(encoderStatus);
if (encodedData == null) {
throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
}
if (mBufferInfo.size > 1) {
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
mMuxer.writeSampleData(videoTrackIndex, encodedData, mBufferInfo);
} else if (videoTrackIndex == MEDIATYPE_NOT_AUDIO_VIDEO) {
byte[] csd = new byte[mBufferInfo.size];
encodedData.limit(mBufferInfo.offset + mBufferInfo.size);
encodedData.position(mBufferInfo.offset);
encodedData.get(csd);
ByteBuffer sps = null;
ByteBuffer pps = null;
for (int a = mBufferInfo.size - 1; a >= 0; a--) {
if (a > 3) {
if (csd[a] == 1 && csd[a - 1] == 0 && csd[a - 2] == 0 && csd[a - 3] == 0) {
sps = ByteBuffer.allocate(a - 3);
pps = ByteBuffer.allocate(mBufferInfo.size - (a - 3));
sps.put(csd, 0, a - 3).position(0);
pps.put(csd, a - 3, mBufferInfo.size - (a - 3)).position(0);
break;
}
} else {
break;
}
}
MediaFormat newFormat = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
if (sps != null) {
newFormat.setByteBuffer("csd-0", sps);
newFormat.setByteBuffer("csd-1", pps);
}
videoTrackIndex = mMuxer.addTrack(newFormat);
mMuxer.start();
}
}
outputDone = (mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
mEncoder.releaseOutputBuffer(encoderStatus, false);
}
if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) {
continue;
}
int decoderStatus = mDecoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
decoderOutputAvailable = false;
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
} else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = mDecoder.getOutputFormat();
Log.e(TAG, "newFormat = " + newFormat);
} else if (decoderStatus < 0) {
throw new RuntimeException("unexpected result from mDecoder.dequeueOutputBuffer: " + decoderStatus);
} else {
boolean doRender = mBufferInfo.size != 0;
mDecoder.releaseOutputBuffer(decoderStatus, doRender);
if (doRender) {
boolean errorWait = false;
try {
mInputSurface.awaitNewImage();
} catch (Exception e) {
errorWait = true;
Log.e(TAG, e.getMessage());
}
if (!errorWait) {
mInputSurface.drawImage();
mInputSurface.setPresentationTime(mBufferInfo.presentationTimeUs * 1000);
if (listener != null) {
listener.onProgress((float) mBufferInfo.presentationTimeUs / (float) duration * 100);
}
mInputSurface.swapBuffers();
}
}
if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
decoderOutputAvailable = false;
Log.e(TAG, "decoder stream end");
mEncoder.signalEndOfInputStream();
}
}
}
}
}
writeAudioTrack(mAudioExtractor, mMuxer, mBufferInfo, videoStartTime, endTime, cacheFile, muxerAudioTrackIndex);
} catch (Exception e) {
error = true;
Log.e(TAG, e.getMessage());
} finally {
if (mVideoExtractor != null) {
mVideoExtractor.release();
}
if (mAudioExtractor != null) {
mAudioExtractor.release();
}
Log.e(TAG, "time = " + (System.currentTimeMillis() - time));
}
Log.e("ViratPath", path + "");
Log.e("ViratPath", cacheFile.getPath() + "");
Log.e("ViratPath", inputFile.getPath() + "");
releaseCoder();
return !error;
}
Editor is loading...
Leave a Comment