Search in sources :

Example 11 with Entry

use of androidx.media3.common.Metadata.Entry in project media by androidx.

the class VorbisUtil method parseVorbisComments.

/**
 * Builds a {@link Metadata} instance from a list of Vorbis Comments.
 *
 * <p>METADATA_BLOCK_PICTURE comments will be transformed into {@link PictureFrame} entries. All
 * others will be transformed into {@link VorbisComment} entries.
 *
 * @param vorbisComments The raw input of comments, as a key-value pair KEY=VAL.
 * @return The fully parsed Metadata instance. Null if no vorbis comments could be parsed.
 */
@Nullable
public static Metadata parseVorbisComments(List<String> vorbisComments) {
    List<Entry> metadataEntries = new ArrayList<>();
    for (int i = 0; i < vorbisComments.size(); i++) {
        String vorbisComment = vorbisComments.get(i);
        String[] keyAndValue = Util.splitAtFirst(vorbisComment, "=");
        if (keyAndValue.length != 2) {
            Log.w(TAG, "Failed to parse Vorbis comment: " + vorbisComment);
            continue;
        }
        if (keyAndValue[0].equals("METADATA_BLOCK_PICTURE")) {
            // Decode it from Base64 and transform it into a PictureFrame.
            try {
                byte[] decoded = Base64.decode(keyAndValue[1], Base64.DEFAULT);
                metadataEntries.add(PictureFrame.fromPictureBlock(new ParsableByteArray(decoded)));
            } catch (RuntimeException e) {
                Log.w(TAG, "Failed to parse vorbis picture", e);
            }
        } else {
            VorbisComment entry = new VorbisComment(keyAndValue[0], keyAndValue[1]);
            metadataEntries.add(entry);
        }
    }
    return metadataEntries.isEmpty() ? null : new Metadata(metadataEntries);
}
Also used : ParsableByteArray(androidx.media3.common.util.ParsableByteArray) Entry(androidx.media3.common.Metadata.Entry) ArrayList(java.util.ArrayList) Metadata(androidx.media3.common.Metadata) VorbisComment(androidx.media3.extractor.metadata.vorbis.VorbisComment) Nullable(androidx.annotation.Nullable)

Example 12 with Entry

use of androidx.media3.common.Metadata.Entry in project media by androidx.

the class FragmentedMp4Extractor method parseSampleGroups.

private static void parseSampleGroups(ContainerAtom traf, @Nullable String schemeType, TrackFragment out) throws ParserException {
    // Find sbgp and sgpd boxes with grouping_type == seig.
    @Nullable ParsableByteArray sbgp = null;
    @Nullable ParsableByteArray sgpd = null;
    for (int i = 0; i < traf.leafChildren.size(); i++) {
        LeafAtom leafAtom = traf.leafChildren.get(i);
        ParsableByteArray leafAtomData = leafAtom.data;
        if (leafAtom.type == Atom.TYPE_sbgp) {
            leafAtomData.setPosition(Atom.FULL_HEADER_SIZE);
            if (leafAtomData.readInt() == SAMPLE_GROUP_TYPE_seig) {
                sbgp = leafAtomData;
            }
        } else if (leafAtom.type == Atom.TYPE_sgpd) {
            leafAtomData.setPosition(Atom.FULL_HEADER_SIZE);
            if (leafAtomData.readInt() == SAMPLE_GROUP_TYPE_seig) {
                sgpd = leafAtomData;
            }
        }
    }
    if (sbgp == null || sgpd == null) {
        return;
    }
    sbgp.setPosition(Atom.HEADER_SIZE);
    int sbgpVersion = Atom.parseFullAtomVersion(sbgp.readInt());
    // grouping_type == seig.
    sbgp.skipBytes(4);
    if (sbgpVersion == 1) {
        // grouping_type_parameter.
        sbgp.skipBytes(4);
    }
    if (sbgp.readInt() != 1) {
        // entry_count.
        throw ParserException.createForUnsupportedContainerFeature("Entry count in sbgp != 1 (unsupported).");
    }
    sgpd.setPosition(Atom.HEADER_SIZE);
    int sgpdVersion = Atom.parseFullAtomVersion(sgpd.readInt());
    // grouping_type == seig.
    sgpd.skipBytes(4);
    if (sgpdVersion == 1) {
        if (sgpd.readUnsignedInt() == 0) {
            throw ParserException.createForUnsupportedContainerFeature("Variable length description in sgpd found (unsupported)");
        }
    } else if (sgpdVersion >= 2) {
        // default_sample_description_index.
        sgpd.skipBytes(4);
    }
    if (sgpd.readUnsignedInt() != 1) {
        // entry_count.
        throw ParserException.createForUnsupportedContainerFeature("Entry count in sgpd != 1 (unsupported).");
    }
    // CencSampleEncryptionInformationGroupEntry
    // reserved = 0.
    sgpd.skipBytes(1);
    int patternByte = sgpd.readUnsignedByte();
    int cryptByteBlock = (patternByte & 0xF0) >> 4;
    int skipByteBlock = patternByte & 0x0F;
    boolean isProtected = sgpd.readUnsignedByte() == 1;
    if (!isProtected) {
        return;
    }
    int perSampleIvSize = sgpd.readUnsignedByte();
    byte[] keyId = new byte[16];
    sgpd.readBytes(keyId, 0, keyId.length);
    @Nullable byte[] constantIv = null;
    if (perSampleIvSize == 0) {
        int constantIvSize = sgpd.readUnsignedByte();
        constantIv = new byte[constantIvSize];
        sgpd.readBytes(constantIv, 0, constantIvSize);
    }
    out.definesEncryptionData = true;
    out.trackEncryptionBox = new TrackEncryptionBox(isProtected, schemeType, perSampleIvSize, keyId, cryptByteBlock, skipByteBlock, constantIv);
}
Also used : ParsableByteArray(androidx.media3.common.util.ParsableByteArray) Nullable(androidx.annotation.Nullable) LeafAtom(androidx.media3.extractor.mp4.Atom.LeafAtom)

