做淘宝店铺装修的公司网站/国际热点事件
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍Ogg文件格式🍭
😎金句分享😎:🍭子曰:见贤思齐焉,见不贤而内自省也。——《论语·里仁篇》。意思是,看见德才兼备的人就向他学习,希望能向他看齐;看见不贤的人,就反省自己有没有和他一样的缺点,有要改正。🍭
文章未经允许,不许转载 !!!
opus、Ogg 相关文章:
1、RFC3533 :Ogg封装格式版本 0(The Ogg Encapsulation Format Version 0)
2、Ogg封装格式详解——包含Ogg封装过程、数据包(packet)、页(page)、段(segment)等
3、libogg库详解介绍以及使用——附带libogg库解析.opus文件的C源码
4、RFC7845:Opus音频编解码器的Ogg封装(Ogg Encapsulation for the Opus Audio Codec)
5、opus编解码库(opus-1.4)详细介绍以及使用——附带解码示例代码
6、opus编码的Ogg封装文件详解
目录
- 🎄一、Ogg 概述
- 🎄二、Ogg 支持的编码格式
- 🎄三、Ogg 基础知识
- ✨3.1 Ogg 相关术语
- ✨3.2 Ogg 物理比特流类型
- ✨3.3 Ogg 封装过程
- 🎄四、Ogg 文件结构
- ✨4.1 Ogg 页(page)格式
- ✨4.2 Ogg 封装文件解析
- 🎄五、读取Ogg文件的C语言代码
- 🎄六、总结
🎄一、Ogg 概述
Ogg
是一个自由且开放标准的多媒体文件格式,由Xiph.Org基金会所维护。Ogg格式并不受到软件专利的限制,并设计用于有效率地流媒体和处理高质量的数字多媒体。
与大多数容器格式一样,它封装了原始的压缩数据,并允许在一种方便的格式中交错存储音频和视频数据。
Ogg
这个词汇通常意指Ogg Vorbis
此一音频文件格式,也就是将Vorbis编码的音效包含在Ogg的容器中所成的格式。在以往,.ogg
此一扩展名曾经被用在任何Ogg支持格式下的内容,但在2007年,Xiph.Org
基金会为了向后兼容的考虑,提出请求,将.ogg
只留给Vorbis格式来使用。 Xiph.Org
基金会决定创造一些新的扩展名和媒体格式来描述不同类型的内容,像是只包含音效所用的.oga
,包含或不含声音的影片(涵盖 Theora)所用的.ogv
和程序所用的.ogx
。
更多关于Ogg的资料可以到Ogg官网学习:https://xiph.org/ogg/
描述Ogg封装格式的 RFC3533
文档:https://www.xiph.org/ogg/doc/rfc3533.txt 或 https://datatracker.ietf.org/doc/html/rfc3533
原文链接:https://blog.csdn.net/wkd_007/article/details/134150061
🎄二、Ogg 支持的编码格式
Ogg
意指一种文件格式,可以纳入各式各样自由和开放源代码的编解码器,包含音效、视频、文字(像字幕)与元数据的处理。
下面是Ogg支持的编码格式:
-
音频
- 有损
- Speex:以低比特率处理语音数据(〜2.1-32 kbit / s /通道)
- Vorbis:处理中高级可变比特率(每通道≈16-500kbit / s)的一般音频数据
- Opus:以低和高可变比特率处理语音,音乐和通用音频(每通道≈6-510kbit / s)
- 无损
- FLAC:处理文件和高保真音频数据。
- 未压缩
- OggPCM:处理未压缩的PCM音频。它与WAV大致相当[5]。
- 有损
-
视频
- 有损
- Theora:基于On2的VP3,它的目标是与MPEG-4视频(例如,使用DivX或Xvid编码),RealVideo或Windows Media Video进行竞争。
- Daala:正在开发的视频编码格式。
- Dirac:由BBC开发的免费开放视频格式。使用小波编码[6]。
- Tarkin:实验项目,现在过时的视频编解码器在2000年,2001年和2002年开发利用离散小波变换的三个维度的宽度,高度和时间。[7][8][9]。在Theora成为视频编码的主要焦点之后,已被搁置(2002年8月)[10]。
- 无损
- Dirac:Dirac规范的一部分涵盖无损压缩。
- Daala:正在开发的视频编码格式。
- 有损
-
文本
- Writ:用于嵌入字幕或字幕的文本编解码器的草稿不完整,于2007年停止[11]。
- CMML:用于定时元数据,字幕和格式的文本/应用编解码器。
- Annodex:CSIRO开发的免费开源标准,用于注释和索引网络媒体。
- OggKate:最初设计用于卡拉OK和文本的重叠编解码器,可以在Ogg中复用。
🎄三、Ogg 基础知识
✨3.1 Ogg 相关术语
- 物理比特流:Ogg封装的结果,被称为
物理(Ogg)比特流
,也就是说.ogg
文件属于一个物理比特流。 - 逻辑比特流:Ogg封装了一个或多个编码器创建的比特流,称为
逻辑比特流
,例如:Vorbis编码的流,Theora编码的流等。
每个逻辑比特流都以一个特殊的起始页(bos=beginning of stream)开始,并以一个特定的页(eos=end of stream)结束。 - 分包(packet):Ogg封装过程中,逻辑比特流会被拆分为一系列数据包(packet),它们不包含边界信息地串在一起。
- 页(page):页(page)是Ogg物理比特流的基本组成单位。Ogg比特流由一个个大小可变的页(page)组成,页的大小通常为4-8 kB,最大65307字节。
- 段(segments):由于页的最大大小约为64k字节,封装时有些数据包(packet)太大,需要存在几个页里。为了简化过程,Ogg将每个数据包划分为255字节长的块和最后一个较短的块,这些块被称为“Ogg段”(Ogg Segments)。假设一个数据包(packet)大小为520字节,那么它会被分成三个段,大小分别为:255字节、255字节、10字节。
(疑问:有没有可能有些数据包很小,使得一页中包含很多个数据包?)
✨3.2 Ogg 物理比特流类型
- 分组(Grouping):分组(Grouping)定义了如何在同一物理比特流中逐页交错多个逻辑比特流。例如,在同一比特流中将视频流和音频流交错存储。
- 链接(Chaining):完整的逻辑比特流被连接在一起。
看下图例子加深理解:在这个例子中,有两个链接的物理比特流,第一个是由三个逻辑比特流A、B和C组成的分组流。第二个物理比特流D链接在分组比特流的末尾之后,分组比特流在其所有分组逻辑比特流的最后一个eos页之后结束。
✨3.3 Ogg 封装过程
Ogg 封装过程:
1、编码器提供的比特流作为“分包”(Packets)移交给Ogg,分包边界(packet boundaries)取决于编码格式;
2、Ogg封装过程将数据包分割成若干段;
3、将一组连续的段(segments)包装成一个可变长度的页面(page);
4、最后将各个页(page)混合组成一个Ogg物理比特流。
上图是Ogg封装过程的例子:
- 1、编解码器提供的部分比特流细分为数据包。
- 2、Ogg封装过程将数据包分割成若干段。本例中的数据包相当大,因此数据包1被分为5个段,其中4个段有255个字节,最后一个较小。数据包2分为4个段,其中3个段有255个字节,最后一个非常小。数据包3分为两个段。
- 3、封装过程会创建页面,在本例中页面非常小。页面1由数据包1的前三个段组成,页面2包含数据包1中剩余的两个段,页面3包含数据包2的前三页。
- 4、最后,该逻辑比特流的页面和其他逻辑比特流页面被混合组成一个物理Ogg比特流。
🎄四、Ogg 文件结构
从上面内容可知,Ogg文件也属于一个物理比特流。是由一个个页(page)组成的。首先,我们要了解一个页的内容,然后找到Ogg文件的各个页就可以解析Ogg文件了。
✨4.1 Ogg 页(page)格式
Ogg的页(page)由页面头部(page header) 加上该页的各个段(segments)的数据组成。
页面头部(page header)中的9个字段具有以下含义:
-
1、capture_pattern:表示页面开始的4字节字段。它包含4个字符:
O
、g
、g
、S
。它可以帮助解码器找到页面边界,并在解析损坏的流后重新获得同步。一旦发现捕获模式,解码器就通过计算和比较校验和来验证页面同步和完整性。 -
2、stream_structure_version:1字节,表示该流中使用的Ogg文件格式的版本号(本文档指定版本0)。
-
3、header_type_flag:这1字节字段中的位标识该页面的特定类型。
- bit 0x01
- 被设置:页面包含从上一页继续的数据包的数据。
- 没设置: 页面包含新的数据包
- bit 0x02
- 被设置:这是逻辑比特流(bos)的第一页
- 没设置:此页面不是首页
- bit 0x04
- 被设置:这是逻辑比特流(eos)的最后一页
- 没设置:这一页不是最后一页
- bit 0x01
-
4、granule_position:包含位置信息的8字节字段。例如,对于音频流,它可能包含在包括此页面上完成的所有帧之后编码的PCM样本的总数。对于视频流,它可能包含在此页面之后编码的视频帧的总数。这是对解码器的提示,并给它一些定时和位置信息。其含义取决于该逻辑比特流的编解码器,并在特定媒体映射中指定。特殊值-1(以2的补码表示)表示此页上没有数据包结束。
-
5、bitstream_serial_number:包含唯一序列号的4字节字段,通过该唯一序列号来识别逻辑比特流。
-
6、page_sequence_number:包含页面序列号的4字节字段,使得解码器可以识别页面丢失。该序列号在每个逻辑比特流上分别增加。
-
7、CRC_checksum:包含页面的32位CRC校验和的4字节字段(包括具有零CRC字段的报头和页面内容)。生成多项式为0x04c11db7。
-
8、number_page_segments:1字节,给出分段表(segment table)中编码的分段条目的数量。
-
9、segment_table:大小为 number_page_segments 个字节。包含此页中所有段的lacing value。每个字节包含一个 lacing value。
以字节为单位的页面头部大小(total header size)由下式给出:
header_size = number_page_segments + 27 [Byte]
以字节为单位的总页面大小由下式给出:页面头部大小
+ 所有lacing_values值之和
page_size = header_size + sum(lacing_values: 1..number_page_segments)[Byte]
✨4.2 Ogg 封装文件解析
这里按照上面的页的格式,演示怎样解析一个Ogg封装的文件,文件可以在这个链接下载:https://download.csdn.net/download/wkd_007/88492683 。
用Notepad打开该文件并查看十六进制模式:
下面是文件第一页的数据:
- capture_pattern字段:值为
0x4f、0x67、0x67、0x53
,对应字符OggS
,表示页起始标志;- stream_structure_version字段:值为
0x00
,表示版本号;- header_type_flag字段:值为
0x02
,表示逻辑比特流(bos)的第一页;- granule_position字段:值为
0x0
,媒体编码相关的参数信息,表示到本页为止逻辑流有0个采样;- bitstream_serial_number字段:
0x23、0x49、0x02、0x11
,逻辑比特流序列号;- page_sequence_number字段:
0x00、0x00、0x00、0x00
,页面序列号;- CRC_checksum字段:
0xdf、0xe2、0x0c、0x1f
,32位CRC校验;- number_page_segments字段:
0x01
,表示后面段(segment)的个数,本页有1个段(segment);- segment_table:前面指明了只有1个段,所以segment_table大小为1个字节,值为
0x13
,表示这个段的大小为0x13
个字节。- 后面的0x13个字节就是段的内容(上图中浅蓝色背景的字节):
0x4f
开始到0x00
。
紧接着是第二页的数据:
- capture_pattern字段:值为
0x4f、0x67、0x67、0x53
,对应字符OggS
,表示页起始标志;- stream_structure_version字段:值为
0x00
,表示版本号;- header_type_flag字段:值为
0x00
,表示不是逻辑比特流(bos)的第一页,也不是最后一页,也不包含从上一页继续的数据包;- granule_position字段:值为
0x0
,媒体编码相关的参数信息,表示到本页为止逻辑流有0个采样;- bitstream_serial_number字段:
0x23、0x49、0x02、0x11
,逻辑比特流唯一序列号;- page_sequence_number字段:
0x01、0x00、0x00、0x00
,页面序列号;- CRC_checksum字段:
0xd4、0x3e、0x3f、0x20
,32位CRC校验;- number_page_segments字段:
0x03
,表示后面段(segment)的个数,本页有3个段(segment);- segment_table:前面指明了3个段,所以segment_table大小为3个字节,值为
0xff、0xff、0xfe
,表示这个3个段的大小分别为为0xff、0xff、0xfe
个字节。后面三个段的总字节数为:0xff+0xff+0xfe=0x2fc
字节。- 之后的
0x2fc
个字节就是三个段的内容(上图中浅蓝色背景的字节,没显示完整):0x4f
开始到0x00
。这里的起始地址是0x4d
,加上0x2fc
,就是下一页的地址0x349
。
紧接着是第三页的数据,起始地址是
0x349
:
- capture_pattern字段:值为
0x4f、0x67、0x67、0x53
,对应字符OggS
,表示页起始标志;- stream_structure_version字段:值为
0x00
,表示版本号;- header_type_flag字段:值为
0x00
,表示不是逻辑比特流(bos)的第一页,也不是最后一页,也不包含从上一页继续的数据包;- granule_position字段:值为
0x80、0xbb、0x0、0x0、0x0、0x0、0x0、0x0
,媒体编码相关的参数信息,小端表示到本页的逻辑流有48000
帧(小端0xbb80=48000);- bitstream_serial_number字段:
0x23、0x49、0x02、0x11
,逻辑比特流唯一序列号;- page_sequence_number字段:
0x02、0x00、0x00、0x00
,页面序列号;- CRC_checksum字段:
0x98、0x9d、0xc5、0x56
,32位CRC校验;- number_page_segments字段:
0x33
,表示后面段(segment)的个数,本页有51(0x33=51)个段(segment);- segment_table:前面指明了51个段,所以segment_table大小为51个字节,值分别为图中蓝色背景部分,每个字节表示各个段的大小。这51个字节的值相加就是后面51个段总字节数:0xff + 0x06 + 0xe5 + 0xab + 0xa2 + 0xa1 + 0xa5 + 0xa3 + 0xdf + 0xab + 0xa7 + 0xa1 + 0xa3 + 0x9d + 0xec + 0xe0 + 0xa4 + 0x9e + 0xb3 + 0xa6 + 0xbe + 0xb8 + 0xb4 + 0xaa + 0xa3 + 0xa2 + 0xa4 + 0x99 + 0x9f + 0x9c + 0x96 + 0x94 + 0x94 + 0x97 + 0x99 + 0x9a + 0xa1 + 0x9e + 0xa0 + 0xa6 + 0xa1 + 0xa0 + 0xaa + 0xa9 + 0xac + 0xa4 + 0xa6 + 0x9d + 0x9a + 0x94 + 0x98 =
8484
个字节;- 之后的
8484
个字节就是51个段的内容。第一个段的起始地址是0x397
,加上8484
,就是下一页的地址0x24bb
。
紧接着是第四页的数据,起始地址是
0x24bb
:
- capture_pattern字段:值为
0x4f、0x67、0x67、0x53
,对应字符OggS
,表示页起始标志;- stream_structure_version字段:值为
0x00
,表示版本号;- header_type_flag字段:值为
0x00
,表示不是逻辑比特流(bos)的第一页,也不是最后一页,也不包含从上一页继续的数据包;- granule_position字段:值为
0x00、0x77、0x01、0x0、0x0、0x0、0x0、0x0
,媒体编码相关的参数信息,小端表示到本页的逻辑流有96000
帧(小端0x017700=96000);- bitstream_serial_number字段:
0x23、0x49、0x02、0x11
,逻辑比特流唯一序列号;- page_sequence_number字段:
0x03、0x00、0x00、0x00
,页面序列号;- CRC_checksum字段:
0x25、0x80、0xd7、0x7d
,32位CRC校验;- number_page_segments字段:
0x32
,表示后面段(segment)的个数,本页有50(0x32=51)个段(segment);- segment_table:前面指明了50个段,所以segment_table大小为50个字节,值分别为图中蓝色背景部分,每个字节表示各个段的大小。这50个字节的值相加就是后面50个段总字节数,这里不计算了,感兴趣自己算。
- 之后的若干个字节就是50个段的内容。
这里解析了4页,后面的页数依次类推去分析,这个文件有118页,最后一页的话,其header_type_flag字段值为0x04。
🎄五、读取Ogg文件的C语言代码
// readOggFile.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 8字节数组转成 unsigned long long
unsigned long long ToULL(unsigned char num[8], int len)
{unsigned long long ret = 0;if(len==8){ int i=0;for(i=0; i<len; i++){ret |= ((unsigned long long)num[i] << (i*8));}}return ret;
}// 4字节数组转成 unsigned int
unsigned int ToUInt(unsigned char num[4], int len)
{unsigned int ret = 0;if(len==4){int i=0;for(i=0; i<len; i++){ret |= ((unsigned int)num[i] << (i*8));}}return ret;
}int readOggPage(char *oggFile)
{typedef struct PAGE_HEADER{ char Oggs[4]; unsigned char ver;unsigned char header_type_flag;unsigned char granule_position[8];unsigned char stream_serial_num[4];unsigned char page_sequence_number[4];unsigned char CRC_checksum[4];unsigned char seg_num;unsigned char segment_table[];}PAGE_HEADER;FILE *fp=fopen(oggFile,"rb");while(!feof(fp)){// 1、读取 page_headerPAGE_HEADER page_header;if(1 != fread(&page_header,sizeof(page_header),1,fp))break;printf("page_num:%03u; ",ToUInt(page_header.page_sequence_number, 4));printf("Oggs:%c %c %c %c; ",page_header.Oggs[0],page_header.Oggs[1],page_header.Oggs[2],page_header.Oggs[3]);printf("type=%d, granule_position:%08llu; ", page_header.header_type_flag,ToULL(page_header.granule_position, 8));//printf("seg_num:%d \n",page_header.seg_num);// 2、读取 Segment_tableunsigned char *pSegment_table = (unsigned char *)malloc(page_header.seg_num);fread(pSegment_table,sizeof(unsigned char),page_header.seg_num,fp);// 3、计算段数据总大小unsigned int TotalSegSize = 0;int i=0;for(i=0; i<page_header.seg_num; i++){TotalSegSize += pSegment_table[i];}printf("TotalSegSize:%d \n",TotalSegSize);// 4、读取段数据unsigned char *pSegment_data = (unsigned char *)malloc(TotalSegSize);fread(pSegment_data,sizeof(unsigned char),TotalSegSize,fp);if(page_header.header_type_flag == 4)printf("Last 4 Byte: %x %x %x %x\n",pSegment_data[TotalSegSize-4],pSegment_data[TotalSegSize-3], pSegment_data[TotalSegSize-2],pSegment_data[TotalSegSize-1]);free(pSegment_data);free(pSegment_table);}fclose(fp);return 0;
}int main()
{readOggPage("48000Hz-s16le-1ch-ChengDu.opus");return 0;
}
🎄六、总结
本文介绍了Ogg支持的编码格式,Ogg的封装过程,Ogg文件结构,以及Ogg的相关术语(物理比特流、逻辑比特流、数据包(packet)、页(page)、段(segment) )等内容。
最后,似乎有点问题,文章只讲了Ogg文件结构和页头部数据,并没有解析各个段的内容。因为段的内容是根据编码不同而变化的,需要再了解跟编码相关的文档如:opus音频编解码器的Ogg封装。这些内容后面单独去分析。
这两天发现了查看RFC文档的一个网址:https://datatracker.ietf.org/,只需要搜索想看的RFC文档,基本都可以搜到。
https://datatracker.ietf.org/doc/rfc7845/,显示格式是标题栏在上面;
https://datatracker.ietf.org/doc/html/rfc7845/,显示格式是标题栏在侧边,个人比较喜欢这个风格。
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁
参考文档:
rfc3533:https://datatracker.ietf.org/doc/html/rfc3533
Opus从入门到精通(五)OggOpus封装器全解析:https://juejin.cn/post/6844904016254599175
https://www.cnblogs.com/dylancao/p/8303418.html
https://blog.csdn.net/zyx4843/article/details/51439279
相关文章:

【音视频 | Ogg】Ogg封装格式详解——包含Ogg封装过程、数据包(packet)、页(page)、段(segment)等
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...

ubuntu 22.04 安装ros2 iron
目录 一、镜像 二、ifconfig 三、ssh连接不上 四、安装iron 一、镜像 123云盘直接下载 二、ifconfig sudo apt install net-tools 三、ssh连接不上 sudo apt install openssh-server 四、安装iron Ubuntu (Debian packages) — ROS 2 Documentation: Iron document…...

PHP语言、B/S手术麻醉临床信息管理系统源码
手术麻醉临床信息管理系统有着完善的临床业务功能,能够涵盖整个围术期的工作,能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施,能够规范麻醉科的工作流程,实现麻醉手术过程的信息数字化,自动生…...

Win11安装网络打印机
https://support.microsoft.com/zh-cn/windows/%E5%9C%A8-windows-%E4%B8%AD%E5%AE%89%E8%A3%85%E6%89%93%E5%8D%B0%E6%9C%BA-cc0724cf-793e-3542-d1ff-727e4978638b...

逆向学习记录(3)工具介绍jadx、gda和jeb
1、jadx 下载地址如下,目前最新版本为v1.4.7,改成想要下载的版本号就能下载对应的版本。 https://github.com/skylot/jadx/releases/tag/v1.4.7 下载后解压,进入对应路径的bin文件夹内,运行jadx-gui.bat。 2、gda 下载地址和gi…...

C#,数值计算——偏微分方程,Mglin的计算方法与源程序
1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Mglin { private int n { get; set; } private int ng { get; set; } private double[,] uj1 { get; set; } private Lis…...

一机服务万人,拓世法宝AI智能商业数字人一体机,解锁文旅新表达
在人工智能的强劲推动下,人们走进了一个令人振奋的数字化时代。如何让文化传承与现代科技完美融合,成为一个十分有趣的议题,当AI技术结合文旅生活,便悄然开启了一种全新的旅游服务模式——AI数字文旅。 在我国国家博物馆、文旅大…...

【源码解析】聊聊SpringBean是如何初始化和创建
我们知道通过类进行修复不同的属性,比如单例、原型等,而具体的流程是怎么样的呢,这一篇我们开始从源码的视角分析以下。 刷新方法 在刷新容器中有一个方法,其实就是 Bean创建的过程。 finishBeanFactoryInitialization(beanFact…...

【0基础学Java第六课】-- 数组的定义与使用
6 数组的定义与使用 6.1 什么是数组6.2 数组的创建及初始化6.2.1 数组的创建:6.2.2 数组的初始化 6.3 数组的使用6.3.1 数组中元素的访问6.3.2 Java中JVM当中的内存划分6.3.3 遍历数组 6.4 数组是引用类型6.4.1 初始JVM的内存分布6.4.2 基本类型变量与引用类型变量的…...

后台项目Gradle打包jar,不包含依赖jar并放到外部路径
# 1.Gradle打包jar # 2.依赖jar包外放到其他目录 # 3.保留引用关系 # 4.去掉引入的缓存build.gradle// 需要放到dependencies下面 // 傻逼问题 1 这个jar打包还得主动开 jar.enabled true // 1.清除上一次的lib目录 task clearJar(type: Delete) {delete "$buildDir\\lib…...

NSSCTF web刷题记录4
文章目录 [NSSRound#4 SWPU]1zweb(revenge)[强网杯 2019]高明的黑客[BJDCTF 2020]Cookie is so subtle![MoeCTF 2021]fake game[第五空间 2021]PNG图片转换器[ASIS 2019]Unicorn shop[justCTF 2020]gofs[UUCTF 2022 新生赛]phonecode[b01lers 2020]Life On Mars[HZNUCTF 2023 f…...

什么是大模型?一文读懂大模型的基本概念
大模型是指具有大规模参数和复杂计算结构的机器学习模型。本文从大模型的基本概念出发,对大模型领域容易混淆的相关概念进行区分,并就大模型的发展历程、特点和分类、泛化与微调进行了详细解读,供大家在了解大模型基本知识的过程中起到一定参…...

数据结构之队的实现
𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…...

【实战Flask API项目指南】之三 路由和视图函数
实战Flask API项目指南之 路由和视图函数 本系列文章将带你深入探索实战Flask API项目指南,通过跟随小菜的学习之旅,你将逐步掌握 Flask 在实际项目中的应用。让我们一起踏上这个精彩的学习之旅吧! 前言 当小菜踏入Flask后端开发的世界时&…...

mediasoup udp端口分配策略
mediasoup-worker多进程启动时,rtcMinPort/rtcMaxPort可以使用相同的配置。 for (let i 0; i < numWorkers; i) { let worker await mediasoup.createWorker({ logLevel: config.mediasoup.worker.logLevel, logTags: config.mediasoup.work…...

山西电力市场日前价格预测【2023-11-07】
日前价格预测 预测说明: 如上图所示,预测明日(2023-11-07)山西电力市场全天平均日前电价为318.54元/MWh。其中,最高日前电价为514.01元/MWh,预计出现在18: 00。最低日前电价为192.95元/MWh,预计…...

Microsoft Dynamics 365 CE 扩展定制 - 5. 外部集成
本章内容包括: 使用.NET从其他系统连接到Dynamics 365使用OData(Java)从其他系统连接到Dynamics 365使用外部库从外部源检索数据使用web应用程序连接到Dynamics 365运行Azure计划任务设置Azure Service Bus终结点与Azure Service Bus构建近乎实时的集成使用来自Azure服务总线…...

手机升级STM32单片机,pad下载程序,手机固件升级单片机,局域网程序下载,STM32单片机远程下载升级
STM32单片机,是我们最常见的一种MCU。通常我们在使用STM32单片机都会遇到程序在线升级下载的问题。 STM32单片机的在线下载通常需要以下几种方式完成: 1、使用ST提供的串口下载工具,本地完成固件的升级下载。 2、自行完成系统BootLoader的编写…...

【漏洞复现】weblogic-SSRF漏洞
感谢互联网提供分享知识与智慧,在法治的社会里,请遵守有关法律法规 文章目录 漏洞测试注入HTTP头,利用Redis反弹shell 问题解决 Path : vulhub/weblogic/ssrf 编译及启动测试环境 docker compose up -dWeblogic中存在一个SSRF漏洞࿰…...

FreeSWTCH dialplan check nosdp
应朋友要求写一段dialplan,如果没有sdp(sip_profile打开了3pcc),马上回486,当然如果有sdp,dialplan正常往下走 我试了试,貌似不太复杂,如下: <!-- check no sdp --&…...

微信小程序案例3-1 比较数字
文章目录 一、运行效果二、知识储备(一)Page()函数(二)数据绑定(三)事件绑定(四)事件对象(五)this关键字(六)setData()方法࿰…...

哈希表----数据结构
引入 如果你是一个队伍的队长,现在有 24 个队员,需要将他们分成 6 组,你会怎么分?其实有一种方法是让所有人排成一排,然后从队头开始报数,报的数字就是编号。当所有人都报完数后,这 24 人也被分…...

可达矩阵-邻接矩阵-以及有向图的python绘制
参考1 自定义输入矩阵来绘制 根据参考代码, 自定义 代码如下: # 编程实现有向图连通性的判断 from pylab import mplmpl.rcParams[font.sans-serif] [SimHei] mpl.rcParams[axes.unicode_minus] False import numpy as np import networkx as nx imp…...

react typescript @别名的使用
1、config/webpack.config.js中找到alias,添加: path.resolve(src) ,如下: alias: {// Support React Native Web// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/"react-native&qu…...

C++性能优化笔记-6-C++元素的效率差异-7-类型转换
C元素的效率差异 类型转换signed与unsigned转换整数大小转换浮点精度转换整数到浮点转换浮点到整数转换指针类型转换重新解释对象的类型const_caststatic_castreinterpret_castdynamic_cast转换类对象 类型转换 在C语法中,有几种方式进行类型转换: // …...

c#中switch常用模式
声明模式 首先检查value的类型,然后根据类型输出相应的消息 public void ShowMessage(object value) {switch (value){case int i: Console.WriteLine($"value is int:{i}"); break;case long l: Console.WriteLine($"value is long:{l}"); b…...

Flink SQL 常用作业sql
目录 flink sql常用配置kafka source to mysql sink窗口函数 开窗datagen 自动生成数据表tumble 滚动窗口hop 滑动窗口cumulate 累积窗口 grouping sets 多维分析over 函数TopN flink sql常用配置 设置输出结果格式 SET sql-client.execution.result-modetableau;kafka source…...

nodejs国内镜像及切换版本工具nvm
淘宝 NPM 镜像站(http://npm.taobao.org)已更换域名,新域名: Web 站点:https://npmmirror.com Registry Endpoint:https://registry.npmmirror.com 详见: 【望周知】淘宝 NPM 镜像换域名了&…...

用Rust和Scraper库编写图像爬虫的建议
本文提供一些有关如何使用Rust和Scraper库编写图像爬虫的一般建议: 1、首先,你需要安装Rust和Scraper库。你可以通过Rustup或Cargo来安装Rust,然后使用Cargo来安装Scraper库。 2、然后,你可以使用Scraper库的Crawler类来创建一个…...

Java 语言环境搭建
JDK 是一种用于构建在 Java 平台上发布的应用程序、Applet 和组件的开发环境,即编写 Java 程序必须使用 JDK,它提供了编译和运行 Java 程序的环境。 在安装 JDK 之前,首先要到 Oracle 网站获取 JDK 安装包。JDK 安装包被集成在 Java SE 中&a…...