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 "); 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); } } } }