项目简介

OBS - Free and open source software for live streaming and screen recording(OBS是一款开源的用于录屏直播的工具软件)。

旧版的OBS只能支持Windows,目前已经停止开发。作者为了支持Windows/Mac/Linux重写了整个软件,项目地址为obs-studio in Github。

新版的OBS的目标有以下几点:

  1. Make it multiplatform.(跨平台支持)
  2. Separate the application from the core, allowing custom application of the core if desired, and easier extending of the user interface.(模块化、易扩展)
  3. Simplify complex systems to not only make it easier to use, but easier to maintain.(简化系统,使其易用易维护)
  4. Make a better/cleaner code base, use better coding standards, use standard libraries where possible (not just STL and C standard library, but also things like ffmpeg as well), and improve maintainability of the project as a whole.(尽量利用其他开源软件成果)
  5. Implement a new API-independent shader/effect system allowing better and easier shaders usage and customization without having to duplicate shader code.(实现独立于API的shader/effect系统)
  6. Better device support. (更好的支持有录屏需求的设备)

OBS项目的语言分布:

  1. C: 57.6%
  2. C++: 36.3%
  3. Objective-C/Objective-C++: 4%
  4. others: 3%

OBS代码主要包含这些部分:

  1. libobs: 核心代码,定义项目框架以及核心API,主要用C语言编写。
  2. UI: 界面代码,采用C++的QT框架,开发出适用三大平台的界面。
  3. plugins: 插件代码,可独立编译成dll(windows平台)或so(*nix平台),包含Source(录屏输入源)、Output、Service(各种流播服务)等全部被定义为插件。
  4. libobs-d3d11: 基于D3D的图形子系统,主要用在Windows系统。
  5. libobs-opengl: 基于opengl的图形子系统,主要用在*uix系统。

OBS软件功能概述

OBS项目工程中以场景组的方式呈现给用户,可以自由设置场景、输入源、效果处理,配置直播服务。

OBS项目工程结构

OBS项目中一个工程结构如下

一个场景组包含多个场景,OBS直播的时候是把整个场景流播给用户,那为什么需要多个场景?因为播主在直播时有快速切换场景的需要,所以播主需要在直播前编辑好多个场景(比如纯游戏场景;游戏+头像;解说;休息场景等),然后直播的过程中可以根据不同的需要快速切换。

OBS场景的转场

OBS中的转场,是场景切换时的动画效果,目前支持 Fade和Switch等多种效果。

OBS输入源的种类

一个场景可以包含多个输入源,一个直播工具可以支持的输入源种类反应了其强大性。OBS支持 输入源种类如下

OBS输入源的效果设置

针对每个输入源可以增加各种滤镜效果,以下列出我觉得最实用的几种:

  1. 音频效果:

    1. Video Delay: 设置延迟时间,用来处理音视频不同步的的场景。
    2. Noise Suppression: 噪音抑制
    3. Gain: 音频增益
    4. Noise Gate: 噪声门,把小噪音去掉
  2. 视频效果:
    1. Crop: 就是最实用的Crop,不过OBS里不能用鼠标拖拽来控制Crop区域,略显不便
    2. Chroma Key: 如果有绿幕背景,可以用来去背景,在摄像头的输入源中最常用。
    3. Image Mask: 打水印
    4. Scroll: 滚动效果,在一些浏览器的输入源上最实用。

OBS工作室模式


左边是预览界面,可以进行编辑。右边是正在直播的界面。中间是把预览界面切到直播界面的各种转场效果。

一般比较专业的直播都是使用这个模式,可以在预览界面编辑好画面之后再推送到直播画面。

OBS插件系统

OBS项目中把除了核心框架以及渲染系统之外的 部件全部抽象成了Module,一个或多个Module最后封装到插件中(以dll或so的形式),只要把插件放入特定的目录即可被主程序使用。

Mac版OBS的插件目录在/Applications/OBS.app/Contents/Resources/obs-plugins,其中

  1. mac-avcapture.so 对应Mac的视频捕获设备
  2. mac-capture.so 对应屏幕捕获 和 窗口捕获
  3. mac-syphon.so 对应注入捕获游戏画面

OBS插件定义

一个典型的OBS插件代码包含三个部分:

  1. 插件定义 -> plugin-main.c
  2. 编译打包 -> CMakeList.txt
  3. 内部实现代码 -> XX.c/YY.c …

