当前位置: 首页 > 面试题库 >

Xuggler编码和混合

卫高明
2023-03-14
问题内容

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

  • 接受原始的MPJPEG视频比特流(来自小型TTL串行相机)并将其编码/转码为h.264;和
  • 接受原始音频bitream(来自麦克风)并将其编码为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的此示例代码,以下代码应该可以将视频编码为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() )的 时间戳较早

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

要回答您提出的特定问题:

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

(2)“找出原始音频供稿的“ BufferedImage-等效”是什么”-这是short
[]或IAudioSamples对象(两者似乎都起作用,但是IAudioSamples必须从IBuffer构造,这要不太直接)。

(3)“将此音频类别编码为AAC音频流”-呼叫 writer.addAudioStream(..., ICodec.ID.CODEC_ID_AAC, channelCount, sampleRate)

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

PS始终首先传递最早可用的音频/视频。例如,如果您有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

…等等

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

PS:您可能要参考一些文档:Xuggler类图,ToolFactory,IMediaWriter,ICodec。



 类似资料:
  • 我正在尝试使用Xugler(我相信它在引擎盖下使用)来执行以下操作: 接收原始MPJPEG视频比特流(来自小型TTL串行摄像头),并将其编码/转码为h.264;和 接收原始音频比特RAM(来自麦克风)并将其编码到AAC;然后 将两个(音频和视频)位存储在一起,并将其多路复用到一个MPEG-TS容器中 我已经看过了他们的一些优秀教程,到目前为止,我得到的是: 首先,我认为我离这里很近,但它仍然不正确

  • 问题内容: 是的,我知道FAQ会假装回答此问题,但实际上并非如此。相反,它指示您从源代码构建项目(并且构建说明非常复杂)。那种打败了整个观点:) 让我们省去世界上每个人的麻烦,即不必再构建另一个开源项目,以了解它是否真正解决了他们的问题。Xuggler支持哪些编解码器? 问题答案: FAQ不能回答这个问题的原因是,随着我们发布新版本,它会不断变化,并且要使文档中的列表保持最新状态会花费很长时间。但

  • Xuggler 提供了利用 Java 来解压缩,修改和重新压缩任何媒体或流文件的最简单方式。

  • 我正在编写一个记录屏幕和音频的应用程序。虽然屏幕录制工作完美,但我很难使用JDK库获取原始音频。代码如下: 这个页面有一些伪代码,比如 但是对于,我应该做些什么呢? 此外,还有一个额外的问题——在这种方法中,是否可以从多个麦克风中进行选择? 另请参见:Xuggler编码和muxing

  • 问题内容: 我有一个主要为UTF-8的文件,但是也发现了一些Windows-1252字符。 我创建了一个表,以将Windows-1252(cp1252)字符映射到对应的Unicode对应表,并希望使用它来修复编码错误的字符,例如 但是尝试以这种方式进行替换会导致引发UnicodeDecodeError,例如: 有关如何处理此问题的任何想法? 问题答案: 如您所知,如果您尝试将此字符串解码为utf-

  • 问题内容: 我对如何混合剃须刀和js感到很困惑。这是我坚持的当前功能: 如果我可以用声明c#代码,而其他所有内容都是JS代码,这就是我的追求: 实现此目的的最佳方法是什么? 问题答案: 用途: