KVFCodec
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
package org.kne.codec.kvf;
|
||||
|
||||
import org.jcodec.api.FrameGrab;
|
||||
import org.jcodec.api.JCodecException;
|
||||
import org.jcodec.common.io.FileChannelWrapper;
|
||||
import org.jcodec.common.io.SeekableByteChannel;
|
||||
import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.containers.mp4.demuxer.MP4Demuxer;
|
||||
import org.jcodec.scale.AWTUtil;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* JCodec 最小化 Demo:读取 MP4 文件,解码每一帧为 BufferedImage
|
||||
*
|
||||
* 用法:java JCodecDemo /path/to/video.mp4
|
||||
*/
|
||||
public class H264ToKVF {
|
||||
|
||||
public static void main(String[] args) throws IOException, JCodecException {
|
||||
// 1. 注册 KIF 插件
|
||||
org.kne.codec.kif.KIFImageReaderSpi.register();
|
||||
org.kne.codec.kif.KIFImageWriterSpi.register();
|
||||
System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));
|
||||
System.setErr(new PrintStream(System.err, true, StandardCharsets.UTF_8));
|
||||
if (args.length < 1) {
|
||||
System.err.println("用法: java JCodecDemo <video.mp4>");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
File inputFile = new File(args[0]);
|
||||
if (!inputFile.exists()) {
|
||||
System.err.println("文件不存在: " + inputFile.getAbsolutePath());
|
||||
System.exit(1);
|
||||
}
|
||||
File outputFile=new File("output.kvf");
|
||||
|
||||
System.out.println("🎬 开始转码: " + inputFile.getName());
|
||||
|
||||
// 1. 打开 FileChannel,向上转型为 SeekableByteChannel
|
||||
try ( KVFOutputStream kvo=new KVFOutputStream(new FileOutputStream(outputFile))){
|
||||
try (FileInputStream fis = new FileInputStream(inputFile);
|
||||
FileChannel fileChannel = fis.getChannel()) {
|
||||
|
||||
// 关键:用 SeekableByteChannel 类型接收
|
||||
SeekableByteChannel channel =new FileChannelWrapper( fileChannel);
|
||||
// 2. 创建帧抓取器
|
||||
MP4Demuxer demux=MP4Demuxer.createMP4Demuxer(channel);
|
||||
// 3. 逐帧解码
|
||||
int frameCount = 0;
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
Picture picture;
|
||||
/* while ((picture = grab.getNativeFrame()) != null) {
|
||||
frameCount++;
|
||||
|
||||
System.out.printf(" 已解码 %d 帧...\n", frameCount);
|
||||
kvo.writeFrame(0, frameCount, picture, "kif");
|
||||
}*/
|
||||
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
System.out.printf("✅ 转码完成!共 %d 帧,耗时 %dms\n", frameCount, elapsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user