The Developer Preview for Android 11 is now available; test it out and share your feedback.

MediaParser

public final class MediaParser
extends Object

java.lang.Object
   ↳ android.media.MediaParser


Parses media container formats and extracts contained media samples and metadata.

This class provides access to a battery of low-level media container parsers. Each instance of this class is associated to a specific media parser implementation which is suitable for extraction from a specific media container format. The media parser implementation assignment depends on the factory method (see create(MediaParser.OutputConsumer, String...) and createByName(String, MediaParser.OutputConsumer)) used to create the instance.

Users must implement the following to use this class.

  • InputReader: Provides the media container's bytes to parse.
  • OutputConsumer: Provides a sink for all extracted data and metadata.

The following code snippet includes a usage example:

 MyOutputConsumer myOutputConsumer = new MyOutputConsumer();
 MyInputReader myInputReader = new MyInputReader("www.example.com");
 MediaParser mediaParser = MediaParser.create(myOutputConsumer);

 while (mediaParser.advance(myInputReader)) {}

 mediaParser.release();
 mediaParser = null;
 

The following code snippet provides a rudimentary OutputConsumer sample implementation which extracts and publishes all video samples:


 class VideoOutputConsumer implements MediaParser.OutputConsumer {

     private static final int MAXIMUM_SAMPLE_SIZE = ...;
     private byte[] sampleDataBuffer = new byte[MAXIMUM_SAMPLE_SIZE];
     private int videoTrackIndex = -1;
     private int bytesWrittenCount = 0;

     \@Override
     public void onSeekMap(int i, @NonNull MediaFormat mediaFormat) { \/* Do nothing. *\/ }

     \@Override
     public void onTrackData(int i, @NonNull TrackData trackData) {
       MediaFormat mediaFormat = trackData.mediaFormat;
       if (videoTrackIndex == -1 && mediaFormat
           .getString(MediaFormat.KEY_MIME, \/* defaultValue= *\/ "").startsWith("video/")) {
         videoTrackIndex = i;
       }
     }

     \@Override
     public void onSampleData(int trackIndex, @NonNull InputReader inputReader)
         throws IOException, InterruptedException {
       int numberOfBytesToRead = (int) inputReader.getLength();
       if (videoTrackIndex != trackIndex) {
         // Discard contents.
         inputReader.read(\/* bytes= *\/ null, \/* offset= *\/ 0, numberOfBytesToRead);
       }
       int bytesRead = inputReader.read(sampleDataBuffer, bytesWrittenCount, numberOfBytesToRead);
       bytesWrittenCount += bytesRead;
     }

     \@Override
     public void onSampleCompleted(
         int trackIndex,
         long timeUs,
         int flags,
         int size,
         int offset,
         \@Nullable CryptoInfo cryptoData) {
       if (videoTrackIndex != trackIndex) {
         return; // It's not the video track. Ignore.
       }
       byte[] sampleData = new byte[size];
       System.arraycopy(sampleDataBuffer, bytesWrittenCount - size - offset, sampleData, \/*
       destPos= *\/ 0, size);
       // Place trailing bytes at the start of the buffer.
       System.arraycopy(
           sampleDataBuffer,
           bytesWrittenCount - offset,
           sampleDataBuffer,
           \/* destPos= *\/ 0,
           \/* size= *\/ offset);
       publishSample(sampleData, timeUs, flags);
     }
   }

 

Summary

Nested classes

interface MediaParser.InputReader

Provides input data to MediaParser

interface MediaParser.OutputConsumer

Receives extracted media sample data and metadata from MediaParser

class MediaParser.SeekMap

Maps seek positions to SeekPoint in the stream. 

class MediaParser.SeekPoint

Defines a seek point in a media stream. 

interface MediaParser.SeekableInputReader

InputReader that allows setting the read position. 

class MediaParser.TrackData

Holds information associated with a track. 

class MediaParser.UnrecognizedInputFormatException

Thrown if all extractors implementations provided to MediaParser.create(MediaParser.OutputConsumer, String...) failed to sniff the input content. 

Public methods

boolean advance(MediaParser.SeekableInputReader seekableInputReader)

Makes progress in the extraction of the input media stream, unless the end of the input has been reached.

static MediaParser create(MediaParser.OutputConsumer outputConsumer, String... extractorNames)

Creates an instance whose backing extractor will be selected by sniffing the content during the first advance(MediaParser.SeekableInputReader) call.

static MediaParser createByName(String name, MediaParser.OutputConsumer outputConsumer)

Creates an instance backed by the extractor with the given name.

String getExtractorName()

Returns the name of the backing extractor implementation.

static List<String> getExtractorNames(MediaFormat mediaFormat)

Returns an immutable list with the names of the extractors that are suitable for container formats with the given MediaFormat.

void release()

Releases any acquired resources.

void seek(MediaParser.SeekPoint seekPoint)

Seeks within the media container being extracted.

Inherited methods

Public methods

advance

public boolean advance (MediaParser.SeekableInputReader seekableInputReader)

Makes progress in the extraction of the input media stream, unless the end of the input has been reached.

This method will block until some progress has been made.

If this instance was created using create(MediaParser.OutputConsumer, String...). the first call to this method will sniff the content with the extractors with the provided names.

Parameters
seekableInputReader MediaParser.SeekableInputReader: The SeekableInputReader from which to obtain the media container data. This value must never be null.

Returns
boolean Whether there is any data left to extract. Returns false if the end of input has been reached.

Throws
android.media.MediaParser.UnrecognizedInputFormatException
IOException
InterruptedException

create

public static MediaParser create (MediaParser.OutputConsumer outputConsumer, 
                String... extractorNames)

Creates an instance whose backing extractor will be selected by sniffing the content during the first advance(MediaParser.SeekableInputReader) call. Extractor implementations will sniff the content in order of appearance in extractorNames.

Parameters
outputConsumer MediaParser.OutputConsumer: The OutputConsumer to which extracted data is output. This value must never be null.

extractorNames String: The names of the extractors to sniff the content with. If empty, a default array of names is used. This value must never be null.

Returns
MediaParser A new instance. This value will never be null.

createByName

public static MediaParser createByName (String name, 
                MediaParser.OutputConsumer outputConsumer)

Creates an instance backed by the extractor with the given name. The returned instance will attempt extraction without sniffing the content.

Parameters
name String: The name of the extractor that will be associated with the created instance. This value must never be null.

outputConsumer MediaParser.OutputConsumer: The OutputConsumer to which track data and samples are pushed. This value must never be null.

Returns
MediaParser A new instance. This value will never be null.

Throws
IllegalArgumentException If an invalid name is provided.

getExtractorName

public String getExtractorName ()

Returns the name of the backing extractor implementation.

If this instance was creating using createByName(String, MediaParser.OutputConsumer), the provided name is returned. If this instance was created using create(MediaParser.OutputConsumer, String...), this method will return null until the first call to advance(MediaParser.SeekableInputReader), after which the name of the backing extractor implementation is returned.

Returns
String The name of the backing extractor implementation, or null if the backing extractor implementation has not yet been selected.

getExtractorNames

public static List<String> getExtractorNames (MediaFormat mediaFormat)

Returns an immutable list with the names of the extractors that are suitable for container formats with the given MediaFormat.

TODO: List which properties are taken into account. E.g. MimeType.

Parameters
mediaFormat MediaFormat: This value must never be null.

Returns
List<String> This value will never be null.

release

public void release ()

Releases any acquired resources.

After calling this method, this instance becomes unusable and no other methods should be invoked. DESIGN NOTE: Should be removed. There shouldn't be any resource for releasing.

seek

public void seek (MediaParser.SeekPoint seekPoint)

Seeks within the media container being extracted.

SeekPoint can be obtained from the SeekMap passed to OutputConsumer#onSeekMap(SeekMap).

Following a call to this method, the InputReader passed to the next invocation of advance(MediaParser.SeekableInputReader) must provide data starting from SeekPoint#position in the stream.

Parameters
seekPoint MediaParser.SeekPoint: The SeekPoint to seek to. This value must never be null.