Truy xuất siêu dữ liệu

Trong khi phát

Bạn có thể truy xuất siêu dữ liệu của nội dung nghe nhìn trong khi phát theo nhiều cách. Cách đơn giản nhất là theo dõi sự kiện Player.Listener#onMediaMetadataChanged. Sự kiện này sẽ cung cấp một đối tượng MediaMetadata để sử dụng, có các trường như titlealbumArtist. Ngoài ra, việc gọi Player#getMediaMetadata sẽ trả về cùng một đối tượng.

Kotlin

override fun onMediaMetadataChanged(mediaMetadata: MediaMetadata) {
  mediaMetadata.title?.let(::handleTitle)
}

Java

@Override
public void onMediaMetadataChanged(MediaMetadata mediaMetadata) {
  if (mediaMetadata.title != null) {
    handleTitle(mediaMetadata.title);
  }
}

Nếu cần quyền truy cập vào các đối tượng Metadata.Entry cụ thể, thì ứng dụng của bạn phải theo dõi Player.Listener#onMetadata (đối với siêu dữ liệu động được phân phối trong quá trình phát). Ngoài ra, nếu cần xem siêu dữ liệu tĩnh, bạn có thể truy cập vào siêu dữ liệu này thông qua TrackSelections#getFormat. Player#getMediaMetadata được lấy từ cả hai nguồn này.

Không phát

Nếu không cần phát, bạn nên dùng MetadataRetriever để trích xuất siêu dữ liệu vì cách này giúp bạn không phải tạo và chuẩn bị trình phát.

Kotlin

try {
  MetadataRetriever.Builder(context, mediaItem).build().use { metadataRetriever ->
    val trackGroups = metadataRetriever.retrieveTrackGroups().await()
    val timeline = metadataRetriever.retrieveTimeline().await()
    val durationUs = metadataRetriever.retrieveDurationUs().await()
    handleMetadata(trackGroups, timeline, durationUs)
  }
} catch (e: IOException) {
  handleFailure(e)
}

Java

try (MetadataRetriever metadataRetriever =
    new MetadataRetriever.Builder(context, mediaItem).build()) {
  ListenableFuture<TrackGroupArray> trackGroupsFuture = metadataRetriever.retrieveTrackGroups();
  ListenableFuture<Timeline> timelineFuture = metadataRetriever.retrieveTimeline();
  ListenableFuture<Long> durationUsFuture = metadataRetriever.retrieveDurationUs();
  ListenableFuture<List<Object>> allFutures =
      Futures.allAsList(trackGroupsFuture, timelineFuture, durationUsFuture);
  Futures.addCallback(
      allFutures,
      new FutureCallback<List<Object>>() {
        @Override
        public void onSuccess(List<Object> result) {
          handleMetadata(
              Futures.getUnchecked(trackGroupsFuture),
              Futures.getUnchecked(timelineFuture),
              Futures.getUnchecked(durationUsFuture));
        }

        @Override
        public void onFailure(Throwable t) {
          handleFailure(t);
        }
      },
      executor);
}

Ảnh chuyển động

Bạn cũng có thể trích xuất siêu dữ liệu của ảnh chuyển động, bao gồm cả độ lệch và độ dài của phần hình ảnh và video trong tệp.

Đối với ảnh chuyển động, TrackGroupArray thu được bằng MetadataRetriever chứa TrackGroup có một Format duy nhất bao quanh một mục siêu dữ liệu MotionPhotoMetadata.

Kotlin

0.until(trackGroups.length)
  .asSequence()
  .mapNotNull { trackGroups[it].getFormat(0).metadata }
  .filter { metadata -> metadata.length() == 1 }
  .map { metadata -> metadata[0] }
  .filterIsInstance<MotionPhotoMetadata>()
  .forEach(::handleMotionPhotoMetadata)

Java

for (int i = 0; i < trackGroups.length; i++) {
  TrackGroup trackGroup = trackGroups.get(i);
  Metadata metadata = trackGroup.getFormat(0).metadata;
  if (metadata != null && metadata.length() == 1) {
    Metadata.Entry metadataEntry = metadata.get(0);
    if (metadataEntry instanceof MotionPhotoMetadata) {
      MotionPhotoMetadata motionPhotoMetadata = (MotionPhotoMetadata) metadataEntry;
      handleMotionPhotoMetadata(motionPhotoMetadata);
    }
  }
}