use of androidx.media3.extractor.metadata.mp4.MotionPhotoMetadata in project ExoPlayer by google.
the class Mp4Extractor method processEndOfStreamReadingAtomHeader.
/**
* Processes the end of stream in case there is not atom left to read.
*/
private void processEndOfStreamReadingAtomHeader() {
if (fileType == FILE_TYPE_HEIC && (flags & FLAG_READ_MOTION_PHOTO_METADATA) != 0) {
// Add image track and prepare media.
ExtractorOutput extractorOutput = checkNotNull(this.extractorOutput);
TrackOutput trackOutput = extractorOutput.track(/* id= */
0, C.TRACK_TYPE_IMAGE);
@Nullable Metadata metadata = motionPhotoMetadata == null ? null : new Metadata(motionPhotoMetadata);
trackOutput.format(new Format.Builder().setMetadata(metadata).build());
extractorOutput.endTracks();
extractorOutput.seekMap(new SeekMap.Unseekable(/* durationUs= */
C.TIME_UNSET));
}
}
use of androidx.media3.extractor.metadata.mp4.MotionPhotoMetadata in project media by androidx.
the class JpegExtractor method readSegment.
private void readSegment(ExtractorInput input) throws IOException {
if (marker == MARKER_APP1) {
ParsableByteArray payload = new ParsableByteArray(segmentLength);
input.readFully(payload.getData(), /* offset= */
0, /* length= */
segmentLength);
if (motionPhotoMetadata == null && HEADER_XMP_APP1.equals(payload.readNullTerminatedString())) {
@Nullable String xmpString = payload.readNullTerminatedString();
if (xmpString != null) {
motionPhotoMetadata = getMotionPhotoMetadata(xmpString, input.getLength());
if (motionPhotoMetadata != null) {
mp4StartPosition = motionPhotoMetadata.videoStartPosition;
}
}
}
} else {
input.skipFully(segmentLength);
}
state = STATE_READING_MARKER;
}
use of androidx.media3.extractor.metadata.mp4.MotionPhotoMetadata in project media by androidx.
the class Mp4Extractor method processEndOfStreamReadingAtomHeader.
/**
* Processes the end of stream in case there is not atom left to read.
*/
private void processEndOfStreamReadingAtomHeader() {
if (fileType == FILE_TYPE_HEIC && (flags & FLAG_READ_MOTION_PHOTO_METADATA) != 0) {
// Add image track and prepare media.
ExtractorOutput extractorOutput = checkNotNull(this.extractorOutput);
TrackOutput trackOutput = extractorOutput.track(/* id= */
0, C.TRACK_TYPE_IMAGE);
@Nullable Metadata metadata = motionPhotoMetadata == null ? null : new Metadata(motionPhotoMetadata);
trackOutput.format(new Format.Builder().setMetadata(metadata).build());
extractorOutput.endTracks();
extractorOutput.seekMap(new SeekMap.Unseekable(/* durationUs= */
C.TIME_UNSET));
}
}
use of androidx.media3.extractor.metadata.mp4.MotionPhotoMetadata in project media by androidx.
the class MotionPhotoDescriptionTest method getMotionPhotoMetadata_withPrimaryAndSecondaryMediaItems.
@Test
public void getMotionPhotoMetadata_withPrimaryAndSecondaryMediaItems() {
MotionPhotoDescription motionPhotoDescription = new MotionPhotoDescription(TEST_PRESENTATION_TIMESTAMP_US, ImmutableList.of(new MotionPhotoDescription.ContainerItem(MimeTypes.IMAGE_JPEG, "Primary", /* length= */
0, TEST_MOTION_PHOTO_PHOTO_PADDING_BYTES), new MotionPhotoDescription.ContainerItem(MimeTypes.VIDEO_MP4, "MotionPhoto", TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES, /* padding= */
0)));
@Nullable MotionPhotoMetadata metadata = motionPhotoDescription.getMotionPhotoMetadata(TEST_MOTION_PHOTO_LENGTH_BYTES);
assertThat(metadata.photoStartPosition).isEqualTo(0);
assertThat(metadata.photoSize).isEqualTo(TEST_MOTION_PHOTO_LENGTH_BYTES - TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES - TEST_MOTION_PHOTO_PHOTO_PADDING_BYTES);
assertThat(metadata.photoPresentationTimestampUs).isEqualTo(TEST_PRESENTATION_TIMESTAMP_US);
assertThat(metadata.videoStartPosition).isEqualTo(TEST_MOTION_PHOTO_LENGTH_BYTES - TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES);
assertThat(metadata.videoSize).isEqualTo(TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES);
}
use of androidx.media3.extractor.metadata.mp4.MotionPhotoMetadata in project media by androidx.
the class MotionPhotoDescriptionTest method getMotionPhotoMetadata_withPrimaryAndMultipleSecondaryMediaItems_returnsSecondMediaItemAsVideo.
@Test
public void getMotionPhotoMetadata_withPrimaryAndMultipleSecondaryMediaItems_returnsSecondMediaItemAsVideo() {
MotionPhotoDescription motionPhotoDescription = new MotionPhotoDescription(TEST_PRESENTATION_TIMESTAMP_US, ImmutableList.of(new MotionPhotoDescription.ContainerItem(MimeTypes.IMAGE_JPEG, "Primary", /* length= */
0, TEST_MOTION_PHOTO_PHOTO_PADDING_BYTES), new MotionPhotoDescription.ContainerItem(MimeTypes.VIDEO_MP4, "MotionPhoto", TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES, /* padding= */
0), new MotionPhotoDescription.ContainerItem(MimeTypes.VIDEO_MP4, "MotionPhoto", TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES, /* padding= */
0)));
@Nullable MotionPhotoMetadata metadata = motionPhotoDescription.getMotionPhotoMetadata(TEST_MOTION_PHOTO_LENGTH_BYTES);
assertThat(metadata.photoStartPosition).isEqualTo(0);
assertThat(metadata.photoSize).isEqualTo(TEST_MOTION_PHOTO_LENGTH_BYTES - TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES * 2 - TEST_MOTION_PHOTO_PHOTO_PADDING_BYTES);
assertThat(metadata.photoPresentationTimestampUs).isEqualTo(TEST_PRESENTATION_TIMESTAMP_US);
assertThat(metadata.videoStartPosition).isEqualTo(TEST_MOTION_PHOTO_LENGTH_BYTES - TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES * 2);
assertThat(metadata.videoSize).isEqualTo(TEST_MOTION_PHOTO_VIDEO_LENGTH_BYTES);
}
Aggregations