问题描述
我需要从ogg / opus文件中逐一读取OPUS数据包,并以OPUS格式进一步发送它们,因此无需解码。我正在查看opusfile lib,但API和示例相当复杂,并且更加着重于解码文件并获得结果PCM。有没有办法用这个库实现我想要的功能,以及如何实现?如果没有,我还有什么其他选择?
解决方法
libogg可用于解析Ogg Opus文件的“页面”,然后可以从这些页面中提取opus“数据包”。请注意,数据包 可能会跨越页面,但是我个人在测试opusenc创建的文件时并没有遇到。您还可以手动解析页面(请参见Splitting an Ogg Opus File stream)
我建议您阅读Opus文件规范( RFC 7845 )的基础知识,以首先了解文件结构。 https://opus-codec.org/docs/
,您可以使用libogg
来访问Opus数据包。不幸的是,它并没有比opusfile
更简单。在C-ish伪代码中,一般流程为:
readPage(ogg_sync_state* syncState,ogg_page* page,file) {
while ((ogg_sync_pageout(syncState,page) != 1) && file is good) {
buffer = ogg_sync_buffer(syncState,yourMaxReadSize);
bytesActuallyRead = read(file,buffer,yourMaxReadSize);
ogg_sync_wrote(syncState,bytesActuallyReadFromFile); //tell the syncState how many bytes were actually read
} //now we have a page,or the file is done
}
read() {
ogg_sync_state oggSyncState;
ogg_stream_state oggStreamState;
ogg_page oggPage;
ogg_packet oggPacket;
open file;
while (file is good) {
readPage(&oggSyncState,&oggPage);
if (ogg_page_bos(&oggPage)) {
sn = ogg_page_serialno(&oggPage); //you can remember this serial number and check it on every page for robustness
ogg_stream_init(&oggStreamState,sn);
}
ogg_stream_pagein(&oggStreamState,&oggPage);
while (ogg_stream_packetout(&oggStreamState,&oggPacket) != 0) {
//check if it's a header packet,skip if so.
//See https://tools.ietf.org/html/rfc7845.html#section-5 to see how to identify a header packet
//Else it must be data
do something with the buffer oggPacket.packet with size oggPacket.bytes
}
readPage(&oggSyncState,&oggPage,file);
ogg_stream_pagein(&oggStreamState,&oggPage_);
}
}
readPage
从文件中拉出一堆字节(yourMaxReadSize
)到oggSyncState
结构中,然后一个一个地提取页面。在read
中,数据包是从页面中一个接一个地提取的。
我想我来晚了。我有非常相似的用例,我想从ogg opus文件中提取opus数据包。我找到了这个答案
https://stackoverflow.com/a/26285277/10110652
以下代码将帮助您在while循环内的“ nextPacket” byteArray中获取Opus数据包(未解码为pcm)
samples:
chr1A:
- scaffold26096
- scaffold40476
chr1B:
- scaffold11969
- scaffold83281
- scaffold43483
chr1D:
- scaffold4701
- scaffold102360
同一程序可用于提取ogg容器中的vorbis编码数据包,即ogg vorbis文件。
编码愉快!