Example 13 with Entry

use of androidx.media3.common.Metadata.Entry in project media by androidx.

the class AtomParsers method parseIlst.

@Nullable
private static Metadata parseIlst(ParsableByteArray ilst, int limit) {
    ilst.skipBytes(Atom.HEADER_SIZE);
    ArrayList<Metadata.Entry> entries = new ArrayList<>();
    while (ilst.getPosition() < limit) {
        @Nullable Metadata.Entry entry = MetadataUtil.parseIlstElement(ilst);
        if (entry != null) {
            entries.add(entry);
        }
    }
    return entries.isEmpty() ? null : new Metadata(entries);
}
Also used : SmtaMetadataEntry(androidx.media3.extractor.metadata.mp4.SmtaMetadataEntry) ArrayList(java.util.ArrayList) Metadata(androidx.media3.common.Metadata) Nullable(androidx.annotation.Nullable) Nullable(androidx.annotation.Nullable)

Example 14 with Entry

use of androidx.media3.common.Metadata.Entry in project media by androidx.

the class PictureFrameTest method populateMediaMetadata_setsBuilderValues.

@Test
public void populateMediaMetadata_setsBuilderValues() {
    byte[] pictureData = new byte[] { -12, 52, 33, 85, 34, 22, 1, -55 };
    Metadata.Entry entry = new PictureFrame(/* pictureType= */
    MediaMetadata.PICTURE_TYPE_FRONT_COVER, /* mimeType= */
    MimeTypes.IMAGE_JPEG, /* description= */
    "an image", /* width= */
    4, /* height= */
    2, /* depth= */
    1, /* colors= */
    1, pictureData);
    MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon();
    entry.populateMediaMetadata(builder);
    MediaMetadata mediaMetadata = builder.build();
    assertThat(mediaMetadata.artworkData).isEqualTo(pictureData);
    assertThat(mediaMetadata.artworkDataType).isEqualTo(MediaMetadata.PICTURE_TYPE_FRONT_COVER);
}
Also used : MediaMetadata(androidx.media3.common.MediaMetadata) Metadata(androidx.media3.common.Metadata) MediaMetadata(androidx.media3.common.MediaMetadata) Test(org.junit.Test)

Example 15 with Entry

use of androidx.media3.common.Metadata.Entry in project media by androidx.

the class ApicFrameTest method populateMediaMetadata_setsBuilderValues.

@Test
public void populateMediaMetadata_setsBuilderValues() {
    byte[] pictureData = new byte[] { -12, 52, 33, 85, 34, 22, 1, -55 };
    @MediaMetadata.PictureType int pictureType = MediaMetadata.PICTURE_TYPE_LEAFLET_PAGE;
    Metadata.Entry entry = new ApicFrame(/* mimeType= */
    MimeTypes.BASE_TYPE_IMAGE, /* description= */
    "an image", pictureType, pictureData);
    MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon();
    entry.populateMediaMetadata(builder);
    MediaMetadata mediaMetadata = builder.build();
    assertThat(mediaMetadata.artworkData).isEqualTo(pictureData);
    assertThat(mediaMetadata.artworkDataType).isEqualTo(pictureType);
}
Also used : MediaMetadata(androidx.media3.common.MediaMetadata) Metadata(androidx.media3.common.Metadata) MediaMetadata(androidx.media3.common.MediaMetadata) Test(org.junit.Test)

Aggregations

Metadata (androidx.media3.common.Metadata)11 Nullable (androidx.annotation.Nullable)10 ArrayList (java.util.ArrayList)7 MediaMetadata (androidx.media3.common.MediaMetadata)4 Test (org.junit.Test)4 ParsableByteArray (androidx.media3.common.util.ParsableByteArray)3 SmtaMetadataEntry (androidx.media3.extractor.metadata.mp4.SmtaMetadataEntry)3 Format (androidx.media3.common.Format)2 TrackGroup (androidx.media3.common.TrackGroup)2 SlowMotionData (androidx.media3.extractor.metadata.mp4.SlowMotionData)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 Bitmap (android.graphics.Bitmap)1 Uri (android.net.Uri)1 SpannableStringBuilder (android.text.SpannableStringBuilder)1 Pair (android.util.Pair)1 AdPlaybackState (androidx.media3.common.AdPlaybackState)1 SchemeData (androidx.media3.common.DrmInitData.SchemeData)1 Entry (androidx.media3.common.Metadata.Entry)1 TrackGroupArray (androidx.media3.common.TrackGroupArray)1