如何使用 JCodec 将一系列图像转换为视频?

2023-12-05

我正在尝试使用 JCodec 将一系列图像转换为 Java SE 桌面应用程序内的视频。我尝试过的几种方法都导致 Windows Media Player 无法播放视频。

我不清楚这是否是编解码器问题(值得怀疑)或者我是否没有正确创建视频。当我尝试在 Windows Media Player 中播放视频时,我得到:

Windows Media Player 无法播放该文件。玩家可能不会 支持文件类型或可能不支持用于的编解码器 压缩文件。

这是我最近使用的拼凑样本。我真的不了解视频格式的内部原理,所以我什至不完全确定某些代码在做什么。

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;

import javax.imageio.ImageIO;

import org.jcodec.codecs.h264.H264Encoder;
import org.jcodec.codecs.h264.H264Utils;
import org.jcodec.common.NIOUtils;
import org.jcodec.common.SeekableByteChannel;
import org.jcodec.common.model.ColorSpace;
import org.jcodec.common.model.Picture;
import org.jcodec.containers.mp4.Brand;
import org.jcodec.containers.mp4.MP4Packet;
import org.jcodec.containers.mp4.TrackType;
import org.jcodec.containers.mp4.muxer.FramesMP4MuxerTrack;
import org.jcodec.containers.mp4.muxer.MP4Muxer;
import org.jcodec.scale.AWTUtil;
import org.jcodec.scale.RgbToYuv420;

public class CreateVideo {
    private SeekableByteChannel ch;
    private Picture toEncode;
    private RgbToYuv420 transform;
    private H264Encoder encoder;
    private ArrayList<ByteBuffer> spsList;
    private ArrayList<ByteBuffer> ppsList;
    private FramesMP4MuxerTrack outTrack;
    private ByteBuffer _out;
    private int frameNo;
    private MP4Muxer muxer;

    public CreateVideo(File out) throws IOException {
        ch = NIOUtils.writableFileChannel(out);

        // Transform to convert between RGB and YUV
        transform = new RgbToYuv420(0, 0);

        // Muxer that will store the encoded frames
        muxer = new MP4Muxer(ch, Brand.MP4);

        // Add video track to muxer
        outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, 25);

        // Allocate a buffer big enough to hold output frames
        _out = ByteBuffer.allocate(1920 * 1080 * 6);

        // Create an instance of encoder
        encoder = new H264Encoder();

        // Encoder extra data ( SPS, PPS ) to be stored in a special place of
        // MP4
        spsList = new ArrayList<ByteBuffer>();
        ppsList = new ArrayList<ByteBuffer>();

    }

    public void encodeImage(BufferedImage bi) throws IOException {
        if (toEncode == null) {
            toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420);
        }

        // Perform conversion
        for (int i = 0; i < 3; i++) {
            Arrays.fill(toEncode.getData()[i], 0);
        }
        transform.transform(AWTUtil.fromBufferedImage(bi), toEncode);

        // Encode image into H.264 frame, the result is stored in '_out' buffer
        _out.clear();
        ByteBuffer result = encoder.encodeFrame(_out, toEncode);

        // Based on the frame above form correct MP4 packet
        spsList.clear();
        ppsList.clear();
        H264Utils.encodeMOVPacket(result, spsList, ppsList);

        // Add packet to video track
        outTrack.addFrame(new MP4Packet(result, frameNo, 25, 1, frameNo, true, null, frameNo, 0));

        frameNo++;
    }

    public void finish() throws IOException {
        // Push saved SPS/PPS to a special storage in MP4
        outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList));

        // Write MP4 header and finalize recording
        muxer.writeHeader();
        NIOUtils.closeQuietly(ch);
    }

    public static void main(String[] args) throws IOException {
        CreateVideo encoder = new CreateVideo(new File("C:\\video\\video.mp4"));
        for (int i = 10; i < 34; i++) {
            String filename = String.format("C:\\video\\%02d.png", i);
            BufferedImage bi = ImageIO.read(new File(filename));
            encoder.encodeImage(bi);
        }
        encoder.finish();
    }
}

如果有一些更简单的编解码器/容器,我不会依赖 H264 或 MP4。唯一的要求是它应该在没有安装任何其他软件的基准 Windows 7 机器上运行。


