【音视频 | opus】opus编码的Ogg封装文件详解

news2025/2/22 23:37:51

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍 opus 编码的 Ogg 封装文件🍭
😎金句分享😎:🍭🍭

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
  • 🎄二、ID头部数据(ID Header)
    • ✨2.1、ID 头部数据的介绍
    • ✨2.2、.opus 文件 ID头部数据 分析
  • 🎄三、注释头部数据(Comment Header)
    • ✨3.1、注释头部数据的介绍
    • ✨3.2、.opus 文件 注释头部数据 分析
    • 在这里插入图片描述
  • 🎄四
  • 🎄五
  • 🎄六、


在这里插入图片描述

🎄一、概述

前面的文章 Ogg封装格式详解 介绍了Ogg格式的封装,介绍了封装过程、Ogg的页结构、Ogg的段,但没涉及到每个段的内容,因为这跟编码有关系。本文就介绍 opus 编码在 Ogg 封装文件中是怎样存储的,同样地,从一个 opus 编码的Ogg文件去查看十六进制,最终了解 opus 编码 Ogg 封装文件的整个结构,这样就可以轻易将这类文件解码为PCM了。

opus 编码的Ogg文件结构如下图:

  • 逻辑Ogg比特流中的第一个数据包必须包含ID头部数据(ID Header),该头部数据将流唯一标识为Opus音频。
  • 逻辑Ogg比特流中的第二个数据包必须包含注释头部数据(Comment Header),其中包含用户提供的元数据。
  • 之后的所有页面(page)都是音频数据页面。
    在这里插入图片描述
    下文分析的Ogg封装文件为 48000Hz-s16le-1ch-ChengDu.opus,下载链接:https://download.csdn.net/download/wkd_007/88492683

在这里插入图片描述

🎄二、ID头部数据(ID Header)

✨2.1、ID 头部数据的介绍

opus编码的逻辑Ogg比特流中,第一页必须包含ID头部数据,其结构如下图,包括8个字段,各个字段代表的含义如下:

