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

يسترد MetadataRetriever المعلومات (مثل المدة ودقة الفيديو وبرامج الترميز والمقاطع الصوتية المتاحة ومعدلات أخذ العينات) من MediaItem بدون تشغيل.

تشمل حالات الاستخدام الشائعة ما يلي:

  • استرداد البيانات الوصفية للصور المتحركة: بما في ذلك الإزاحات وأطوال أجزاء الصورة والفيديو في الملف
  • إنشاء مكتبة وسائط: ملء MediaLibraryService بتفاصيل غنية MediaItem (مثل المدة والعنوان) لتقديم كتالوج وسائط كامل إلى العملاء، مثل Android Auto.
  • جلب تفاصيل واجهة المستخدم المسبق: جلب معلومات مثل دقة الفيديو أو مدته لتجهيز واجهة المستخدم قبل بدء التشغيل
  • التحقّق من صحة ملفات الوسائط: التحقّق مما إذا كان الملف يتضمّن مسارات الصوت أو الفيديو المطلوبة أو بيانات وصفية معيّنة قبل معالجته

نظرة عامة

يتضمّن استخدام MetadataRetriever خطوتَين:

  1. إنشاء أداة الاسترجاع: أنشئ مثيلاً باستخدام MetadataRetriever.Builder. مرِّر Context وMediaItem اللذين تريد فحصهما إلى أداة الإنشاء. في حالات الاستخدام المتقدّم، مثل الشبكات المخصّصة أو التخزين المؤقت، يمكنك أيضًا توفير MediaSource.Factory مخصّص.
  2. استرداد البيانات الوصفية: استدعِ طرقًا مثل retrieveDurationUs() أو retrieveTimeline() أو retrieveTrackGroups() لجلب المعلومات المطلوبة. هذه الطرق غير متزامنة، وتُرجع ListenableFuture، ما يضمن عدم حظر سلسلة التعليمات الرئيسية بسبب عمليات الشبكة أو الإدخال/الإخراج.

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) {
        throw RuntimeException(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<>() {
            @Override
            public void onSuccess(List<Object> result) {
                handleMetadata(
                        Futures.getUnchecked(trackGroupsFuture),
                        Futures.getUnchecked(timelineFuture),
                        Futures.getUnchecked(durationUsFuture)
                );
            }

            @Override
            public void onFailure(@NonNull Throwable t) {
                handleFailure(t);
            }
        }, MoreExecutors.directExecutor());
    }
}