下面列出了android.media.MediaExtractor#release ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@RequiresApi(23)
static @Nullable VideoTrackConverter create(
final @NonNull MediaInput input,
final long timeFrom,
final long timeTo,
final int videoResolution,
final int videoBitrate,
final @NonNull String videoCodec) throws IOException, TranscodingException {
final MediaExtractor videoExtractor = input.createExtractor();
final int videoInputTrack = getAndSelectVideoTrackIndex(videoExtractor);
if (videoInputTrack == -1) {
videoExtractor.release();
return null;
}
return new VideoTrackConverter(videoExtractor, videoInputTrack, timeFrom, timeTo, videoResolution, videoBitrate, videoCodec);
}
public static float getAveFrameRate(VideoProcessor.MediaSource mediaSource) throws IOException {
MediaExtractor extractor = new MediaExtractor();
mediaSource.setDataSource(extractor);
int trackIndex = VideoUtil.selectTrack(extractor, false);
extractor.selectTrack(trackIndex);
long lastSampleTimeUs = 0;
int frameCount = 0;
while (true) {
long sampleTime = extractor.getSampleTime();
if (sampleTime < 0) {
break;
} else {
lastSampleTimeUs = sampleTime;
}
frameCount++;
extractor.advance();
}
extractor.release();
return frameCount / (lastSampleTimeUs / 1000f / 1000f);
}
public static boolean isStereo(String aacPath) throws IOException {
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(aacPath);
MediaFormat format = null;
int numTracks = extractor.getTrackCount();
for (int i = 0; i < numTracks; i++) {
format = extractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if (mime.startsWith("audio/")) {
break;
}
}
extractor.release();
if (format == null) {
return false;
}
return format.getInteger(MediaFormat.KEY_CHANNEL_COUNT) > 1;
}
public int retrieveFrameRate() {
MediaExtractor extractor = new MediaExtractor();
int frameRate = -1;
try {
//Adjust data source as per the requirement if file, URI, etc.
extractor.setDataSource(getPath());
int numTracks = extractor.getTrackCount();
for (int i = 0; i < numTracks; i++) {
MediaFormat format = extractor.getTrackFormat(i);
if (format.containsKey(MediaFormat.KEY_FRAME_RATE)) {
frameRate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//Release stuff
extractor.release();
}
return frameRate;
}
/**
* 该音频是否符合采样率是sampleRate,通道数是channelCount,值为-1表示忽略该条件
*
* @param audioFile
* @param sampleRate
* @param channelCount
* @return
*/
public static boolean isMatchAudioFormat(String audioFile, int sampleRate,int channelCount){
MediaExtractor mex = new MediaExtractor();
try {
mex.setDataSource(audioFile);
} catch (IOException e) {
e.printStackTrace();
}
MediaFormat mf = mex.getTrackFormat(0);
boolean result = true;
if(sampleRate != -1){
result = sampleRate == mf.getInteger(MediaFormat.KEY_SAMPLE_RATE);
}
if(result && channelCount != -1){
result = channelCount == mf.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
}
mex.release();
return result;
}
@TargetApi( Build.VERSION_CODES.JELLY_BEAN )
public static int GetMediaFormatPropertyInteger( Uri uri, String key, int defaultValue ) {
int value = defaultValue;
MediaExtractor extractor = new MediaExtractor();
try {
extractor.setDataSource( uri.toString() );
} catch ( IOException e ) {
e.printStackTrace();
return value;
}
MediaFormat format = GetTrackFormat( extractor, MIME_TYPE_AVC );
extractor.release();
if ( format.containsKey( key ) ) {
value = format.getInteger( key );
}
return value;
}
static @Nullable
AudioTrackConverter create(
final @NonNull MediaInput input,
final long timeFrom,
final long timeTo,
final int audioBitrate) throws IOException {
final MediaExtractor audioExtractor = input.createExtractor();
final int audioInputTrack = getAndSelectAudioTrackIndex(audioExtractor);
if (audioInputTrack == -1) {
audioExtractor.release();
return null;
}
return new AudioTrackConverter(audioExtractor, audioInputTrack, timeFrom, timeTo, audioBitrate);
}
/**
* 用于制作全关键帧视频时计算比特率应该为多少
*
* @return
*/
public static int getBitrateForAllKeyFrameVideo(VideoProcessor.MediaSource input) throws IOException {
MediaExtractor extractor = new MediaExtractor();
input.setDataSource(extractor);
int trackIndex = VideoUtil.selectTrack(extractor, false);
extractor.selectTrack(trackIndex);
int keyFrameCount = 0;
int frameCount = 0;
while (true) {
int flags = extractor.getSampleFlags();
if (flags > 0 && (flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
keyFrameCount++;
}
long sampleTime = extractor.getSampleTime();
if (sampleTime < 0) {
break;
}
frameCount++;
extractor.advance();
}
extractor.release();
float bitrateMultiple = (frameCount - keyFrameCount) / (float) keyFrameCount + 1;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
input.setDataSource(retriever);
int oriBitrate = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE));
retriever.release();
if (frameCount == keyFrameCount) {
return oriBitrate;
}
return (int) (bitrateMultiple * oriBitrate);
}
public static Pair<Integer, Integer> getVideoFrameCount(String input) throws IOException {
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(input);
int trackIndex = VideoUtil.selectTrack(extractor, false);
extractor.selectTrack(trackIndex);
int keyFrameCount = 0;
int frameCount = 0;
while (true) {
int flags = extractor.getSampleFlags();
if (flags > 0 && (flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
keyFrameCount++;
}
long sampleTime = extractor.getSampleTime();
if (sampleTime < 0) {
break;
}
frameCount++;
extractor.advance();
}
extractor.release();
return new Pair<>(keyFrameCount, frameCount);
}
public static int getFrameRate(VideoProcessor.MediaSource mediaSource) {
MediaExtractor extractor = new MediaExtractor();
try {
mediaSource.setDataSource(extractor);
int trackIndex = VideoUtil.selectTrack(extractor, false);
MediaFormat format = extractor.getTrackFormat(trackIndex);
return format.containsKey(MediaFormat.KEY_FRAME_RATE) ? format.getInteger(MediaFormat.KEY_FRAME_RATE) : -1;
} catch (IOException e) {
CL.e(e);
return -1;
} finally {
extractor.release();
}
}
/**
* 去掉视频的音轨
*/
public static void removeAudioTrack(String videoPath, String outPath) throws IOException {
MediaExtractor videoExtractor = new MediaExtractor();
videoExtractor.setDataSource(videoPath);
try {
int videoTrack = VideoUtil.selectTrack(videoExtractor, false);
videoExtractor.selectTrack(videoTrack);
MediaFormat videoFormat = videoExtractor.getTrackFormat(videoTrack);
MediaMuxer mediaMuxer = new MediaMuxer(outPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
int muxerVideoTrackIndex = mediaMuxer.addTrack(videoFormat);
mediaMuxer.start();
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
//写视频
int maxBufferSize = videoFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
ByteBuffer videoBuffer = ByteBuffer.allocateDirect(maxBufferSize);
while (true) {
long sampleTimeUs = videoExtractor.getSampleTime();
if (sampleTimeUs == -1) {
break;
}
int flags = videoExtractor.getSampleFlags();
int size = videoExtractor.readSampleData(videoBuffer, 0);
info.presentationTimeUs = sampleTimeUs;
info.flags = flags;
info.size = size;
mediaMuxer.writeSampleData(muxerVideoTrackIndex, videoBuffer, info);
videoExtractor.advance();
}
mediaMuxer.stop();
mediaMuxer.release();
} finally {
videoExtractor.release();
}
}
static void extractThumbnails(final @NonNull MediaInput input,
final int thumbnailCount,
final int thumbnailResolution,
final @NonNull Callback callback)
{
MediaExtractor extractor = null;
MediaCodec decoder = null;
OutputSurface outputSurface = null;
try {
extractor = input.createExtractor();
MediaFormat mediaFormat = null;
for (int index = 0; index < extractor.getTrackCount(); ++index) {
if (extractor.getTrackFormat(index).getString(MediaFormat.KEY_MIME).startsWith("video/")) {
extractor.selectTrack(index);
mediaFormat = extractor.getTrackFormat(index);
break;
}
}
if (mediaFormat != null) {
final String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
final int rotation = mediaFormat.containsKey(MediaFormat.KEY_ROTATION) ? mediaFormat.getInteger(MediaFormat.KEY_ROTATION) : 0;
final int width = mediaFormat.getInteger(MediaFormat.KEY_WIDTH);
final int height = mediaFormat.getInteger(MediaFormat.KEY_HEIGHT);
final int outputWidth;
final int outputHeight;
if (width < height) {
outputWidth = thumbnailResolution;
outputHeight = height * outputWidth / width;
} else {
outputHeight = thumbnailResolution;
outputWidth = width * outputHeight / height;
}
final int outputWidthRotated;
final int outputHeightRotated;
if ((rotation % 180 == 90)) {
//noinspection SuspiciousNameCombination
outputWidthRotated = outputHeight;
//noinspection SuspiciousNameCombination
outputHeightRotated = outputWidth;
} else {
outputWidthRotated = outputWidth;
outputHeightRotated = outputHeight;
}
Log.i(TAG, "video: " + width + "x" + height + " " + rotation);
Log.i(TAG, "output: " + outputWidthRotated + "x" + outputHeightRotated);
outputSurface = new OutputSurface(outputWidthRotated, outputHeightRotated, true);
decoder = MediaCodec.createDecoderByType(mime);
decoder.configure(mediaFormat, outputSurface.getSurface(), null, 0);
decoder.start();
long duration = 0;
if (mediaFormat.containsKey(MediaFormat.KEY_DURATION)) {
duration = mediaFormat.getLong(MediaFormat.KEY_DURATION);
} else {
Log.w(TAG, "Video is missing duration!");
}
callback.durationKnown(duration);
doExtract(extractor, decoder, outputSurface, outputWidthRotated, outputHeightRotated, duration, thumbnailCount, callback);
}
} catch (IOException | TranscodingException e) {
Log.w(TAG, e);
callback.failed();
} finally {
if (outputSurface != null) {
outputSurface.release();
}
if (decoder != null) {
decoder.stop();
decoder.release();
}
if (extractor != null) {
extractor.release();
}
}
}
/**
* 需要改变音频速率的情况下,需要先解码->改变速率->编码
*/
private void decodeToPCM(MediaCodec decoder, MediaExtractor extractor, MediaFormat oriAudioFormat, String outPath, Long endTimeUs) throws IOException {
int maxBufferSize = getAudioMaxBufferSize(oriAudioFormat);
ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
//调整音频速率需要重解码音频帧
decoder.configure(oriAudioFormat, null, null, 0);
decoder.start();
boolean decodeDone = false;
boolean decodeInputDone = false;
final int TIMEOUT_US = 2500;
File pcmFile = new File(outPath);
FileChannel writeChannel = new FileOutputStream(pcmFile).getChannel();
ByteBuffer[] inputBuffers = null;
ByteBuffer[] outputBuffers = null;
try {
while (!decodeDone) {
if (!decodeInputDone) {
boolean eof = false;
int decodeInputIndex = decoder.dequeueInputBuffer(TIMEOUT_US);
if (Build.VERSION.SDK_INT < 21 && decodeInputIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
outputBuffers = decoder.getOutputBuffers();
inputBuffers = decoder.getInputBuffers();
} else if (decodeInputIndex >= 0) {
long sampleTimeUs = extractor.getSampleTime();
if (sampleTimeUs == -1) {
eof = true;
} else if (endTimeUs != null && sampleTimeUs > endTimeUs) {
eof = true;
}
if (eof) {
decodeInputDone = true;
decoder.queueInputBuffer(decodeInputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
} else {
info.size = extractor.readSampleData(buffer, 0);
info.presentationTimeUs = sampleTimeUs;
info.flags = extractor.getSampleFlags();
ByteBuffer inputBuffer = null;
if (android.os.Build.VERSION.SDK_INT >= 21) {
inputBuffer = decoder.getInputBuffer(decodeInputIndex);
} else {
inputBuffer = inputBuffers[decodeInputIndex];
}
inputBuffer.put(buffer);
MLog.i(TAG, "audio decode queueInputBuffer " + info.presentationTimeUs / 1000);
decoder.queueInputBuffer(decodeInputIndex, 0, info.size, info.presentationTimeUs, info.flags);
extractor.advance();
}
}
}
while (!decodeDone) {
int outputBufferIndex = decoder.dequeueOutputBuffer(info, TIMEOUT_US);
if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
break;
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = decoder.getOutputFormat();
MLog.i(TAG, "audio decode newFormat = " + newFormat);
} else if (outputBufferIndex < 0) {
//ignore
MLog.e(TAG, "unexpected result from audio decoder.dequeueOutputBuffer: " + outputBufferIndex);
} else {
if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
decodeDone = true;
} else {
ByteBuffer decodeOutputBuffer = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
decodeOutputBuffer = decoder.getOutputBuffer(outputBufferIndex);
} else {
decodeOutputBuffer = outputBuffers[outputBufferIndex];
}
MLog.i(TAG, "audio decode saveFrame " + info.presentationTimeUs / 1000);
writeChannel.write(decodeOutputBuffer);
}
decoder.releaseOutputBuffer(outputBufferIndex, false);
}
}
}
} finally {
writeChannel.close();
extractor.release();
decoder.stop();
decoder.release();
}
}
static long appendVideoTrack(MediaExtractor extractor, MediaMuxer mediaMuxer, int muxerVideoTrackIndex,
Integer startTimeUs, Integer endTimeUs, long baseMuxerFrameTimeUs, int bitrate, int iFrameInterval,
boolean isFirst, boolean isLast) throws Exception {
int videoTrack = selectTrack(extractor, false);
extractor.selectTrack(videoTrack);
if (startTimeUs == null) {
startTimeUs = 0;
}
extractor.seekTo(startTimeUs, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
MediaFormat videoFormat = extractor.getTrackFormat(videoTrack);
//初始化编码器
int resultWidth = videoFormat.getInteger(MediaFormat.KEY_WIDTH);
int resultHeight = videoFormat.getInteger(MediaFormat.KEY_HEIGHT);
AtomicBoolean decodeDone = new AtomicBoolean(false);
VideoAppendEncodeThread encodeThread = new VideoAppendEncodeThread(extractor, mediaMuxer, bitrate,
resultWidth, resultHeight, iFrameInterval, videoTrack,
decodeDone, baseMuxerFrameTimeUs, isFirst, isLast, muxerVideoTrackIndex);
VideoDecodeThread decodeThread = new VideoDecodeThread(encodeThread, extractor, startTimeUs == null ? null : startTimeUs / 1000,
endTimeUs == null ? null : endTimeUs / 1000,
null, null, null, false,videoTrack, decodeDone);
decodeThread.start();
encodeThread.start();
try {
decodeThread.join();
encodeThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
extractor.release();
} catch (Exception e2) {
CL.e(e2);
}
if (encodeThread.getException() != null) {
throw encodeThread.getException();
} else if (decodeThread.getException() != null) {
throw decodeThread.getException();
}
return encodeThread.getLastFrametimeUs();
}
/**
* 对视频先检查,如果不是全关键帧,先处理成所有帧都是关键帧,再逆序
*/
public static void reverseVideo(Context context, MediaSource input, String output, boolean reverseAudio, @Nullable VideoProgressListener listener) throws Exception {
File tempFile = new File(context.getCacheDir(), System.currentTimeMillis() + ".temp");
File temp2File = new File(context.getCacheDir(), System.currentTimeMillis() + ".temp2");
try {
MediaExtractor extractor = new MediaExtractor();
input.setDataSource(extractor);
int trackIndex = VideoUtil.selectTrack(extractor, false);
extractor.selectTrack(trackIndex);
int keyFrameCount = 0;
int frameCount = 0;
List<Long> frameTimeStamps = new ArrayList<>();
while (true) {
int flags = extractor.getSampleFlags();
if (flags > 0 && (flags & MediaExtractor.SAMPLE_FLAG_SYNC) != 0) {
keyFrameCount++;
}
long sampleTime = extractor.getSampleTime();
if (sampleTime < 0) {
break;
}
frameTimeStamps.add(sampleTime);
frameCount++;
extractor.advance();
}
extractor.release();
if (frameCount == keyFrameCount || frameCount == keyFrameCount + 1) {
reverseVideoNoDecode(input, output, reverseAudio, frameTimeStamps, listener);
} else {
VideoMultiStepProgress stepProgress = new VideoMultiStepProgress(new float[]{0.45f, 0.1f, 0.45f}, listener);
stepProgress.setCurrentStep(0);
float bitrateMultiple = (frameCount - keyFrameCount) / (float) keyFrameCount + 1;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
input.setDataSource(retriever);
int oriBitrate = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE));
int duration = Integer.parseInt(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION));
try {
processor(context)
.input(input)
.output(tempFile.getAbsolutePath())
.bitrate((int) (oriBitrate * bitrateMultiple))
.iFrameInterval(0)
.progressListener(stepProgress)
.process();
} catch (MediaCodec.CodecException e) {
CL.e(e);
/** Nexus5上-1代表全关键帧*/
processor(context)
.input(input)
.output(tempFile.getAbsolutePath())
.bitrate((int) (oriBitrate * bitrateMultiple))
.iFrameInterval(-1)
.progressListener(stepProgress)
.process();
}
stepProgress.setCurrentStep(1);
reverseVideoNoDecode(new MediaSource(tempFile.getAbsolutePath()), temp2File.getAbsolutePath(), reverseAudio, null, stepProgress);
int oriIFrameInterval = (int) (keyFrameCount / (duration / 1000f));
oriIFrameInterval = oriIFrameInterval == 0 ? 1 : oriIFrameInterval;
stepProgress.setCurrentStep(2);
processor(context)
.input(temp2File.getAbsolutePath())
.output(output)
.bitrate(oriBitrate)
.iFrameInterval(oriIFrameInterval)
.progressListener(stepProgress)
.process();
}
} finally {
tempFile.delete();
temp2File.delete();
}
}
/**
* 需要改变音频速率的情况下,需要先解码->改变速率->编码
*/
public static void decodeToPCM(VideoProcessor.MediaSource audioSource, String outPath, Integer startTimeUs, Integer endTimeUs) throws IOException {
MediaExtractor extractor = new MediaExtractor();
audioSource.setDataSource(extractor);
int audioTrack = VideoUtil.selectTrack(extractor, true);
extractor.selectTrack(audioTrack);
if (startTimeUs == null) {
startTimeUs = 0;
}
extractor.seekTo(startTimeUs, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
MediaFormat oriAudioFormat = extractor.getTrackFormat(audioTrack);
int maxBufferSize;
if (oriAudioFormat.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
maxBufferSize = oriAudioFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
} else {
maxBufferSize = 100 * 1000;
}
ByteBuffer buffer = ByteBuffer.allocateDirect(maxBufferSize);
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
//调整音频速率需要重解码音频帧
MediaCodec decoder = MediaCodec.createDecoderByType(oriAudioFormat.getString(MediaFormat.KEY_MIME));
decoder.configure(oriAudioFormat, null, null, 0);
decoder.start();
boolean decodeDone = false;
boolean decodeInputDone = false;
final int TIMEOUT_US = 2500;
File pcmFile = new File(outPath);
FileChannel writeChannel = new FileOutputStream(pcmFile).getChannel();
try {
while (!decodeDone) {
if (!decodeInputDone) {
boolean eof = false;
int decodeInputIndex = decoder.dequeueInputBuffer(TIMEOUT_US);
if (decodeInputIndex >= 0) {
long sampleTimeUs = extractor.getSampleTime();
if (sampleTimeUs == -1) {
eof = true;
} else if (sampleTimeUs < startTimeUs) {
extractor.advance();
continue;
} else if (endTimeUs != null && sampleTimeUs > endTimeUs) {
eof = true;
}
if (eof) {
decodeInputDone = true;
decoder.queueInputBuffer(decodeInputIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
} else {
info.size = extractor.readSampleData(buffer, 0);
info.presentationTimeUs = sampleTimeUs;
info.flags = extractor.getSampleFlags();
ByteBuffer inputBuffer = decoder.getInputBuffer(decodeInputIndex);
inputBuffer.put(buffer);
CL.it(TAG, "audio decode queueInputBuffer " + info.presentationTimeUs / 1000);
decoder.queueInputBuffer(decodeInputIndex, 0, info.size, info.presentationTimeUs, info.flags);
extractor.advance();
}
}
}
while (!decodeDone) {
int outputBufferIndex = decoder.dequeueOutputBuffer(info, TIMEOUT_US);
if (outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
break;
} else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
MediaFormat newFormat = decoder.getOutputFormat();
CL.it(TAG, "audio decode newFormat = " + newFormat);
} else if (outputBufferIndex < 0) {
//ignore
CL.et(TAG, "unexpected result from audio decoder.dequeueOutputBuffer: " + outputBufferIndex);
} else {
if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM) {
decodeDone = true;
} else {
ByteBuffer decodeOutputBuffer = decoder.getOutputBuffer(outputBufferIndex);
CL.it(TAG, "audio decode saveFrame " + info.presentationTimeUs / 1000);
writeChannel.write(decodeOutputBuffer);
}
decoder.releaseOutputBuffer(outputBufferIndex, false);
}
}
}
} finally {
writeChannel.close();
extractor.release();
decoder.stop();
decoder.release();
}
}
protected boolean process() throws IOException {
mMediaExtractor = new MediaExtractor();
mMediaExtractor.setDataSource(SDCARD_PATH+"/input.mp4");
int mVideoTrackIndex = -1;
int framerate = 0;
for(int i = 0; i < mMediaExtractor.getTrackCount(); i++) {
MediaFormat format = mMediaExtractor.getTrackFormat(i);
String mime = format.getString(MediaFormat.KEY_MIME);
if(!mime.startsWith("video/")) {
continue;
}
framerate = format.getInteger(MediaFormat.KEY_FRAME_RATE);
mMediaExtractor.selectTrack(i);
mMediaMuxer = new MediaMuxer(SDCARD_PATH+"/ouput.mp4", OutputFormat.MUXER_OUTPUT_MPEG_4);
mVideoTrackIndex = mMediaMuxer.addTrack(format);
mMediaMuxer.start();
}
if(mMediaMuxer == null) {
return false;
}
BufferInfo info = new BufferInfo();
info.presentationTimeUs = 0;
ByteBuffer buffer = ByteBuffer.allocate(500*1024);
while(true) {
int sampleSize = mMediaExtractor.readSampleData(buffer, 0);
if(sampleSize < 0) {
break;
}
mMediaExtractor.advance();
info.offset = 0;
info.size = sampleSize;
info.flags = MediaCodec.BUFFER_FLAG_SYNC_FRAME;
info.presentationTimeUs += 1000*1000/framerate;
mMediaMuxer.writeSampleData(mVideoTrackIndex,buffer,info);
}
mMediaExtractor.release();
mMediaMuxer.stop();
mMediaMuxer.release();
return true;
}
private void feedClipToEncoder( SamplerClip clip ) {
mLastSampleTime = 0;
MediaCodec decoder = null;
MediaExtractor extractor = setupExtractorForClip(clip);
if(extractor == null ) {
return;
}
int trackIndex = getVideoTrackIndex(extractor);
extractor.selectTrack( trackIndex );
MediaFormat clipFormat = extractor.getTrackFormat( trackIndex );
if ( clip.getStartTime() != -1 ) {
extractor.seekTo( clip.getStartTime() * 1000, MediaExtractor.SEEK_TO_PREVIOUS_SYNC );
clip.setStartTime( extractor.getSampleTime() / 1000 );
}
try {
decoder = MediaCodec.createDecoderByType( MediaHelper.MIME_TYPE_AVC );
mOutputSurface = new OutputSurface();
decoder.configure( clipFormat, mOutputSurface.getSurface(), null, 0 );
decoder.start();
resampleVideo( extractor, decoder, clip );
} finally {
if ( mOutputSurface != null ) {
mOutputSurface.release();
}
if ( decoder != null ) {
decoder.stop();
decoder.release();
}
if ( extractor != null ) {
extractor.release();
extractor = null;
}
}
}