在这里插入图片描述

  • 1、Magic Signature(8字节):

    这是一个8位字节(64位)字段,允许编解码器识别,并且是人类可读的。它按顺序包含以下的字母:

    0x4F 'O'
    0x70 'p'
    0x75 'u'
    0x73 's'
    0x48 'H'
    0x65 'e'
    0x61 'a'
    0x64 'd'
    

    从“Op”开始有助于将其与音频数据包区分开来,因为这是一个无效的TOC序列。

  • 2、Version (1字节, unsigned):
    对于此版本的封装规范,版本号必须始终为“1”。实现应该将版本号的前四位与已识别规范的版本号匹配的流视为与该规范向后兼容。也就是说,版本号可以分为“主要”和“次要”版本子字段,次要子字段的变化(在较低的四位中)表示兼容的变化。例如,本规范的实现应该接受版本号为“15”或更低的任何流,并且应该假设版本号为”16“或更高的任何流不兼容。选择初始版本“1”是为了防止实现依赖此八位字节作为“OpusHead”字符串的null终止符。

  • 3、Output Channel Count ‘C’ (1字节, unsigned)
    这是输出通道的数量。这可能与编码信道的数量不同,编码信道的数目可以在逐包的基础上改变。此值不得为零。最大允许值取决于通道映射族,可能大到255。详见[RFC7845]文档的第5.1.1节。

  • 4、Pre-skip (2字节, unsigned, little endian):

    这是开始播放时要从解码器输出中丢弃的采样数(48 kHz),也是要从页面的颗粒位置中减去以计算其PCM采样位置的数量。当裁剪现有Ogg Opus流的开头时,建议预跳过至少3840个样本(80ms),以确保解码器完全收敛。

  • 5、Input Sample Rate (4字节, unsigned, little endian):

    这是原始输入(编码前)的采样率,单位为Hz。该字段不是用于播放编码数据的采样率。

    Opus可以在4、6、8、12和20kHz的内部音频带宽之间切换。流中的每个数据包可以具有不同的音频带宽。不管音频带宽如何,参考解码器都支持以8、12、16、24或48kHz的采样率对任何流进行解码。传递到编码器的音频的原始采样率不被有损压缩所保留。

    Ogg Opus播放器应根据以下程序选择播放采样率:

    1.如果硬件支持48 kHz播放,则以48 kHz进行解码。

    2.否则,如果硬件的最高可用采样率是支持的速率,则以该采样率进行解码。

    3.否则,如果硬件的最高可用采样率小于48kHz,则以高于最高可用硬件速率的下一个更高的Opus支持速率进行解码并重新采样。

    4.否则,以48 kHz解码并重新采样。

    然而,“输入采样率”字段允许复用器将原始输入流的采样率作为元数据传递。当用户需要输出采样率来匹配输入采样率时,这是有用的。例如,当不播放输出时,将PCM格式样本写入磁盘的实现可能会选择将音频重新采样回原始输入采样率,以减少用户的意外,因为用户可能会合理地期望以相同的采样率返回文件。

    零值表示“未指定”。复用器应该写入实际输入采样率或零,但使用该字段执行某些操作的实现应该注意,如果给定疯狂的值(例如,如果请求,不要实际将输出上采样到10MHz),则行为要理智。实现应支持 8kHz 和 192kHz(包括8kHz)之间的输入采样率。此范围之外的速率可以通过回落到默认速率 48kHz 来忽略。

  • 6、Output Gain (2字节, signed, little endian):

    这是解码时要应用的增益。它是对解码器输出进行缩放以获得所需播放量的因子的20*log10,存储在具有8个小数比特的16比特、带符号的2的补码定点值中(即Q7.8[Q-NOTATION])。

    为了应用增益,实现可以使用以下内容:

    sample *= pow(10, output_gain/(20.0*256))
    

    其中“output_gain”是来自标头的原始16位值。

    玩家和媒体框架应该默认应用它。如果播放器选择应用任何音量调整或增益修改,如R128_TRACK_AIN(见第5.2节),则除了此输出增益外,还必须应用该调整,以实现标准化音量的播放。

    复用器应该将该字段设置为零,而不是在编码之前应用任何增益,只要这是可能的,并且不会与用户的愿望相冲突。非零输出增益表示在编码之后调整了增益,或者用户希望在保持恢复原始信号幅度的能力的同时调整增益以进行回放。

    尽管输出增益具有巨大的范围(+/-128 dB,足以将听不见的声音放大到身体疼痛的阈值),但大多数应用程序只能合理地使用零附近这个范围的一小部分。大范围的部分作用是确保增益始终可以在OpusHead和R128增益标签之间无损传输(见下文)而不会饱和。

  • 7、Channel Mapping Family (1字节, unsigned):

    这个八位字节表示输出通道的顺序和语义。

    该八位位组的每个当前指定值都指示一个映射族,该映射族定义了一组允许的通道计数,以及每个允许的通道数的有序通道名称集。详见[RFC7845]文档的第5.1.1节。

  • 8、Channel Mapping Table:

    此表定义了从编码流到输出通道的映射。其内容见[RFC7845]文档的第5.1.1节。ID标头中的所有字段都是必需的,但“通道映射表”除外,当通道映射族为0时,必须省略该字段,否则为必需字段。如果流包含的ID标头没有足够的数据用于这些字段,即使它包含有效的“魔术签名”,实现也应该将其视为无效。该规范的未来版本,甚至是向后兼容的版本,可能会在ID头中包含额外的字段。如果ID标头具有兼容的主版本,但具有较大的次版本,则实现不得将其视为无效,因为它包含此处未指定的其他数据,前提是它仍然在第一页上完成。

✨2.2、.opus 文件 ID头部数据 分析

现在按照上面的字段,分析opus编码的Ogg文件,用Notepad打开 48000Hz-s16le-1ch-ChengDu.opus 并查看十六进制模式:

在这里插入图片描述

  • 前面蓝色背景的部分(包括0x13)是Ogg页头部数据,不清楚的看 [上篇文章] 的 4.2 节;
  • 紫色框开始是opus编码的ID头部数据,内容是8个字符:OpuaHead
  • 接下去的蓝色框是版本号,目前的版本,该值为 1
  • 紧接着的蓝色框是声道数量,这里值为 1 ,表示单声道;
  • 后面的橙色框表示 “开始播放时要从解码器输出中丢弃的采样数”,值为0x0138
  • 接着的绿色框表示 “原始输入(编码前)的采样率”,值为0xbb80,对应十进制 48000
  • 后面的蓝色框表示 “解码时要应用的增益”;
  • 后面的黑色框表示 “表示输出通道的顺序和语义”,值为 0 ,代表使用映射族0,允许的通道数:1或2,且省略通道映射表(Channel Mapping Table);

在这里插入图片描述

🎄三、注释头部数据(Comment Header)

✨3.1、注释头部数据的介绍

