بازیابی متادیتا

در حین پخش

فراداده‌های رسانه را می‌توان در حین پخش به روش‌های مختلفی بازیابی کرد. ساده‌ترین راه، گوش دادن به رویداد Player.Listener#onMediaMetadataChanged ؛ این رویداد یک شیء MediaMetadata برای استفاده فراهم می‌کند که دارای فیلدهایی مانند title و albumArtist است. به عنوان یک روش جایگزین، فراخوانی Player#getMediaMetadata همان شیء را برمی‌گرداند.

کاتلین

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

جاوا

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

اگر برنامه شما نیاز به دسترسی به اشیاء خاص Metadata.Entry دارد، باید به Player.Listener#onMetadata (برای متادیتای پویا که هنگام پخش ارائه می‌شود) گوش دهد. از طرف دیگر، اگر نیاز به بررسی متادیتای استاتیک باشد، می‌توان از طریق TrackSelections#getFormat به آن دسترسی پیدا کرد. Player#getMediaMetadata از هر دوی این منابع پر می‌شود.

بدون پخش

اگر نیازی به پخش نباشد، استفاده از MetadataRetriever برای استخراج فراداده کارآمدتر است زیرا از ایجاد و آماده‌سازی پخش‌کننده جلوگیری می‌کند.

کاتلین

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)
}

جاوا

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);
}

عکس‌های متحرک

همچنین می‌توان فراداده‌های عکس متحرک، از جمله فاصله‌ها و طول بخش‌های تصویر و ویدیوی فایل را استخراج کرد.

برای عکس‌های متحرک، TrackGroupArray که با MetadataRetriever به دست می‌آید، شامل یک TrackGroup با یک Format واحد است که ورودی فراداده MotionPhotoMetadata را در بر می‌گیرد.

کاتلین

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

جاوا

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);
    }
  }
}