【发布时间】:2021-01-21 09:40:36
【问题描述】:
我在尝试打开包含opus 格式的原始音频数据 的二进制文件时遇到问题。当我尝试打开此文件时,库返回错误:未知输入格式:opus。
如何打开这个文件?
我需要打开它并将所有原始音频数据写入音频容器。我了解opus 格式仅适用于encoding。我使用命令实现了这一点:
$ ffmpeg -formats | grep Opus
ffmpeg version 3.4.4 Copyright (c) 2000-2018 the FFmpeg developers
E opus Ogg Opus # For only encoding
那我应该用什么格式打开这个文件呢?使用 ogg ?我试过了,但是打开传出文件也有问题。我提供的代码仅显示打开文件的必要部分:
int main(int argc, char *argv[])
{
// ...
av_register_all();
AVFormatContext *iFrmCtx = nullptr;
AVFormatContext *oFrmCtx = nullptr;
AVPacket packet;
const char *iFilename = "opus.bin"; // Raw audio data with `opus` format
const char *oFilename = "opus.mka"; // Audio file with `opus` audio format
AVDictionary* frmOpts = nullptr;
const qint32 smpRateErrorCode = av_dict_set_int(&frmOpts, "sample_rate", 8000, 0);
const qint32 bitRateErrorCode = av_dict_set_int(&frmOpts, "bit_rate", 64000, 0);
const qint32 channelErrorCode = av_dict_set_int(&frmOpts, "channels", 2, 0);
if (smpRateErrorCode < 0 ||
bitRateErrorCode < 0 ||
channelErrorCode < 0) {
return EXIT_FAILURE;
}
AVInputFormat *iFrm = av_find_input_format("opus"); // Error: Unknown input format
if (iFrm == nullptr) {
av_dict_free(&frmOpts);
return EXIT_FAILURE;
}
qint32 ret = 0;
if ((ret = avformat_open_input(&iFrmCtx, iFilename, iFrm, &frmOpts)) < 0) {
av_dict_free(&frmOpts);
return EXIT_FAILURE;
}
// We're doing something...
}
【问题讨论】:
-
opus 格式的原始音频数据是什么意思? Opus 不是自定界的,它需要一个容器(OGG、Matroska、ISO BMFF 可能/建议、UDP/RTP)。在 RFC 6716 中有一个用于自定界帧的附录 B,但它通常用于为多个流/通道打包数据包,并且它仍然依赖于传输层来发出信号。我在 FFmpeg 中知道的所有解复用器都是用于 OGG 的。无论如何,使用虚拟的
image2demuxer 似乎至少能够检测从 RTP 有效负载中提取的作品,但不确定它是否在所有情况下都能解码,无论如何这都是个坏主意。 -
@aergistal,opus 格式是指音频数据以 opus 编码(也可以是 pcm_alaw 音频数据、pcm_mulaw 等)。在实践中,我得到 RTP 数据包,其中 opus 音频数据存储在有效负载中。然后我从 RTP 数据包中提取有效负载并将其发送到音频编码器。在我的示例中,我只想从文件中提取所有 opus 格式的音频数据,并将其打包为 Matroska 格式。
-
@aergistal,音频数据没有问题
alaw、mulaw、s16le、s16be(因为avformat_open_input找到了这些格式),但我的作品有问题,在问题本身中进行了描述。如果你愿意,我可以给你我自己的代码 (~300 lines of code),我用它来将原始音频数据编码成一个音频文件 :) -
就像我说的,我没有看到任何用于原始有效负载的解复用器,只有 OGG。但是您可以编写一个快速解复用器来设置有效负载长度,然后将其传递给
libopus(可选编解码器,您需要在 FFmpeg 配置期间启用)。不过没试过。 -
@aergistal,写一个解复用器,this 足以让我理解如何实现它吗?另外,这句话是什么意思:
you need to enable during FFmpeg configure.