opus编码的逻辑Ogg比特流中,第二页必须包含注释头部数据。它可能跨越多个页面(page),从逻辑流的第二页开始。无论它跨越多少页,注释头数据包都必须结束在一个完整的页面,其结构如下图,包括6个字段,各个字段代表的含义如下:
在这里插入图片描述

  • 1、Magic Signature(8个字节):

    这是一个8位字节(64位)字段,允许编解码器识别,并且是人类可读的。它按顺序包含以下神奇数字:

    0x4F 'O'
    0x70 'p'
    0x75 'u'
    0x73 's'
    0x54 'T'
    0x61 'a'
    0x67 'g'
    0x73 's'
    

    从“Op”开始有助于将其与音频数据包区分开来,因为这是一个无效的TOC序列。

  • 2、Vendor String Length (4个字节, unsigned, little endian):

    此字段给出下个字段Vendor String的长度,单位为八位字节。它不得指示供应商字符串比数据包的其余部分长。

  • 3、Vendor String (variable length, UTF-8 vector):

    这是一个用于供应商信息的简单可读标签,编码为UTF-8字符串[RFC3629]。不需要终止空八位字节。

    此标签旨在识别编解码器编码器和封装实现,以跟踪技术行为的差异。面向用户的应用程序可以使用“ENCODER”用户注释标记来标识自己。

  • 4、User Comment List Length (4个字节, unsigned, little endian):

    此字段指示用户提供的注释个数。它可能表示用户提供的注释为零,在这种情况下,数据包中没有其他字段。它不能表明有太多的注释,以至于注释字符串长度需要比数据包其余部分更多的数据。

  • 5、User Comment #i String Length (4个字节, unsigned, little endian):

    此字段给出下个字段User Comment #i String的长度,单位为八位字节。“用户评论列表长度”字段指示的每个用户评论都有一个。它不能指示字符串比数据包的其余部分长。

  • 6、User Comment #i String (variable length, UTF-8 vector):

    此字段包含编码为UTF-8字符串的单个用户注释[RFC3629]。“用户评论列表长度”字段指示的每个用户评论都有一个。

✨3.2、.opus 文件 注释头部数据 分析

在这里插入图片描述

在这里插入图片描述

🎄四

在这里插入图片描述

🎄五

在这里插入图片描述

🎄六、

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1171949.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SpringCloud Alibaba -- Nacos】Linux 搭建 Nacos 集群

搭建 Nacos 集群 架构 centos安装docker https://docs.docker.com/engine/install/centos/ 详细配置过程 MySql8 mysql数据库配置 数据库脚本 nacos/conf/nacos-mysql.sql Nacos2 application.properties 修改为mysql spring.datasource.platformmysqldb.num1 db.url…

【算法挑战】字符的最短距离(含解析、源码)

821.字符的最短距离 https://leetcode-cn.com/problems/shortest-distance-to-a-character/ 821.字符的最短距离 题目描述解法 1:中心扩展法 思路复杂度分析代码 (JS/C) 解法 2:空间换时间 思路复杂度分析代码 (JS/C) 解法 3:贪心 思路复杂…

阿里大佬:DDD 领域层,该如何设计?

说在前面 在40岁老架构师 尼恩的读者交流群(50)中,最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: 谈谈你的DDD落地经验? 谈谈你对DDD的理解&#xff1f…

C语言 程序环境 编译和链接

目录 1.程序的翻译环境和执行环境 2.详解C语言程序的编译和链接 2.1翻译环镜 2.2翻译的几个阶段 2.2.1预编译 2.2.2编译 词法分析 符号汇总 2.2.3汇编 生成符号表 2.3链接 1.合并段表 2.合并符号表和重定位 2.4运行环境 1.程序的翻译环境和执行环境 在ANSI C的任…

【网络协议】聊聊DNS协议如何域名解析和负载均衡

DNS 服务器 我们知道如果使用IP地址进行访问网站,很难进行记忆,所以DNS的作用是将域名转换成对应的IP地址。如果全世界都使用同一台DNS服务器,那么DNS服务器本身需要保证服务的高可用、高性能,以及分布式等。最好的方式就是分层。…

日语动词三分类

所有的动词原形都是由う段结尾 50音图 一类动词 一类动词又称五段动词(う段动词) 1.结尾是う段非る的动词 ます形规律:う段 > 同行的い段ます 日文平假名ます形中文書くかく書きます写探すさがす探します寻找勝つかつ勝ちます胜利遊ぶ…

电脑报错找不到msvcp120dll,无法继续执行代码,怎么修复?

在运行电脑软件时,出现msvcp120.dll丢失,我深知大家在遇到这种电脑问题时所感受到的无助和焦虑。今天,我就来为大家分享一下关于msvcp120.dll文件缺失的4个一键解决方法,希望能帮助到大家。 首先,我们要明确什么是msv…

SecoClient连接报错:接收返回码超时