下面以mac-capture.so插件为例来看看它的插件定义代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <obs-module.h>OBS_DECLARE_MODULE()
OBS_MODULE_USE_DEFAULT_LOCALE("mac-capture", "en-US") //多语言支持extern struct obs_source_info coreaudio_input_capture_info; //输入源1
extern struct obs_source_info coreaudio_output_capture_info;//输入源2
extern struct obs_source_info display_capture_info;//输入源3
extern struct obs_source_info window_capture_info;//输入源4bool obs_module_load(void) //注册支持的输入源
{obs_register_source(&coreaudio_input_capture_info);obs_register_source(&coreaudio_output_capture_info);obs_register_source(&display_capture_info);obs_register_source(&window_capture_info);return true;
}

可以看出这个插件定义了四个输入源,这里你可能有个疑问,为什么不是一个插件 对应 一个输入源,因为功能相近的输入源集成到一个插件里可以减少冗余代码。

所以OBS中插件可以定义为 包含 一个 或 多个 输入(或 输出/编码/服务)模块的动态库代码。

任意一个开源库比如FFmpeg,经过OBS统一的接口定义封装即可编译成OBS的一个插件为OBS系统所用。

OBS插件加载流程

插件系统大体都有一个类似的套路,OBS的也不例外。简单来说就是定义插件存放在特定目录,在程序启动时,动态加载所有的插件(存储为对象或一系列函数指针),存储在字典 或者 链表这样的数据结构里。

下面来详细分析一下OBS中插件加载流程:

然后以mac-capture.so中的display_capture_info,来看看它的结构定义,可以看出它主要定义了id、type、name 以及一些接口API。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct obs_source_info display_capture_info = {.id             = "display_capture",.type           = OBS_SOURCE_TYPE_INPUT,.get_name       = display_capture_getname,.create         = display_capture_create,.destroy        = display_capture_destroy,.output_flags   = OBS_SOURCE_VIDEO | OBS_SOURCE_CUSTOM_DRAW |OBS_SOURCE_DO_NOT_DUPLICATE,.video_tick     = display_capture_video_tick,.video_render   = display_capture_video_render,.get_width      = display_capture_getwidth,.get_height     = display_capture_getheight,.get_defaults   = display_capture_defaults,.get_properties = display_capture_properties,.update         = display_capture_update,
};

其中需要注意一下get_properties这个接口,这个接口是干啥用的?顾名思义是获取模块的属性数据,按我的理解 UI层可以利用这个属性数据来构建这个模块对应的界面,并设置这个模块的属性参数。

OBS视频处理流程

视频渲染输出流程

OBS视频渲染和输出是系统的核心流程,我们以Mac桌面录制输入,以及ffmpeg输出为例来分析一下整个流程(多路输入 和 多路输出道理也是类似的), 图中为了简单起见忽略了输出编码流程仅包含非编码流程。

可以看出OBS创建了两个线程,一个用于显示渲染,另一个用于编码输出。
渲染部分最终调用的是 输入模块里的渲染代码,而编码输出部分最终也是调用 输出模块的代码。

另外在渲染线程中 也负责把图形系统的数据 拷贝到 输出数据的缓存中,以便于输出线程进行处理

视频输出数据结构分析

OBS的核心数据结构定义在libobs/obs-internal.h中 主体结构为obs_core如下图所示(仅保留的主要的数据结构)

右下方的video(结构为video_output)用在输出模块的raw_video接口进行处理,把 输出数据中的cache转成实际的输出,以下是video_output详细数据结构:

OBS音频处理流程

OBS音频处理是在一个线程中完成了先渲染后输出的过程。而视频处理则是 分别开了渲染线程 和 输出线程。

具体流程如下, 在输出函数中在判断是否需要编码,再调用对应的非编码流程 或 编码流程:

OBS图形系统架构

OBS的图形系统主要负责 场景的渲染、场景的切换、以及各种输入源的音视频效果的处理,属于OBS的核心之一。
通过使用软件以及视频渲染流程的分析 得到OBS图形系统的大体的逻辑关系。

针对图形系统主要分析以下三个问题:

  1. 多滤镜叠加的渲染处理。
  2. 滤镜和转场效果的实现与集成。
  3. 图形API的封装。

单个场景的渲染流程

场景(Scene)也被封装成输入源(Source)的一种,所以UI层只要把当前的场景取出来,调用它的obs_source_video_render即可。

