首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从ogg/opus文件中逐个读取OPUS数据包

如何从ogg/opus文件中逐个读取OPUS数据包
EN

Stack Overflow用户
提问于 2020-10-22 17:32:45
回答 3查看 667关注 0票数 2

我需要从ogg/opus文件中一个接一个地读取OPUS数据包,并在没有解码的情况下以OPUS格式进一步发送它们。我正在研究PCM库,但是opusfile和示例相当复杂,并且更多地集中在解码文件和获得结果的PCM上。有没有办法用这个库实现我想要的东西?如果不是,我还有其他选择吗?

EN

回答 3

Stack Overflow用户

发布于 2020-10-22 20:11:44

libogg可以用来解析Ogg Opus文件的“页面”,然后可以从这些页面中提取操作“数据包”。请注意,数据包可能会跨越多个页面,但我个人在测试opusenc创建的文件时没有遇到过这种情况。您也可以手动解析页面(请参阅Splitting an Ogg Opus File stream)

我建议先阅读Opus文件规范(RFC7845)的基础知识,以了解文件结构。https://opus-codec.org/docs/

票数 1
EN

Stack Overflow用户

发布于 2020-12-16 17:44:15

我想我来晚了一点。我有非常相似的用例,我想从ogg opus文件中提取opus包。我找到了这个答案

https://stackoverflow.com/a/26285277/10110652

下面的代码将帮助您在while循环内的'nextPacket‘byteArray中获得opus数据包(没有解码为pcm)

代码语言:javascript
复制
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文件。

编码快乐!

票数 1
EN

Stack Overflow用户

发布于 2020-10-22 20:20:30

您可以使用libogg访问Opus数据包。不幸的是,它并不比opusfile简单得多。在C-ish伪代码中,一般流程是:

代码语言:javascript
复制
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中,数据包是逐个从页面中提取的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64479365

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档