话接上回,SecoClient能打开了,但是出现了连接时的错误 这次针对接收返回码超时进行解决。 参考连接: https://www.cnblogs.com/Crazy-Liu/p/14700121.html https://blog.csdn.net/lnigluan511513/article/details/1280683581、正常我们进入…

【JVM】双亲委派机制、打破双亲委派机制

🐌个人主页: 🐌 叶落闲庭 💨我的专栏:💨 c语言 数据结构 javaEE 操作系统 Redis 石可破也,而不可夺坚;丹可磨也,而不可夺赤。 JVM 一、双亲委派机制1.1 双亲委派的作用1.…

Jetpack:028-Jetpack中的Card

文章目录 1. 概念介绍2. 使用方法2.1 主要类型2.2 其它类型 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack中Switch相关的内容,本章回中 主要介绍Card。闲话休提,让我们一起Talk Android Jetpack吧! 1. 概念介绍 我们在本章回中介…

linux的shell script判断用户输入的字符串,判断主机端口开通情况

判断输入的字符串是否是hello 图一运行报错 检查发下,elif 判断里面少个引号,哎,现在小白到了,一看就会,一写就错的时候了,好像现在案例比较简单,行数较少。 案例二 if 结合test 判断主机端…

企业电脑屏幕监控有哪些?如何实现电脑屏幕监控

企业电脑屏幕监控有哪些?如何实现电脑屏幕监控 下载使用安企神电脑屏幕监控软件 企业电脑屏幕监控是一种监测和记录员工在工作时间内在他们的计算机上执行的活动的技术。这种监控可以有多种目的,包括确保员工的生产力、确保数据安全性,或满…

CCLINK IEFB总线转ETHERNET/IP网络的协议网关使欧姆龙和三菱的数据互通的简单配置方法

想要实现CCLINK IEFB总线和ETHERNET/IP网络的数据互通。 捷米JM-EIP-CCLKIE是一款ETHERNET/IP从站功能的通讯网关,该产品主要功能是实现CCLINK IEFB总线和ETHERNET/IP网络的数据互通。本网关连接到ETHERNET/IP总线和CCLINK IEFB总线上都可以做为从站使用。网关分别…

静态链表的定义与实现(数据结构与算法)

1. 静态链表 用数组的方式实现的链表 单链表: 各个结点在内存中星罗棋布、散落天涯 静态链表:分配一整片连续的内存空间, 各个结点集中安置。 1.1 静态链表的优点 不需要像动态链表那样频繁地进行内存分配和释放,可以节省内存…

产品手册应该如何组织内容,以便用户能够快速找到所需信息?

产品手册应该如何组织内容,以便用户能够快速找到所需信息?这是一个关乎用户体验和产品文档效力的重要问题。当用户需要了解产品的功能、操作指南或故障排除时,他们希望能够轻松地找到准确、清晰的信息,而不是在冗长的手册中迷失方…

C语言——选择排序

完整代码: //选择排序 // 选择排序是一种简单直观的排序算法。它的工作原理如下:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大&am…

Rocky 安装jdk17

1)检测jdk是否安装: #运行 java -version如果提示安装,则输入N,跳过 2)检测cpu 类型 若未安装查看linux处理器架构: #运行 hostnamectl #或运行 arch 3)去官网下载相应的编译版本的Jdk Or…

[SSD综述1.7] SSD接口形态: SATA、M.2、U.2、PCIe、BGA

依公知及经验整理,原创保护,禁止转载。 专栏 《SSD入门到精通系列》 <<<< 返回总目录 <<<< 前言 犹记得当年Windows 7系统体验指数中,那5.9分磁盘分数,在其余四项的7.9分面前,似乎已经告诉我们机械硬盘注定被时代淘汰。势如破竹的SSD固态硬盘,彻…

万岳讲堂:抖音小程序开发入门指南

抖音小程序可以将开发者的创意带入这个热门的应用中。本文将带您深入了解抖音小程序的开发入门指南&#xff0c;帮助您开始在这一平台上构建自己的应用。 一、什么是抖音小程序&#xff1f; 抖音小程序是一种轻量级的应用程序&#xff0c;它可以在抖音中直接运行&#xff0c;无…

记录腾讯云重置密码之后ssh就连不上的踩坑

腾讯云轻量级服务器SSH连不上 解决方案在最后&#xff0c;点我跳转 问题背景&#xff1a; 首先ssh ubuntu用户我是能用xshell带上密钥正常连接的 其次我重置了root密码&#xff0c;自己改了一个root密码&#xff0c;因为我要用root账号使用ftp传输文件 然后重置密码之后&…