在场景内部会渲染其包含的renderitem(也就是实际的输入源),比如前一个图所展示的游戏录制、桌面录制输入源等。

多个滤镜叠加的输入源渲染流程

这部分分析了很长时间一直没看懂,主要有两个原因:

  1. 之前不熟悉OpenGl的渲染流程,所以搞不懂滤镜的渲染流程。
  2. 这部分的逻辑比较绕,没分析出多个滤镜是怎么叠加渲染的。

前段时间花了点时间好好学习了一下OpenGl(仅仅学习和音视频处理相关的章节),写了一些demo。

现在再来分析这部分相对轻松一些,简述一下:当渲染带滤镜的输入源时,会先渲染它最后一个滤镜,然后在这个滤镜的渲染代码又会调用渲染前一个滤镜,最后调用第一个滤镜的渲染代码。

在第一个滤镜的渲染代码里 直接渲染 调用输入源的渲染流程,然后生成texture。

每个滤镜都在前一个滤镜渲染生成的texture的基础渲染生成新的texture。

流程图如下:

滤镜和转场效果的实现与集成

OBS项目中,滤镜和转场效果都被抽象成插件。

以Mac版OBS为例:

  1. 所有的滤镜都在obs-filters.so这个插件里;
  2. 所有的转场效果都在obs-transitions.so里;

滤镜和转场其实分析起来是类似的,所以后续的暂时以滤镜为例来加以说明。

首先如果滤镜个数太多,拆分到两个插件里是没问题的。不过OBS项目中全部集中在一个插件里。

每个滤镜其实都被定义成了输入模块,以obs_source_info定义暴露API,以crop_filter为例见如下定义,唯一和普通输入模块不同的是类型定义(.type)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct obs_source_info crop_filter = {.id                            = "crop_filter",.type                          = OBS_SOURCE_TYPE_FILTER,.output_flags                  = OBS_SOURCE_VIDEO,.get_name                      = crop_filter_get_name,.create                        = crop_filter_create,.destroy                       = crop_filter_destroy,.update                        = crop_filter_update,.get_properties                = crop_filter_properties,.get_defaults                  = crop_filter_defaults,.video_tick                    = crop_filter_tick,.video_render                  = crop_filter_render,.get_width                     = crop_filter_width,.get_height                    = crop_filter_height
};

细心观察每个滤镜的代码组成发现都是一个套路,主要由两部分组成:

  1. XXX.c (C代码,用于暴露API以及例行处理)
  2. XXX.effect (自定义文件,实际效果处理逻辑)

关于这个effect留到后续讲解。

看到这里得出一个结论,OBS项目要增加新的滤镜效果只要编写对应的XXX.c 和 XXX.effect,放到对应的插件以输入模块的API暴露出来,并注册就可以了。

图形API的封装处理

目前OBS系统的图形API包括OpenGl以及d3d11:

  1. 在图形库加载层利用了Multi-Language GL/GLES/EGL/GLX/WGL Loader-Generator对不同平台加载图形库代码进行了封装。
  2. 在API调用层面也进行了抽象统一,具体可以查看 libobs/graphics/graphics-imports.c的定义。
  3. 自定义了效果描述文件 XXX.effect,这样就不用针对OpenGl和d3d11写两遍Shader。

我们以chroma-key-filter为例分析一下它的创建流程:

  1. 其中AddNewFilter是在界面中触发的添加效果的功能。
  2. ep_parse把xxx.effect配置文件解析成对应的配置结构。
  3. ep_compile把对应的配置结构解析 效果数据结构。

effect文件的作用可以参考程序中的注释

1
2
3
4
5
6
7
8
9
10
/** Effects introduce a means of bundling together shader text into one* file with shared functions and parameters.  This is done because often* shaders must be duplicated when you need to alter minor aspects of the code* that cannot be done via constants.  Effects allow developers to easily* switch shaders and set constants that can be used between shaders.** Effects are built via the effect parser, and shaders are automatically* generated for each technique's pass.*/

effect文件包括这几个部分:

pass对应 vertex_shader 和 pixel_shader

technique 对应一个具体效果的渲染设置,包含多个pass

effect文件包含多个technique渲染设置、可以共享文件中的参数和函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SolidVertInOut VSSolid(SolidVertInOut vert_in)
{SolidVertInOut vert_out;vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);return vert_out;
}float4 PSSolid(SolidVertInOut vert_in) : TARGET
{return color;
}technique Solid
{pass{vertex_shader = VSSolid(vert_in);pixel_shader  = PSSolid(vert_in);}
}

