جارٍ استرداد البيانات الوصفية

أثناء التشغيل

يمكن استرداد بيانات وصفية للوسائط أثناء التشغيل بعدة طرق. أسهل طريقة هي الاستماع إلى حدث Player.Listener#onMediaMetadataChanged، ما سيوفّر عنصر MediaMetadata للاستخدام، والذي يتضمّن حقولاً مثل title وalbumArtist. بدلاً من ذلك، يؤدي استدعاء Player#getMediaMetadata إلى عرض الكائن نفسه.

Kotlin

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

Java

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

إذا كان تطبيقك يحتاج إلى الوصول إلى عناصر Metadata.Entry معيّنة، يجب أن يستمع إلى Player.Listener#onMetadata (للحصول على البيانات الوصفية الديناميكية التي يتم عرضها أثناء التشغيل). بدلاً من ذلك، إذا كانت هناك حاجة إلى الاطّلاع على بيانات وصفية ثابتة، يمكن الوصول إليها من خلال TrackSelections#getFormat. يتم ملء Player#getMediaMetadata من كلا المصدرَين.

بدون تشغيل

إذا لم تكن هناك حاجة إلى التشغيل، يكون من الأفضل استخدام MetadataRetriever لاستخراج البيانات الوصفية لأنّ ذلك يجنّبك الحاجة إلى إنشاء مشغّل وإعداده.

Kotlin

suspend fun retrieveMetadata(context: Context, mediaItem: MediaItem) {
  try {
    // 1. Build the retriever.
    // `MetadataRetriever` implements `AutoCloseable`, so wrap it in
    // a Kotlin `.use` block, which calls `close()` automatically.
    MetadataRetriever.Builder(context, mediaItem).build().use { retriever ->
      // 2. Retrieve metadata asynchronously.
      val trackGroups = retriever.retrieveTrackGroups().await()
      val timeline = retriever.retrieveTimeline().await()
      val durationUs = retriever.retrieveDurationUs().await()
      handleMetadata(trackGroups, timeline, durationUs)
    }
  } catch (e: Exception) {
    handleFailure(e)
  }
}

Java

public void retrieveMetadata(Context context, MediaItem mediaItem) {
  // 1. Build the retriever.
  // `MetadataRetriever` implements `AutoCloseable`, so use try-with-resources
  // so that the resources are automatically released.
  try (MetadataRetriever retriever = new MetadataRetriever.Builder(context, mediaItem).build()) {
    // 2. Retrieve metadata asynchronously.
    ListenableFuture<TrackGroupArray> trackGroupsFuture = retriever.retrieveTrackGroups();
    ListenableFuture<Timeline> timelineFuture = retriever.retrieveTimeline();
    ListenableFuture<Long> durationUsFuture = retriever.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);
          }
        },
        directExecutor());
  }
}

الصور الحيّة

من الممكن أيضًا استخراج البيانات الوصفية الخاصة بالصور المتحركة، بما في ذلك الإزاحات وأطوال أجزاء الصورة والفيديو في الملف.

بالنسبة إلى الصور الحيّة، يحتوي TrackGroupArray الذي تم الحصول عليه باستخدام MetadataRetriever على TrackGroup مع Format واحد يضم إدخال بيانات وصفية 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);
    }
  }
}