You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ogg Opus granule position转时间戳实现文件无损裁剪问题咨询

Ogg Opus无转码裁剪判断逻辑实现

核心前提

Opus在Ogg封装中的时间计量基于48kHz固定采样率,你可以先将裁剪时间窗口转换为采样计数基准值:

// 成员变量,提前初始化
private long startSample;
private long endSample;
// 初始化时调用一次,将毫秒转为48kHz采样数
public void initTrimRange(long startTimeMs, long endTimeMs) {
    this.startSample = startTimeMs * 48L; // 48000采样率 / 1000ms = 48采样/ms
    this.endSample = endTimeMs * 48L;
}

方案1:基于Ogg页粒度判断(实现pageLiesWithinTrimRange)

Ogg页的granulePosition字段定义为该页内最后一个完整音频包解码后的结束采样位置,你需要额外增加一个成员变量记录上一个音频页的结束采样位置:

// 成员变量,记录上一页的granulePosition,初始值为0
private long prevPageGranule = 0L;

private boolean pageLiesWithinTrimRange(OggPage page){
    long currentGranule = page.getGranulePosition();
    // 跳过ID头、评论头等头页面,你已经单独写入输出流
    if (page.isHeaderPage() || currentGranule == 0) {
        prevPageGranule = currentGranule;
        return false;
    }
    // 当前页覆盖的采样区间为 [prevPageGranule + 1, currentGranule]
    // 判断区间是否和裁剪窗口有交集
    boolean isInRange = (prevPageGranule + 1 <= endSample) && (currentGranule >= startSample);
    // 更新上一页granule记录
    prevPageGranule = currentGranule;
    return isInRange;
}

方案2:基于音频包粒度判断(实现packetLiesWithinTrimRange)

包粒度判断精度更高,需要额外记录当前已处理的累计采样偏移:

// 成员变量,记录当前累计处理的采样偏移,初始值为0
private long currentSampleOffset = 0L;

private boolean packetLiesWithinTrimRange(OpusPacket packet){
    // 从Opus包中获取该包的采样数,oggus库已封装该能力
    long packetSampleCount = packet.getSampleCount();
    long packetStart = currentSampleOffset;
    long packetEnd = currentSampleOffset + packetSampleCount - 1;
    // 更新累计偏移
    currentSampleOffset += packetSampleCount;
    // 判断包的采样区间是否和裁剪窗口有交集
    return (packetStart <= endSample) && (packetEnd >= startSample);
}

注意事项

  1. 裁剪后输出的第一个音频页的granulePosition需要修正,减去裁剪起始点的采样值,保证输出文件的时间轴从0开始
  2. 输出的所有Ogg页的serialNum需要保持统一
  3. 输出流开头需要先写入ID头和评论头,再写入过滤后的音频页

内容的提问来源于stack exchange,提问作者Omkar T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 07:45:03