effect文件支持基本的C语法,支持宏定义和include包含其他文件,由libobs/util中的cf-lexer.c和cf-parser.c提供解析支持。

支持OBS插件

OBS的插件是在OBS项目定义的比较宽泛,插件的范畴包括 整个录屏、处理、推流 中的各个功能模块.

如果我们的软件中可以直接支持OBS插件,就可以节省大量的开发、测试的时间。但由于我们的程序框架和OBS的完全不同,要如何支持OBS项目的插件呢?

想了两种方法,并尝试分析一下优缺点。

支持OBS的方法分析

二进制级别的支持

顾名思义,就是把OBS的插件直接放到我们程序的相应目录就可以用。这种方式下维护、更新、新增 OBS插件 代价是最小的。也是我心中理想的支持方式。

但是以这种方式支持的遇到较大困难。先看OBS项目中的代码的各个模块:

  1. libobs: 核心代码,定义项目框架以及核心API,主要用C语言编写。
  2. UI: 界面代码,采用C++的QT框架,开发出适用三大平台的界面。
  3. plugins: 插件代码,可独立编译成dll(windows平台)或so(*nix平台),包含Source(录屏输入源)、Output、Service(各种流播服务)等全部被定义为插件。
  4. libobs-d3d11: 基于D3D的图形子系统,主要用在Windows系统。
  5. libobs-opengl: 基于opengl的图形子系统,主要用在*uix系统。

我们想要支持plugins中的插件,

但是plugins中的插件要依赖libobs,

而libobs又要依赖libobs-opengl 和 QT界面库。

也就是除非 我们的项目支持基于OBS项目改写,否则这种支持方式的不太现实。

代码级别的支持

这是退而求其次的方式,简单的说就是把OBS的插件代码扣出来,确保其不依赖于libobs,然后集成我们的项目中。这种方式每支持一个插件都存在集成的工作量,也可能会引入Bug,不过不失为一个较为可行的方案。

OBS项目编译

尝试了在Mac平台上编译OBS项目,还比较顺利。具体可以参考install help

有个小问题,在cmake后报错提示无法找到QT5的cmake模块。需要给cmake指定一下QT5的安装目录,以我的安装目录为例,命令如下:

1
cmake .. -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.3.1/

cmake命令我是不熟悉的,不过看了这篇文章也基本懂了。

OBS项目最后的编译结果如下:

主要有三个目录:

  1. bin: 主程序
  2. data: 国际化资源 以及 视频effect效果资源
  3. obs-plugin: 插件编译结果

使用otool -L分析中其中主要动态库和插件(仅以mac-capture为例)的依赖关系如下:

前面在代码层面分析直接二进制支持OBS插件感觉很困难。但这里基于编译后的动态库依赖关系分析好像又有一定可行性。我们把mac-capture.so、libobs.0.dylib、ffmpeg独立出来,去掉OBS主程序和QT等库,自己写代码来调用libobs.0.dylib提供的功能,以此直接支持OBS的插件。

后续进行完相关的实验,看看到底是否可行,再来补充。

模块列表

OBS项目中类型为OBS_SOURCE_TYPE_INPUT是我们可以考虑优先支持的模块。以下是功能说明。

插件 子模块 功能描述
mac-capture coreaudio_input_capture 音频输入获取
  coreaudio_output_capture  
  display_capture 桌面获取
  window_capture 窗体获取
mac-avcapture av_capture 摄像头获取
mac-syphon syphon 程序注入获取界面
obs-ffmpeg ffmpeg_source ffmpeg输入源
obs-browser browser_source 浏览器输入
text-freetype2 freetype2_source text输入
decklink decklink-input  
image-source image_source 图片输入
  slideshow  
vlc-video vlc_source vlc输入

mac-syphon插件分析

mac-syphon是OBS项目中用于获取游戏画面(仅用于mac平台)的插件,十分重要。下面来分析一下它的实现原理。

首先mac-syphon是OBS的输入源插件,所以遵循OBS的插件API设定,具体可以查看OBS插件分析章节的介绍。
mac-syphon内部其实组合了多个开源项目功能来完成:获取游戏画面,并展示到OBS界面上的功能。

我们以OBS获取MineCraft这个游戏的画面为例,来看一张总的实现原理图:

简单解释一下这个过程:

注入游戏进程的方法这里用的是Scripting Additions的方式,这是macOS独有的技术,windows上肯定要用其他方式,到时候再单独研究。除了注入方式的区别,其他流程Win和Mac平台应该类似的。

另外由于注入的函数中替换的是OpenGL的渲染API,所以这个插件支持的游戏必然是使用OpenGL渲染的。假如某个程序或游戏不使用OpenGL则无法注入。

ScriptingAdditions

ScriptingAdditions就是macOS中Applescript中一个技术,不太好解释,反正它的作用就是帮助注入到游戏进程里,直接上两个文档:

  1. Scripting Additions for Mac OS X
  2. Open Scripting Architecture

mach_override

这里其实利用了两个项目jrswizzle和mach_override,功能就是把游戏进程中的flushBuffer替换为自己写的flushBufferSyphon,把orig_CGLFlushDrawable替换为CGLFlushDrawableOverride,从而实现把自己写的功能注入到游戏的渲染API中。

Syphon

Syphon项目是一套传输图形画面的Client/Server框架。

项目还提供了Client/Server Demo可以很方便的测试画面传输的功能。

Syphon Inject

SyphonInject项目组合Syphon的功能以及注入游戏的功能,提供了一个Demo。

下图中我用Syphon Inject注入到Dota2游戏,然后把界面传送给Client Demo。

SyphonInject编译注意事项: SyphonInject项目早期利用mach_inject项目进行注入,后期已经修改为ScriptingAdditions方式注入。最新的代码没有依赖mach_inject,所以可以把mach_inject项目依赖去掉再编译。

最后OBS项目其实上述项目组合,用插件的API包装成了mac-Syphon插件。

mac-capture插件分析

mac-capture插件是OBS项目中对应mac平台的 屏幕界面获取、窗口界面获取、输入音频获取、输出音频获取 四大模块的具体实现。

obs模块的具体结构和API不再列出,详细情况可查看之前的文档,这里着重分析模块内部的功能实现。

mac-display模块

主要利用Quartz Display Services获取界面图像数据转换成texuture提供给主程序。

其中调用CGDisplayStreamCreateWithDispatchQueue接口获取的显示界面图像数据,数据结构是IOSurfaceRef。具体用法可以查看上述Quartz Display Services链接文档。

主要的实现流程如下图:

mac-window-capture模块

获取其他程序窗体界面的模块,也是利用了Quartz Display Services。

使用CGWindowListCreateImage接口,通过windowID把对应程序的界面以 CGImage 的形式返回,直接放到输出的Cache里。

这里有个疑问,模块没有实现.video_render这个渲染API。可能和模块的output_flags设置的是异步有关。
OBS_SOURCE_ASYNC_VIDEO异步的渲染流程可能未放到模块内部实现。

mac-audio模块

音频模块包括两个,音频输入模块 和 音频输出模块。

音频输入设备比如 iMac上自带的外置麦克风;音频输出模块 比如 插入的耳机等。

由于mac平台限制,无法直接录制 音频输出设备的声音。比如我要录制浏览器上youtube视频的声音,在不借助第三方程序的情况下是做不到。使用OBS也做不到。

不过利用第三方开源程序soundflower可以解决这个问题。在安装soundflower之后,OBS可以设置 音频输出捕获模块,设备选择soundflower。同时系统声音输出设备 也选择为soundflower。

这样系统的任何程序发出的声音就会先经过soundflower,然后被OBS捕获。

mac-audio中的音频输入模块 和 输出模块 实现流程基本相同,如下所示:

基本原理是 在初始化模块的时候 使用系统接口AudioObjectAddPropertyListener注册音频的回调函数。然后在回调函数中完成音频渲染以及输出音频数据缓存。

原文网址:http://fancywt.cn/2017/10/28/obs/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io

