Untitled

 avatar
unknown
plain_text
19 days ago
12 kB
3
Indexable
import android.graphics.Bitmap;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

public class VideoFrameExtractor {

        public static List<Bitmap> extractFrames(String videoPath, int frameCount) {
                    List<Bitmap> bitmaps = new ArrayList<>();
                            MediaExtractor extractor = new MediaExtractor();

                                    try {
                                                    extractor.setDataSource(videoPath);

                                                                // Chọn track video
                                                                            int trackIndex = selectVideoTrack(extractor);
                                                                                        if (trackIndex < 0) return bitmaps;

                                                                                                    extractor.selectTrack(trackIndex);
                                                                                                                MediaFormat format = extractor.getTrackFormat(trackIndex);

                                                                                                                            // Lấy tổng thời gian video (microseconds)
                                                                                                                                        long durationUs = format.getLong(MediaFormat.KEY_DURATION);
                                                                                                                                                    long frameIntervalUs = durationUs / frameCount; // Khoảng cách giữa 2 frame
                                                                                                                                                                MediaCodec decoder = createDecoder(format);

                                                                                                                                                                            for (int i = 0; i < frameCount; i++) {
                                                                                                                                                                                                long seekTimeUs = i * frameIntervalUs;
                                                                                                                                                                                                                extractor.seekTo(seekTimeUs, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
                                                                                                                                                                                                                                extractor.advance();
                                                                                                                                                                                                                                                Bitmap bitmap = decodeFrame(extractor, decoder);
                                                                                                                                                                                                                                                                if (bitmap != null) {
                                                                                                                                                                                                                                                                                        bitmaps.add(bitmap);
                                                                                                                                                                                                                                                                }
                                                                                                                                                                            }

                                                                                                                                                                                        decoder.stop();
                                                                                                                                                                                                    decoder.release();
                                    } catch (Exception e) {
                                                    e.printStackTrace();
                                    } finally {
                                                    extractor.release();
                                    }

                                            return bitmaps;
        }

            // 🔹 Chọn track video từ MediaExtractor
                private static int selectVideoTrack(MediaExtractor extractor) {
                            for (int i = 0; i < extractor.getTrackCount(); i++) {
                                            MediaFormat format = extractor.getTrackFormat(i);
                                                        String mime = format.getString(MediaFormat.KEY_MIME);
                                                                    if (mime != null && mime.startsWith("video/")) {
                                                                                        return i;
                                                                    }
                            }
                                    return -1;
                }

                    // 🔹 Tạo và cấu hình decoder
                        private static MediaCodec createDecoder(MediaFormat format) throws Exception {
                                    String mime = format.getString(MediaFormat.KEY_MIME);
                                            MediaCodec decoder = MediaCodec.createDecoderByType(mime);
                                                    decoder.configure(format, null, null, 0);
                                                            decoder.start();
                                                                    return decoder;
                        }

                            // 🔹 Giải mã frame và chuyển thành Bitmap
                                private static Bitmap decodeFrame(MediaExtractor extractor, MediaCodec decoder) {
                                            try {
                                                            int inputIndex = decoder.dequeueInputBuffer(10000);
                                                                        if (inputIndex >= 0) {
                                                                                            ByteBuffer inputBuffer = decoder.getInputBuffer(inputIndex);
                                                                                                            if (inputBuffer == null) return null;

                                                                                                                            int sampleSize = extractor.readSampleData(inputBuffer, 0);
                                                                                                                                            if (sampleSize > 0) {
                                                                                                                                                                    decoder.queueInputBuffer(inputIndex, 0, sampleSize, extractor.getSampleTime(), 0);
                                                                                                                                                                                        extractor.advance();
                                                                                                                                            }
                                                                        }

                                                                                    int outputIndex = decoder.dequeueOutputBuffer(new MediaCodec.BufferInfo(), 10000);
                                                                                                if (outputIndex >= 0) {
                                                                                                                    ByteBuffer outputBuffer = decoder.getOutputBuffer(outputIndex);
                                                                                                                                    if (outputBuffer == null) return null;

                                                                                                                                                    Bitmap bitmap = bitmapFromBuffer(outputBuffer); // Chuyển buffer thành Bitmap
                                                                                                                                                                    decoder.releaseOutputBuffer(outputIndex, false);
                                                                                                                                                                                    return bitmap;
                                                                                                }
                                            } catch (Exception e) {
                                                            e.printStackTrace();
                                            }
                                                    return null;
                                }

                                    // 🔹 Chuyển ByteBuffer thành Bitmap
                                        private static Bitmap bitmapFromBuffer(ByteBuffer buffer) {
                                                    int width = 1920; // Cần chỉnh theo kích thước video thật
                                                            int height = 1080;
                                                                    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
                                                                            bitmap.copyPixelsFromBuffer(buffer);
                                                                                    return bitmap;
                                        }
}
                                        }
                                            }
                                                                                                }
                                                                                                                                            }
                                                                        }
                                            }
                                }
                        }
                                                                    }
                            }
                }
                                    }
                                    }
                                                                                                                                                                                                                                                                }
                                                                                                                                                                            }
                                    }
        }
}
Editor is loading...
Leave a Comment