Untitled
unknown
plain_text
a year ago
7.4 kB
5
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