我对 jcodec 的 RgbToYuv420() 转换有很多问题。
我使用自己的函数将 RGB BufferedImage 转换为 Yuv420。
我遇到的一个问题是 RgbToYuv420 对计算出的 upix 和 vpix 进行平均 值,这导致我的 mp4 中的颜色变得不稳定。

// make a YUV420J out of BufferedImage pixels
private Picture makeFrame(BufferedImage bi, ColorSpace cs)
{   
    DataBuffer imgdata = bi.getRaster().getDataBuffer();
    int[] ypix = new int[imgdata.getSize()];
    int[] upix = new int[ imgdata.getSize() >> 2 ];
    int[] vpix = new int[ imgdata.getSize() >> 2 ];
    int ipx = 0, uvoff = 0;

    for (int h = 0; h < bi.getHeight(); h++) {
        for (int w = 0; w < bi.getWidth();  w++) {
            int elem = imgdata.getElem(ipx);
            int r = 0x0ff & (elem >>> 16);
            int g = 0x0ff & (elem >>> 8);
            int b = 0x0ff & elem;
            ypix[ipx] = ((66 * r + 129 * g + 25 * b) >> 8) + 16;
            if ((0 != w % 2) && (0 != h % 2)) {
                upix[uvoff] = (( -38 * r + -74 * g + 112 * b) >> 8) + 128;
                vpix[uvoff] = (( 112 * r + -94 * g + -18 * b) >> 8) + 128;
                uvoff++;
            }
            ipx++;
        }
    }
    int[][] pix = { ypix, upix, vpix, null };
    // old API
    // return new Picture(bi.getWidth(), bi.getHeight(), pix, ColorSpace.YUV420J);
    return Picture.createPicture(bi.getWidth(), bi.getHeight(), pix, ColorSpace.YUV420J);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 JCodec 将一系列图像转换为视频? 的相关文章

  • 在 JTable 中移动行

    我使用 MVC 模式 并且有一个如下所示的 JTable List
  • 我需要在 Spring 中检查每个控制器中的有效会话吗? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 假设在 Spring Mvc 的 Web 应用程序中 我们是否需要检查每个控制器或 jsps 中的有效会话 我该如何解决 MVC 中的
  • 如何查找 Android 设备中的所有文件并将它们放入列表中?

    我正在寻求帮助来列出 Android 外部存储设备中的所有文件 我想查找所有文件夹 包括主文件夹的子文件夹 有办法吗 我已经做了一个基本的工作 但我仍然没有得到想要的结果 这不起作用 这是我的代码 File files array file
  • 在浏览器中点击应用程序时播放框架挂起

    我正在 Play 中运行一个应用程序activator run 也许 5 次中有 3 次 它会挂起 当我去http localhost 9000 它就永远坐在那里旋转 我看到很多promise timed out错误也 我应该去哪里寻找这个
  • Convert.FromBase64String 方法的 Java 等效项

    Java 中是否有相当于Convert FromBase64String http msdn microsoft com en us library system convert frombase64string aspx which 将指
  • 一种使用 Java Robot API 和 Selenium WebDriver by Java 进行文件上传的解决方案

    我看到很多人在使用 Selenium WebDriver 的测试环境中上传文件时遇到问题 我使用 selenium WebDriver 和 java 也遇到了同样的问题 我终于找到了解决方案 所以我将其发布在这里希望对其他人有所帮助 当我需
  • Java 页面爬行和解析之 Crawler4j 与 Jsoup

    我想获取页面的内容并提取其中的特定部分 据我所知 此类任务至少有两种解决方案 爬虫4j https github com yasserg crawler4j and Jsoup http jsoup org 它们都能够检索页面的内容并提取其
  • 如何在jsp代码中导入java库?

    我有以下jsp代码 我想添加 java io 等库 我怎样才能做到这一点
  • OnClick 事件中的 finish() 如何工作?

    我有一个Activity一键退出Activity 通过layout xml我必须设置OnClick事件至cmd exit调用 this finish 效果很好 public void cmd exit View editLayout thi
  • 无法理解 Java 地图条目集

    我正在看一个 java 刽子手游戏 https github com leleah EvilHangman blob master EvilHangman java https github com leleah EvilHangman b
  • 如何将文件透明地传输到浏览器?

    受控环境 IE8 IIS 7 ColdFusion 当从 IE 发出指向媒体文件 例如 mp3 mpeg 等 的 GET 请求时 浏览器将启动关联的应用程序 Window Media Player 我猜测 IIS 提供文件的方式允许应用程序
  • 从 android 简单上传到 S3

    我在网上搜索了从 android 上传简单文件到 s3 的方法 但找不到任何有效的方法 我认为这是因为缺乏具体步骤 1 https mobile awsblog com post Tx1V588RKX5XPQB TransferManage
  • 使用 AWS Java SDK 为现有 S3 对象设置 Expires 标头

    我正在更新 Amazon S3 存储桶中的现有对象以设置一些元数据 我想设置 HTTPExpires每个对象的标头以更好地处理 HTTP 1 0 客户端 我们正在使用AWS Java SDK http aws amazon com sdkf
  • Java直接内存:在自定义类中使用sun.misc.Cleaner

    在 Java 中 NIO 直接缓冲区分配的内存通过以下方式释放 sun misc Cleaner实例 一些比对象终结更有效的特殊幻像引用 这种清洁器机制是否仅针对直接缓冲区子类硬编码在 JVM 中 或者是否也可以在自定义组件中使用清洁器 例
  • Java - 不要用 bufferedwriter 覆盖

    我有一个程序可以将人员添加到数组列表中 我想做的是将这些人也添加到文本文件中 但程序会覆盖第一行 因此这些人会被删除 如何告诉编译器在下一个空闲行写入 import java io import java util import javax
  • 如何测试 spring-security-oauth2 资源服务器安全性?

    随着 Spring Security 4 的发布改进了对测试的支持 http docs spring io spring security site docs 4 0 x reference htmlsingle test我想更新我当前的
  • 将2-3-4树转换为红黑树

    我正在尝试将 2 3 4 树转换为 java 中的红黑树 但我无法弄清楚它 我将这两个基本类编写如下 以使问题简单明了 但不知道从这里到哪里去 public class TwoThreeFour
  • 休眠以持久保存日期

    有没有办法告诉 Hibernate java util Date 应该持久保存 我需要这个来解决 MySQL 中缺少的毫秒分辨率问题 您能想到这种方法有什么缺点吗 您可以自己创建字段long 或者使用自定义的UserType 实施后User
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • Swagger/Openapi-Annotations:如何使用 $ref 生成 allOf?

    我正在生成 Rest 端点 包括添加OpenAPI Swagger对生成的代码进行注释 虽然它对于基本类型运行得很好 但我在自定义类方面遇到了一些问题 现在我有很多自定义类的重复架构条目 使用 Schema 实现 MyClass class

随机推荐

  • 如何使用 ajax-call joomla 2.5 加载自定义 html 模块

    我的 html 页面中有一个类名 flyer 和 href MY HREF 的链接 当用户单击链接时 我想加载具有特定 ID 的 自定义 html 模块 您能否告诉我 MY HREF 的语法如何 例如http www mywebsite c
  • 如果 autoStartup 设置为 false,如何手动启动 Spring Cloud Stream Binder

    我在用着spring cloud starter stream kafka创建 Kafka 消费者绑定并且我已经配置spring cloud stream bindings input consumer autoStartup to fal
  • 使用 PHP 根据日期显示内容

    我正在搭建一个基于 Wordpress 的竞赛网站 从法律上讲 比赛必须在午夜开始 为了避免半夜起来设置内容 我想构建一些 PHP 逻辑来显示开始日期之后的所有内容 并在此之前显示一些基本的 HTML 用于启动页面 我是一个完全的编程新手
  • 当监视从 componentDidMount 调用的组件方法时,永远不会调用间谍

    在 React 组件中我有 export default class MyComp extends Component componentDidMount this customFunc customFunc gt 当我尝试使用 Jest
  • 是否有一个 R 包可以处理 POSIX 对象并返回一周中的第 n 天?

    我编写了一个函数 当提供日期范围时 一周中特定日期的名称以及给定月份中该天的出现情况 例如 每个月的第二个星期五 将返回相应的日期 然而 它的速度不是很快 而且我并不 100 相信它的稳健性 R 中是否有一个包或一组函数可以对 POSIX
  • 服务器发送事件 停止 使用新参数启动

    请帮忙 我正在使用服务器发送事件根据数据库中存储的数据动态更新网站 我现在希望根据上一条消息中收到的数据将新参数 abc php lastID xxx 传递回 PHP 脚本 我明白我可以使用event close停止当前的 流 但我正在努力
  • 如何将离散值映射到seaborn中的热图?

    我正在尝试使用seaborn 在热图中绘制离散值 这是我试图绘制的列表 xa 5 4 4 4 13 4 4 1 9 4 3 9 1 4 4 1 7 1 5 3 7 1 9 4 3 9 5 4 2 1 4 1 9 4 3 9 4 8 1 7
  • 读取 JSON 文件时出现“参数列表太长”[重复]

    这个问题在这里已经有答案了 我有数千个 JSON 文件 我想将它们合并为一个文件 我正在使用下面的命令来执行此操作 jq s json gt result json 但我收到参数列表太长错误 可能是因为我尝试合并的文件数量 这个问题有什么解
  • ARC (Chrome) 上的 ANDROID_ID 与 Android 有何不同?

    在 Android 上 ANDROID ID 对于设备上的用户配置文件来说是常量 请参阅在这里讨论 ARC 上的情况似乎并非如此 但 ARC 非常新 希望这种情况能够改变 还值得注意的是 关于 ARC 的设备识别 Android 序列号在
  • 确定是否设置了对照片库的访问 - PHPhotoLibrary

    借助 iOS 8 中的新功能 如果您在应用程序中使用相机 它会请求访问相机的权限 然后当您尝试重新拍摄照片时 它会请求访问照片库的权限 下次启动应用程序时 我想检查相机和照片库是否有访问权限 对于相机 我通过以下方式检查 if AVCapt
  • Javascript GZIP 和 btoa 并用 C# 解压

    我正在开发一个应用程序 其中使用 pako gzip 压缩大型 JSON 数据 然后使用 btoa 函数将其设为 base64string 以便将数据发布到服务器 在我写的 JavaScript 中 var data JSON string
  • ff包写入错误

    我正在尝试使用 R 处理 1909x139352 数据集 由于我的计算机只有 2GB RAM 因此该数据集对于传统方法来说太大 500MB 所以我决定使用ff包裹 然而 我遇到了一些麻烦 功能read table ffdf无法读取第一个数据
  • 过去 X 小时内未使用的 Docker 修剪镜像

    有办法吗docker prune image如果在过去 X 小时内未使用图像或其中间层 是否要删除图像 目的是 假设构建已经创建了中间和最终映像 F1 后续构建可以使用中间映像 当后续构建正在运行时 如果我运行docker image pr
  • 在python中导入全局命名空间

    假设我有以下文件 a py glo var 0 def func global glo var glo var 5 print A d glo var b py from a import func print B d glo var 如果
  • 从视图列检索数据时如何避免 64k 限制?

    我知道 SSJS 版本 DbColumn 与原始 Formula 语言版本具有相同的 64k 限制 所以到目前为止我用过NotesView getColumnValues 相反 相信在这里我不会面临这样的限制 正如昨天的紧急支持电话告诉我的
  • 选项卡的关闭按钮不支持 vcl 样式

    我已经使用了本示例中提供的代码如何为 TPageControl 的 Ttabsheet 实现关闭按钮在页面控件的每个选项卡上绘制一个关闭按钮 我在代码中用样式服务替换了 ThemeServices 并且在应用样式时 关闭按钮不会显示 也不会
  • python多线程“超过最大递归深度”

    我使用Python多线程来实现快速排序 快速排序是在函数中实现的 它是一个递归函数 每个线程调用 Quicksort 对其拥有的数组进行排序 每个线程都有自己的数组 用于存储需要排序的数字 如果数组大小较小 def partition ar
  • 运行多模块 Maven 项目

    这是一个基本问题 我只是不太熟悉maven多模块结构 假设我有一个网络应用程序 我想将一些模块连接到它 一些服务 我是否需要将 Web 应用程序制作为依赖于其他模块的模块之一 然后运行它 起初我以为我可以运行整个项目 但这个选项在我的 ID
  • 通过索引获取(真实)监视器的句柄

    假设我有 3 个显示器 如何仅通过索引获取第二个的句柄 EnumDisplayMonitors 不起作用 因为它也会枚举伪设备 而 EnumDisplayDevices 不给我句柄 你需要使用EnumDisplayMonitors 代替En
  • 如何使用 JCodec 将一系列图像转换为视频?

    我正在尝试使用 JCodec 将一系列图像转换为 Java SE 桌面应用程序内的视频 我尝试过的几种方法都导致 Windows Media Player 无法播放视频 我不清楚这是否是编解码器问题 值得怀疑 或者我是否没有正确创建视频 当