Trích xuất khung hình video

Lớp FrameExtractor cung cấp một cách hiệu quả để trích xuất các khung hình đã giải mã từ MediaItem.

Các trường hợp sử dụng phổ biến bao gồm:

  • Tạo hình thu nhỏ: Tạo hình thu nhỏ chất lượng cao cho một thư viện video hoặc thanh tìm kiếm.
  • Bản xem trước khi chỉnh sửa video: Hiển thị bản xem trước chính xác từng khung hình trong dòng thời gian của trình chỉnh sửa, cho phép người dùng tìm kiếm nội dung và hình dung chính xác các khung hình.
  • Áp dụng các phép biến đổi như điều chỉnh tỷ lệ, cắt hoặc xoay trực tiếp trong quá trình trích xuất, tránh một bước xử lý hậu kỳ riêng biệt.
  • Phân tích nội dung: Trích xuất các khung hình theo khoảng thời gian để gửi đến quy trình phân tích cho các tác vụ như phát hiện cảnh, nhận dạng đối tượng hoặc kiểm soát chất lượng.

Tổng quan

Quy trình sử dụng FrameExtractor gồm 2 bước:

  1. Tạo trình trích xuất: Tạo một thực thể bằng cách sử dụng FrameExtractor.Builder. Truyền một ContextMediaItem mà bạn muốn kiểm tra cho trình tạo. Bạn cũng có thể xâu chuỗi các phương thức định cấu hình trên Builder cho các chế độ cài đặt nâng cao.
  2. Trích xuất khung hình: Gọi getFrame() để trích xuất khung hình tại một dấu thời gian cụ thể hoặc getThumbnail() để yêu cầu một hình thu nhỏ đại diện. Các phương thức này không đồng bộ và trả về một ListenableFuture. Do đó, công việc giải mã phức tạp không chặn luồng chính.

Kotlin

suspend fun extractFrame(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) {
        Log.e(TAG, "Exception: $e")
    }
}

Java

public void extractFrame(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<>() {
            @Override
            public void onSuccess(List<Object> result) {
                handleFrame(Futures.getUnchecked(frameFuture), Futures.getUnchecked(thumbnailFuture));
            }

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