开源直播工具OBS研究相关推荐

  1. obs多推流地址_最热门直播工具OBS的下载和设置教程,值得一看

    随着直播行业的再度火热,各个直播平台也推出了自己的直播工具,但各自都有一些不足需要改善.今天我来教大家来下载和设置主播们最常用的直播工具OBS,以开启自己的直播路程. 大多数人都在用的OBS直播工具 ...

  2. obs 推流编码在哪设置_直播软件OBS推流的设置方法

    如今是一个直播盛行的时代,在我们身边有着形形色色的直播内容,以及五花八门的直播看点,还有千奇百怪故事内容,更有危险性极高的探险直播,总之直播已经无所不在,它也是现在生活中不可缺少的一部分,看电脑时要看 ...

  3. 类似obs直播工具有哪些_如何使用OBS直播职业玩家之类的游戏

    类似obs直播工具有哪些 现在,OBS Studio (以前称为Open Broadcaster Software)的版本为19.0.3,可用于Mac和Windows的安装程序下载 ,以及适用于各种L ...

  4. 开源/免费界面自动化测试工具对比研究

    摘要: 随着我行自动化测试实施范围的不断扩大,参与界面自动化测试的应用系统越来越多.我行的应用系统现阶段多采用商用工具QTP(UFT)作为执行工具来进行界面自动化测试,采购的QTP license是有 ...

  5. [论文分享] 开源 C/C++静态软件缺陷检测工具实证研究

    前言 之前读了一遍这篇论文 开源 C/C++静态软件缺陷检测工具实证研究[1] [软件学报 2022] 属于静态软件分析与漏洞挖掘工具及技术的综述性文章, 今天总结一下 (其他的水话就不多说了, 就像 ...

  6. linux可用直播软件,免费直播软件OBS Studio下载 支持Windows/Mac和Linux

    OBS Studio是一款视频直播录制软件,为用户提供了视频.文本.图像等的捕获录制功能.当然你也可以用来录像,OBS Studio是免费的,并且自带中文语言.大多数的直播网站都有主播用这个软件进行直 ...

  7. 8 亿邮件地址泄露,源于邮件验证服务;腾讯推出微信公众号直播工具

    (给技术最前线加星标,每天看技术热点) 转自:开源中国.solidot.cnBeta.腾讯科技.快科技等 [技术资讯] 0.8 亿邮件地址遭泄露,源于邮件验证服务 近日,Security Discov ...

  8. vs2015编译基于obs-studio的阿里巴巴直播工具tblive

    vs2015编译基于obs-studio的阿里巴巴直播工具tblive 开发环境 vs2015+QT5.9.7 因为tblive使用的是vs2013,故需要用到v120平台工具集,如果没有安装可通过控 ...

  9. 源自Google、Facebook、Netflix和Cisco的10款开源安全工具很值得回味

     源自Google.Facebook.Netflix和Cisco的10款开源安全工具很值得回味 选择自由的开源安全软件是一个重要话题,随着新品牌的出现,在选择上也出现很多不确定性.但这没有影响开源 ...

最新文章

  1. c面试题总结(含答案)
  2. 计算机操作系统专题一:多道环境下进程同步与互斥制约关系的学习
  3. SQL SERVER的锁机制(四)——概述(各种事务隔离级别发生的影响)
  4. css3制作炫酷导航栏效果 转
  5. linux通过时间查询日志,linux按时间查询日志
  6. MOT with a hierachical single branch network
  7. linux登录pg数据库密码,PostgreSQL:修改数据库用户的密码
  8. 《锁王创造营》 第一关:初出茅庐
  9. distinct 多列详解
  10. 西门子plc 用c语言编程,西门子PLC常用指令举例
  11. EXIF App for Mac(EXIF查看器)
  12. 【GPT-3】第1章 大型语言模型时代
  13. unable to find account data for the submitted AuthenticationToken
  14. 年产2000t搅拌型发酵酸奶车间工艺设计
  15. Oracle 递归查询详解
  16. 互联网名称与数字地址分配机构ICANN简介
  17. html静态页面作业——酷酷动物主题响应式网页(5页) 大学生动物主题网页作品 动物网页设计作业模板 学生网页制作源代码下载
  18. 直线裁剪算法-Cohen-Sutherland算法
  19. 硬盘数据如何恢复?电脑硬盘资料恢复,方法就是这么简单!
  20. 20110830 寝室物语

热门文章

  1. 心理咨询领域首个开放的QA语料库
  2. 简单php登陆注册模块
  3. [DB]ORACLE监控锁表(锁表与解表)
  4. 专访MongoDB官方大中华区首席架构师唐建法:MongoDB将会领导数据处理新趋势 —— 一个操作型的数据平台...
  5. 项目总结(0730)
  6. 请问大神 APACK景观分析软件怎么用啊 第一次用不会用
  7. 【golang roadmap注册邀请码】
  8. 办公小技巧:word打印怎么做?
  9. 智能车基础四轮组”氢气球“----(1)软件基础框架
  10. 拥抱人工智能 | 智安协携手华为共同举办第五届智慧城市建设高峰论坛圆满成功!