gpt4 book ai didi

java - Xuggler 编码和混合

转载 作者:搜寻专家 更新时间:2023-10-30 21:05:57 25 4
gpt4 key购买 nike

我正在尝试使用 Xuggler (我相信在后台使用 ffmpeg)执行以下操作:

  • 接受原始 MPJPEG 视频比特流(来自小型 TTL 串行相机)并将其编码/转码为 h.264;和
  • 接受原始音频比特流(来自麦克风)并将其编码为 AAC;然后
  • 将两个(音频和视频)比特流混合到一个 MPEG-TS 容器中

我已经观看/阅读了他们的一些优秀教程,到目前为止,我得到的是:

// I'll worry about implementing this functionality later, but
// involves querying native device drivers.
byte[] nextMjpeg = getNextMjpegFromSerialPort();

// I'll also worry about implementing this functionality as well;
// I'm simply providing these for thoroughness.
BufferedImage mjpeg = MjpegFactory.newMjpeg(nextMjpeg);

// Specify a h.264 video stream (how?)
String h264Stream = "???";

IMediaWriter writer = ToolFactory.makeWriter(h264Stream);
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264);
writer.encodeVideo(0, mjpeg);

一方面,我认为我在这里很接近,但仍然不正确;我只是通过阅读视频代码示例(不是音频 - 我找不到任何好的音频示例)才走到这一步。

从字面上看,我将获得对进入我的 Xuggler 实现的原始视频和音频源的字节级访问。但对于我的生活,我无法弄清楚如何将它们转换为 h.264/AAC/MPEG-TS 格式。在此先感谢您的帮助。

最佳答案

查看Xuggler this sample code , 以下代码应该可以将视频编码为 H.264 并将其复用到 MPEG2TS 容器中:

IMediaWriter writer = ToolFactory.makeWriter("output.ts");
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, width, height);
for (...)
{

BufferedImage mjpeg = ...;

writer.encodeVideo(0, mjpeg);
}

根据文件扩展名猜测容器类型,明确指定编解码器。

要混合音频和视频,您可以这样做:

writer.addVideoStream(videoStreamIndex, 0, videoCodec, width, height);
writer.addAudioStream(audioStreamIndex, 0, audioCodec, channelCount, sampleRate);

while (... have more data ...)
{
BufferedImage videoFrame = ...;
long videoFrameTime = ...; // this is the time to display this frame
writer.encodeVideo(videoStreamIndex, videoFrame, videoFrameTime, DEFAULT_TIME_UNIT);

short[] audioSamples = ...; // the size of this array should be number of samples * channelCount
long audioSamplesTime = ...; // this is the time to play back this bit of audio
writer.encodeAudio(audioStreamIndex, audioSamples, audioSamplesTime, DEFAULT_TIME_UNIT);
}

在这种情况下,我相信您的代码负责音频和视频的交织:您希望在每次循环时调用 encodeAudio() encodeVideo(),具体取决于哪些数据可用(一大块音频样本或视频帧)有一个较早的时间戳

您可能最终会使用另一个较低级别的 API,它基于 IStreamCoder ,它可以更好地控制各种参数。我认为您不需要使用它。

回答您提出的具体问题:

(1)“将 BufferedImage (M/JPEG) 编码为 h.264 流”- 您已经知道了,writer.addVideoStream(..., ICodec.ID.CODEC_ID_H264)确保您获得 H.264 编解码器。要获取传输流 (MPEG2 TS) 容器,只需使用扩展名为 .ts 的文件名调用 makeWriter()

(2) “找出原始音频馈送的“BufferedImage-equivalent”是什么”- short[] 或 IAudioSamples对象(两者似乎都有效,但 IAudioSamples 必须从 IBuffer 构造,这要简单得多)。

(3)“将此音频类编码为 AAC 音频流”——调用 writer.addAudioStream(..., ICodec.ID.CODEC_ID_AAC, channelCount, sampleRate)

(4)“将两个流复用到同一个 MPEG-TS 容器中”- 使用 .ts 文件名调用 makeWriter(),这会设置容器类型。为了正确的音频/视频同步,您可能需要以正确的顺序调用 encodeVideo()/encodeAudio()。

附言始终首先传递最早可用的音频/视频。例如,如果您的音频 block 长度为 440 个样本(44000 Hz 采样率,440/44000 = 0.01 秒),而视频恰好为 25fps(1/25 = 0.04 秒),您可以将它们提供给作者这个顺序:

video0 @ 0.00 sec
audio0 @ 0.00 sec
audio1 @ 0.01 sec
audio2 @ 0.02 sec
audio3 @ 0.03 sec
video1 @ 0.04 sec
audio4 @ 0.04 sec
audio5 @ 0.05 sec

...等等

只要连续的音频/视频时间戳相对接近,大多数播放设备可能都可以处理流,但这是您为完美的多路复用所做的。

附言您可能需要引用一些文档:Xuggler class diagram , ToolFactory , IMediaWriter , ICodec .

关于java - Xuggler 编码和混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13839850/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com