如何从ogg / opus文件中一一读取OPUS数据包

问题描述

我需要从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文件。

编码愉快!