// started from: https://github.com/Kickflip/kickflip-android-sdk/blob/e35e0a5bb7161ccffebd564ec1a76a0e2c053fc8/sdk/src/main/java/io/kickflip/sdk/av/AndroidMuxer.java package io.cine.android.streaming; import android.media.MediaCodec; import android.media.MediaFormat; import android.media.MediaMuxer; import android.util.Log; import java.io.IOException; import java.nio.ByteBuffer; /** * @hide */ public class AndroidMuxer extends Muxer { private static final String TAG = "AndroidMuxer"; private static final boolean VERBOSE = false; private MediaMuxer mMuxer; private boolean mStarted; public AndroidMuxer() { mStarted = false; } @Override public void prepare(EncodingConfig config) { super.prepare(config); try { switch (config.getFormat()) { case MPEG4: mMuxer = new MediaMuxer(config.getOutputPath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); break; default: throw new IllegalArgumentException("Unrecognized format!"); } } catch (IOException e) { throw new RuntimeException("MediaMuxer creation failed", e); } } @Override public int addTrack(MediaFormat trackFormat) { super.addTrack(trackFormat); if (mStarted) throw new RuntimeException("format changed twice"); int track = mMuxer.addTrack(trackFormat); if (allTracksAdded()) { start(); } return track; } protected void start() { mMuxer.start(); mStarted = true; } public void shutdown() { mMuxer.stop(); mStarted = false; release(); mMuxer.release(); } @Override public void writeSampleData(MediaCodec encoder, int trackIndex, int bufferIndex, ByteBuffer encodedData, MediaCodec.BufferInfo bufferInfo) { super.writeSampleData(encoder, trackIndex, bufferIndex, encodedData, bufferInfo); if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { // MediaMuxer gets the codec config info via the addTrack command if (VERBOSE) Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG"); encoder.releaseOutputBuffer(bufferIndex, false); return; } if (bufferInfo.size == 0) { if (VERBOSE) Log.d(TAG, "ignoring zero size buffer"); encoder.releaseOutputBuffer(bufferIndex, false); return; } if (!mStarted) { Log.e(TAG, "writeSampleData called before muxer started. Ignoring packet. Track index: " + trackIndex + " tracks added: " + mNumTracks); encoder.releaseOutputBuffer(bufferIndex, false); return; } bufferInfo.presentationTimeUs = getNextRelativePts(bufferInfo.presentationTimeUs, trackIndex); Log.d(TAG, "WRITING SAMPLE DATA TO TRACK: " + trackIndex); mMuxer.writeSampleData(trackIndex, encodedData, bufferInfo); encoder.releaseOutputBuffer(bufferIndex, false); if (allTracksFinished()) { Log.d(TAG, "ALL TRACKS FINISHED"); shutdown(); } } }