diff --git a/media/java/android/media/MediaMuxer.java b/media/java/android/media/MediaMuxer.java index 80832f8a29778..aacce917d910b 100644 --- a/media/java/android/media/MediaMuxer.java +++ b/media/java/android/media/MediaMuxer.java @@ -32,9 +32,8 @@ import java.nio.ByteBuffer; import java.util.Map; /** - * MediaMuxer facilitates muxing elementary streams. Currently supports mp4 or - * webm file as the output and at most one audio and/or one video elementary - * stream. MediaMuxer does not support muxing B-frames. + * MediaMuxer facilitates muxing elementary streams. Currently MediaMuxer supports MP4, Webm + * and 3GP file as the output. It also supports muxing B-frames in MP4 since Android Nougat. *
* It is generally used like this: * @@ -65,6 +64,182 @@ import java.util.Map; * muxer.stop(); * muxer.release(); * + * + +
+ Metadata is usefule in carrying extra information that correlated with video or audio to + facilate offline processing, e.g. gyro signals from the sensor. Meatadata track is only + supported in MP4 format. When adding a metadata track, track's mime format must start with + prefix "application/", e.g. "applicaton/gyro". Metadata's format/layout will be defined by + the application. The generated MP4 file uses TextMetaDataSampleEntry defined in section 12.3.3.2 + of the ISOBMFF to signal the metadata's mime format. When using {@link android.media.MediaExtractor} + to extract the file with metadata track, the mime format of the metadata will be extracted into + {@link android.media.MediaFormat}. + +
+ MediaMuxer muxer = new MediaMuxer("temp.mp4", OutputFormat.MUXER_OUTPUT_MPEG_4);
+ // More often, the MediaFormat will be retrieved from MediaCodec.getOutputFormat()
+ // or MediaExtractor.getTrackFormat().
+ MediaFormat audioFormat = new MediaFormat(...);
+ MediaFormat videoFormat = new MediaFormat(...);
+
+ // Setup Metadata Track
+ MediaFormat metadataFormat = new MediaFormat(...);
+ metadataFormat.setString(KEY_MIME, "application/gyro");
+
+ int audioTrackIndex = muxer.addTrack(audioFormat);
+ int videoTrackIndex = muxer.addTrack(videoFormat);
+ int metadataTrackIndex = muxer.addTrack(metadataFormat);
+ ByteBuffer inputBuffer = ByteBuffer.allocate(bufferSize);
+ boolean finished = false;
+ BufferInfo bufferInfo = new BufferInfo();
+
+ muxer.start();
+ while(!finished) {
+ // getInputBuffer() will fill the inputBuffer with one frame of encoded
+ // sample from either MediaCodec or MediaExtractor, set isAudioSample to
+ // true when the sample is audio data, set up all the fields of bufferInfo,
+ // and return true if there are no more samples.
+ finished = getInputBuffer(inputBuffer, sampleType, bufferInfo);
+ if (!finished) {
+ int currentTrackIndex = getTrackIndex(sampleType);
+ muxer.writeSampleData(currentTrackIndex, inputBuffer, bufferInfo);
+ }
+ };
+ muxer.stop();
+ muxer.release();
+ }
+
+ + The following table summarizes the feature support in different API version and containers. + For API version numbers, see {@link android.os.Build.VERSION_CODES}. + + + +
| Symbol | +Meaning |
|---|---|
| ● | Supported |
| ○ | Not supported |
| ▧ | Supported in MP4/WebM/3GP |
| ⁕ | Only Supported in MP4 |
| Feature | +SDK Version | +|||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 18 | +19 | +20 | +21 | +22 | +23 | +24 | +25 | +26+ | +||||||||||||||||
| MP4 container | +● | +● | +● | +● | +● | +● | +● | +● | +● | +WebM container | +○ | +○ | +○ | +● | +● | +● | +● | +● | +● | + +3GP container | +○ | +○ | +○ | +○ | +○ | +○ | +○ | +○ | +● | + +Muxing B-Frames(bi-directional predicted frames) | +○ | +○ | +○ | +○ | +○ | +○ | +⁕ | +⁕ | +⁕ | + + +Muxing Single Video/Audio Track | +▧ | +▧ | +▧ | +▧ | +▧ | +▧ | +▧ | +▧ | +▧ | + + +Muxing Multiple Video/Audio Tracks | +○ | +○ | +○ | +○ | +○ | +○ | +○ | +○ | +⁕ | + + +Muxing Metadata Tracks | +○ | +○ | +○ | +○ | +○ | +○ | +○ | +○ | +⁕ | + + +