我需要从ogg/opus文件中一个接一个地读取OPUS数据包,并在没有解码的情况下以OPUS格式进一步发送它们。我正在研究PCM库,但是opusfile和示例相当复杂,并且更多地集中在解码文件和获得结果的PCM上。有没有办法用这个库实现我想要的东西?如果不是,我还有其他选择吗?
发布于 2020-10-22 20:11:44
libogg可以用来解析Ogg Opus文件的“页面”,然后可以从这些页面中提取操作“数据包”。请注意,数据包可能会跨越多个页面,但我个人在测试opusenc创建的文件时没有遇到过这种情况。您也可以手动解析页面(请参阅Splitting an Ogg Opus File stream)
我建议先阅读Opus文件规范(RFC7845)的基础知识,以了解文件结构。https://opus-codec.org/docs/
发布于 2020-12-16 17:44:15
我想我来晚了一点。我有非常相似的用例,我想从ogg opus文件中提取opus包。我找到了这个答案
https://stackoverflow.com/a/26285277/10110652
下面的代码将帮助您在while循环内的'nextPacket‘byteArray中获得opus数据包(没有解码为pcm)
File audioFile = null;
try {
audioFile = new File("xyz.ogg"); //input ogg opus file
oggFile = new FileStream(new RandomAccessFile(audioFile, "r"));
for (LogicalOggStream stream : (Collection<LogicalOggStream>) oggFile.getLogicalStreams()) {
byte[] nextPacket = stream.getNextOggPacket();
while (nextPacket != null) {
//nextPacket here contains opus packet
//do what ever you want to do with this packet
nextPacket = stream.getNextOggPacket();
}
}
} catch (EndOfOggStreamException e) {
System.out.println("End of File");
//file usually get over by raising this exception while execution getNextOggPacket()
}同样的程序可以用来提取ogg容器中的vorbis编码的数据包,即ogg vorbis文件。
编码快乐!
发布于 2020-10-22 20:20:30
您可以使用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中,数据包是逐个从页面中提取的。
https://stackoverflow.com/questions/64479365
复制相似问题