Untitled
unknown
plain_text
5 months ago
7.4 kB
4
Indexable
package com.example.myapplication; import android.content.Context; import android.media.MediaExtractor; import android.media.MediaCodec; import android.media.MediaFormat; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveTask; public class VideoBatchProcessor { private static final String VIDEO_PATH = "android.resource://com.example.app/" + R.raw.sample_video; private String OUTPUT_DIR; private Context context; public VideoBatchProcessor(Context context) { this.context = context; this.OUTPUT_DIR = context.getCacheDir().getAbsolutePath(); } private static final long BATCH_DURATION_US = 3000000; public void abcd() throws IOException { MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource(this.context.getResources().openRawResourceFd(R.raw.sample_video)); int videoTrackIndex = -1; for (int i = 0; i < extractor.getTrackCount(); i++) { MediaFormat format = extractor.getTrackFormat(i); String mimeType = format.getString(MediaFormat.KEY_MIME); if (mimeType.startsWith("video/")) { videoTrackIndex = i; break; } } if (videoTrackIndex == -1) { throw new RuntimeException("Video track không tìm thấy."); } extractor.selectTrack(videoTrackIndex); MediaFormat videoFormat = extractor.getTrackFormat(videoTrackIndex); long videoDurationUs = videoFormat.getLong(MediaFormat.KEY_DURATION); extractor.release(); // 2. Chia video thành các batch dựa trên thời gian List<Batch> batches = new ArrayList<>(); for (long startTimeUs = 0; startTimeUs < videoDurationUs; startTimeUs += BATCH_DURATION_US) { long endTimeUs = Math.min(startTimeUs + BATCH_DURATION_US, videoDurationUs); batches.add(new Batch(VIDEO_PATH, OUTPUT_DIR, videoTrackIndex, startTimeUs, endTimeUs)); } // 3. Xử lý song song các batch bằng ForkJoinPool ForkJoinPool pool = new ForkJoinPool(); pool.invoke(new BatchTask(batches,context)); } // Class đại diện cho mỗi batch static class Batch { String videoPath; String outputDir; int videoTrackIndex; long startTimeUs; long endTimeUs; Batch(String videoPath, String outputDir, int videoTrackIndex, long startTimeUs, long endTimeUs) { this.videoPath = videoPath; this.outputDir = outputDir; this.videoTrackIndex = videoTrackIndex; this.startTimeUs = startTimeUs; this.endTimeUs = endTimeUs; } } // ForkJoinTask xử lý các batch static class BatchTask extends RecursiveTask<Void> { List<Batch> batches; Context context; BatchTask(List<Batch> batches,Context context) { this.batches = batches; this.context = context; } @Override protected Void compute() { if (batches.size() <= 1) { // Xử lý một batch if (!batches.isEmpty()) { processBatch(batches.get(0)); } return null; } // Chia các batch thành hai nhóm và xử lý song song int mid = batches.size() / 2; BatchTask leftTask = new BatchTask(batches.subList(0, mid),context); BatchTask rightTask = new BatchTask(batches.subList(mid, batches.size()),context); invokeAll(leftTask, rightTask); return null; } private void processBatch(Batch batch) { try { MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource(this.context.getResources().openRawResourceFd(R.raw.sample_video)); extractor.selectTrack(batch.videoTrackIndex); extractor.seekTo(batch.startTimeUs, MediaExtractor.SEEK_TO_CLOSEST_SYNC); MediaFormat format = extractor.getTrackFormat(batch.videoTrackIndex); String mimeType = format.getString(MediaFormat.KEY_MIME); MediaCodec codec = MediaCodec.createDecoderByType(mimeType); codec.configure(format, null, null, 0); codec.start(); ByteBuffer inputBuffer = ByteBuffer.allocateDirect(format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE)); MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); File batchDir = new File(batch.outputDir, "batch_" + (batch.startTimeUs / 1000000) + "s"); if (!batchDir.exists()) batchDir.mkdirs(); while (true) { int sampleSize = extractor.readSampleData(inputBuffer, 0); long sampleTime = extractor.getSampleTime(); if (sampleSize < 0 || sampleTime >= batch.endTimeUs) { break; } int inputIndex = codec.dequeueInputBuffer(10000); if (inputIndex >= 0) { ByteBuffer codecInputBuffer = codec.getInputBuffer(inputIndex); if (codecInputBuffer != null) { codecInputBuffer.put(inputBuffer); } codec.queueInputBuffer(inputIndex, 0, sampleSize, sampleTime, 0); extractor.advance(); } int outputIndex = codec.dequeueOutputBuffer(bufferInfo, 10000); while (outputIndex >= 0) { ByteBuffer outputBuffer = codec.getOutputBuffer(outputIndex); if (outputBuffer != null) { // Lưu frame ra file saveFrameToFile(outputBuffer, bufferInfo, batchDir); } codec.releaseOutputBuffer(outputIndex, false); outputIndex = codec.dequeueOutputBuffer(bufferInfo, 10000); } } extractor.release(); codec.stop(); codec.release(); } catch (Exception e) { e.printStackTrace(); } } private void saveFrameToFile(ByteBuffer buffer, MediaCodec.BufferInfo info, File outputDir) { try { // Tạo file mới File frameFile = new File(outputDir, "frame_" + (info.presentationTimeUs / 1000) + ".yuv"); FileOutputStream fos = new FileOutputStream(frameFile); // Ghi dữ liệu vào file byte[] data = new byte[info.size]; buffer.get(data); fos.write(data); fos.flush(); fos.close(); } catch (Exception e) { e.printStackTrace(); } } } }
Editor is loading...
Leave a Comment