استخراج إطارات الفيديو

يوفّر الصف FrameExtractor طريقة فعّالة لاستخراج اللقطات التي تم فك ترميزها من MediaItem.

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

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

نظرة عامة

يتألف استخدام FrameExtractor من خطوتَين:

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

Kotlin

suspend fun extractFrames(context: Context, mediaItem: MediaItem) {
  try {
    // 1. Build the frame extractor.
    // `FrameExtractor` implements `AutoCloseable`, so wrap it in
    // a Kotlin `.use` block, which calls `close()` automatically.
    FrameExtractor.Builder(context, mediaItem).build().use { extractor ->
      // 2. Extract frames asynchronously.
      val frame = extractor.getFrame(5000L).await()
      val thumbnail = extractor.thumbnail.await()
      handleFrame(frame, thumbnail)
    }
  } catch (e: Exception) {
    handleFailure(e)
  }
}

Java

public void extractFrames(Context context, MediaItem mediaItem) {
  // 1. Build the frame extractor.
  // `FrameExtractor` implements `AutoCloseable`, so use try-with-resources
  // so that the resources are automatically released.
  try (FrameExtractor frameExtractor = new FrameExtractor.Builder(context, mediaItem).build()) {
    // 2. Extract frames asynchronously.
    ListenableFuture<FrameExtractor.Frame> frameFuture = frameExtractor.getFrame(5000L);
    ListenableFuture<FrameExtractor.Frame> thumbnailFuture = frameExtractor.getThumbnail();

    ListenableFuture<List<Object>> allFutures = Futures.allAsList(frameFuture, thumbnailFuture);
    Futures.addCallback(
        allFutures,
        new FutureCallback<List<Object>>() {
          @Override
          public void onSuccess(List<Object> result) {
            handleFrame(Futures.getUnchecked(frameFuture), Futures.getUnchecked(thumbnailFuture));
          }

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