当前位置: 首页 > news >正文

WebRTC 之音视频同步

在网络视频会议中, 我们常会遇到音视频不同步的问题, 我们有一个专有名词 lip-sync 唇同步来描述这类问题,当我们看到人的嘴唇动作与听到的声音对不上的时候,不同步的问题就出现了

而在线会议中, 听见清晰的声音是优先级最高的, 人耳对于声音的延迟是很敏感的

根据 T-REC-G.114-200305 中的描述

  • 大于~280ms 有些用户就会不满意
  • 大于~380ms 多数用户就会不满意
  • 大于~500ms 几乎所有用户就会不满意

我们就尽量使得声音的延迟在 280 ms 之内,这是解决 lip-sync 问题的前提, 声音不好的严重程序超过音视频不同步。

我们可以定义一个 sync_diff 值 来表示音频帧和视频帧之间的时间差

  • 正值表示音频领先于视频
  • 负值表示音频落后于视频

ITU 对此给出以下的阈值:

  • 不可感知 Undetectability (-100ms, +25ms)
  • 可感知 Detectability: (-125ms, +45ms)
  • 可接受 Acceptability: (–185ms, +90 ms)
  • 影响用户 Impact user experience (-∞, -185ms) ∪ (+90ms,∞)

(ITU-R BT.1359-1, Relative Timing of Sound and Vision for Broadcasting" 1998. Retrieved 30 May 2015)

当我们在播放一个视频帧及对应的音频帧的时候,要计算一下这个 sync_diff

sync_diff = audio_frame_time - video_frame_time

如果这个 sync_diff 大于 90ms, 也就是音频包到得过早,就会有音视频不同步的问题 - 声音听到了,嘴巴没跟上.

如果这个 sync_diff 小于 -185ms, 也就是视频包到得过早,就会有音视频不同步的问题 - 嘴巴在动,声音没跟上.

不同步的原因

lip sync 1

这个问题的原因主要在于音频的采集, 编码,传输, 解码, 播放与视频的采集,编码,传输,解码以及渲染一般是分开进行的,因为音频和视频采集自不同的设备,即它们的来源不同,在网络上传输也会有延迟,也由不同的设备进行播放,这样如果在接收方不采取措施进行时间同步,就会极有可能看到口型和听到的声音对不上的情况。

由此派生出 3 个小问题:

  1. 如何将来自同一个人或设备的多路 audio 及 video stream关联起来?
  2. 如何将 RTP 中的时间戳 timestamp 映射到发送方的音视频采集时间
  3. 如何调整音频或者视频帧的播放时间,让它们怎么之间相对同步?

解决方案

1. 如何将来自同一个人或设备的音视频流关联起来?

对于多媒体会话,每种类型的媒体(例如音频或视频)一般会在单独的 RTP 会话中发送,发送方会在 RTCP SDES 消息中指明
接收方通过 CNAME 项关联要同步的RTP流, 而这个 CNAME 包含在发送方所发送的 RTCP SDES 中

SDES 数据包包含常规包头,有效负载类型为 202,项目计数等于数据包中 SSRC/CSRC 块的数量,后跟零个或多个 SSRC/CSRC 块,其中包含有关特定 SSRC 或 CSRC,每个都与 32 位边界对齐。

0               1               2               30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|V=2|P|    SC   |  PT=SDES=202  |            length L           |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|                          SSRC/CSRC_1                          |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                           SDES items                          ||                              ...                              |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|                          SSRC/CSRC_2                          |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                           SDES items                          ||                              ...                              |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+

CNAME 项在每个 SDES 数据包中都是必需的,而 SDES 数据包又是每个复合 RTCP 数据包中的必需部分。

与 SSRC 标识符一样,CNAME 必须与其他会话参与者的 CNAME 不同。 但 CNAME 不应随机选择 CNAME 标识符,而应允许个人或程序通过 CNAME 内容来定位其来源。

0               1               2               30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|    CNAME=1    |     length    | user and domain name         ...+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

例如 Alice 向外发送一路音频流,一路视频流, 这两路流会使用不同的 SSRC, 但是在其所发送的 RTCP SDES 消息会使用相同的 CNAME.

  • RTP SSRC 1 ~ CNAME 1
  • RTP SSRC 2 ~ CNAME 1

2. 同步的时间如何计算

来自同一个终端用户的音频和视频, 在编码发送的 RTP 包中有一个 timestamp, 这个时间戳表示媒体流的捕捉时间。
同时, 作为发送者也会发送 RTCP Sender Report, 其中包含发送的 RTP timestamp 和 NTP timestamp 的映射关系,这样我们在接收方就可以把 RTP 包里的

lip sync flow

对于每个 RTP 流,发送方定期发出 RTCP SR, 其中包含一对时间戳:

NTP 时间戳以及与该 RTP 流关联的相应 RTP 时间戳。

这对时间戳传达每个媒体流的 NTP 时间和 RTP 时间之间的关系。

先回顾一下 RTP packet 和 RTCP sender report

  • RTP 包结构
0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|V=2|P|X|  CC   |M|     PT      |       sequence number         |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                           timestamp                           |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|           synchronization source (SSRC) identifier            |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|            contributing source (CSRC) identifiers             ||                             ....                              |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  • RTCP Sender Report 结构
0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+header |V=2|P|    RC   |   PT=SR=200   |             length            |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                         SSRC of sender                        |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+sender |              NTP timestamp, most significant word             |info   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|             NTP timestamp, least significant word             |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                         RTP timestamp                         |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                     sender's packet count                     |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                      sender's octet count                     |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+report |                 SSRC_1 (SSRC of first source)                 |block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+1    | fraction lost |       cumulative number of packets lost       |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|           extended highest sequence number received           |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                      interarrival jitter                      |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                         last SR (LSR)                         |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                   delay since last SR (DLSR)                  |+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+report |                 SSRC_2 (SSRC of second source)                |block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+2    :                               ...                             :+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+|                  profile-specific extensions                  |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

通过 NTP timestamp 和 RTP timestamp 之间的映射, 我们可以知道 audio 包的时间和 video 包的时间。

具体的计算可以参见 WebRTC 的 RtpToNtpEstimator 类, 它将收到的若干 SR 中的 NTP time 和 RTP timestamp 保存下来,然后 应用最小二乘法来估算后续 RTP timestamp 所对应的 NTP timestamp, 大致为用最近 N=20 个 RTCP SR 包的 ntp timestamp 和 rtp timestamp 的构造出线性关系 y = ax + b, 通过最小二乘法来计算收到的 RTP 包对应的 ntp timestamp.

// Converts an RTP timestamp to the NTP domain.
// The class needs to be trained with (at least 2) RTP/NTP timestamp pairs from
// RTCP sender reports before the convertion can be done.
class RtpToNtpEstimator {public://...enum UpdateResult { kInvalidMeasurement, kSameMeasurement, kNewMeasurement };// Updates measurements with RTP/NTP timestamp pair from a RTCP sender report.UpdateResult UpdateMeasurements(NtpTime ntp, uint32_t rtp_timestamp);// Converts an RTP timestamp to the NTP domain.// Returns invalid NtpTime (i.e. NtpTime(0)) on failure.NtpTime Estimate(uint32_t rtp_timestamp) const;// Returns estimated rtp_timestamp frequency, or 0 on failure.double EstimatedFrequencyKhz() const;private:// Estimated parameters from RTP and NTP timestamp pairs in `measurements_`.// Defines linear estimation: NtpTime (in units of 1s/2^32) =//   `Parameters::slope` * rtp_timestamp + `Parameters::offset`.struct Parameters {double slope;double offset;};// RTP and NTP timestamp pair from a RTCP SR report.struct RtcpMeasurement {NtpTime ntp_time;int64_t unwrapped_rtp_timestamp;};void UpdateParameters();int consecutive_invalid_samples_ = 0;std::list<RtcpMeasurement> measurements_;absl::optional<Parameters> params_;mutable RtpTimestampUnwrapper unwrapper_;
};

3. 调整播放和渲染时间

一般我们会以 audio 为主, video 向 audio 靠拢, 两者时间一致也就会达到 lip sync 音视频同步

  1. audio 包先来, video 包后来: audio 包放在 jitter buffer 时等一会儿, 但是这个时间是有限的, 音频的流畅是首先要保证的, 视频跟不上可以降低视频的码率
  2. video 包先来, audio 包后来: video 包要等 audio 包来, 这是为了让音视频同步要付出的代价

一般以音频为主流 master stream,视频为从流 slave stream。 一般方法是接收方维护音频流的缓冲区的管理,并通过将视频 RTP 时间戳转换为正确从属于音频流的时间戳来调整视频流的播放。

当带有RTP时间戳 RTPv的视频帧到达接收器时,接收器通过四个步骤将RTP时间戳 RTPv 映射到视频设备时间戳VTB( Video Time Base),如图所示。

  1. 使用 Video RTCP SR 中的 RTP/NTP 时间戳对建立的映射,将视频 RTP 时间戳 RTPv 映射到发送方 NTP 时间。

  2. 根据该 NTP 时间戳,使用 Audio RTCP SR 中的 RTP/NTP 时间戳对建立的映射,计算来自发送方的相应音频 RTPa 时间戳。
    此时,视频RTP时间戳被映射到音频RTP 包的相同时间基准。

  3. 根据该音频 RTP 时间戳,使用卡尔曼滤波的方法计算音频设备时间基准中的相应时间戳。 结果是音频设备时间基准 ATB(Audio Time Base) 中的时间戳。

  4. 根据 ATB,使用偏移量 AtoV 计算视频设备时基 VTB 中的相应时间戳。

接收方需要确保带有 RTP 时间戳 RTPv 的视频帧使用所计算出的发送方视频设备时间基准 VTB 播放。

AtoV = V_time - A_Time/(audio sample rate)

注:

  • AtoV: 音频相较视频的偏移量
  • ATB: Audio device Time Base 音频设备的时间基准
  • VTB: Video device Time Base 视频设备的时间基准

具体方法可以参见 https://www.ccexpert.us/video-conferencing/using-rtcp-for-media-synchronization.html)

WebRTC 的做法原理上差不多,实现略有不同,可以参见 WebRTC 的源代码 StreamSynchronization 类和 RtpStreamsSynchronizer 类

大致上它会计算出 video 的延迟

current_delay_ms = max(min_playout_delay_ms, jitter_delay_ms + decode_time _ms + render_delay_ms)

然后再计算视频相对于音频的延迟 relative_delay_ms,

  • 如果它大于0, 视频比音频慢,减小视频延迟(主要是调整 jitter buffer delay),或者是增大音频延迟, 取决于阈值 base_target_delay_ms
  • 如果它小于0, 音频比视频慢,减小音频延迟,或者是增大视频延迟, 取决于阈值base_target_delay_ms

base_target_delay_ms 的比较逻辑参见StreamSynchronization::ComputeDelays,

if (diff_ms > 0) {// The minimum video delay is longer than the current audio delay.// We need to decrease extra video delay, or add extra audio delay.if (video_delay_.extra_ms > base_target_delay_ms_) {// We have extra delay added to ViE. Reduce this delay before adding// extra delay to VoE.video_delay_.extra_ms -= diff_ms;audio_delay_.extra_ms = base_target_delay_ms_;} else {  // video_delay_.extra_ms > 0// We have no extra video delay to remove, increase the audio delay.audio_delay_.extra_ms += diff_ms;video_delay_.extra_ms = base_target_delay_ms_;}} else {  // if (diff_ms > 0)// The video delay is lower than the current audio delay.// We need to decrease extra audio delay, or add extra video delay.if (audio_delay_.extra_ms > base_target_delay_ms_) {// We have extra delay in VoiceEngine.// Start with decreasing the voice delay.// Note: diff_ms is negative; add the negative difference.audio_delay_.extra_ms += diff_ms;video_delay_.extra_ms = base_target_delay_ms_;} else {  // audio_delay_.extra_ms > base_target_delay_ms_// We have no extra delay in VoiceEngine, increase the video delay.// Note: diff_ms is negative; subtract the negative difference.video_delay_.extra_ms -= diff_ms;  // X - (-Y) = X + Y.audio_delay_.extra_ms = base_target_delay_ms_;}
}

更多细节在 WebRTC 的代码中

  • class StreamSynchronization
  • class RtpStreamsSynchronizer

通过StreamSynchronization::ComputeDelays计算出音频和视频的相对延迟,如果相对延迟很小( < 30ms), 则无需调整音视频的播放时间,如果相对延迟很大, 则以 80ms 的幅度进行逐步调整。 与传统的只调视频延迟,不调音频延迟, WebRTC 会两边都调点,使得音视频的时间彼此靠近,前提是音频的延迟是在上面提到的可接受范围之内。

参考资料

  • https://www.ciscopress.com/articles/article.asp?p=705533&seqNum=6
  • https://www.ccexpert.us/video-conferencing/using-rtcp-for-media-synchronization.html
  • https://testrtc.com/docs/how-do-you-find-lip-sync-issues-in-webrtc/
  • https://en.wikipedia.org/wiki/Audio-to-video_synchronization
  • https://www.simplehelp.net/2018/05/29/how-to-fix-out-of-sync-audio-video-in-an-mkv-mp4-or-avi/
    *RFC6051: Rapid Synchronisation of RTP Flows

相关文章:

WebRTC 之音视频同步

在网络视频会议中&#xff0c; 我们常会遇到音视频不同步的问题&#xff0c; 我们有一个专有名词 lip-sync 唇同步来描述这类问题&#xff0c;当我们看到人的嘴唇动作与听到的声音对不上的时候&#xff0c;不同步的问题就出现了 而在线会议中&#xff0c; 听见清晰的声音是优先…...

kubernetes基于helm部署gitlab-runner

kubernetes基于helm部署gitlab-runner 这篇博文介绍如何在 Kubernetes 中使用helm部署 GitLab-runner。 先决条件&#xff1a; 已运行的 Kubernetes 集群已运行的 gitlab 实例 项目地址&#xff1a;https://gitlab.com/gitlab-org/charts/gitlab-runner 官方文档&#xff…...

深度学习和OpenCV的对象检测(MobileNet SSD图像识别)

基于深度学习的对象检测时,我们主要分享以下三种主要的对象检测方法: Faster R-CNN(后期会来学习分享)你只看一次(YOLO,最新版本YOLO3,后期我们会分享)单发探测器(SSD,本节介绍,若你的电脑配置比较低,此方法比较适合R-CNN是使用深度学习进行物体检测的训练模型; 然而,…...

Gitlab CI/CD笔记-第一天-GitOps和以前的和jenkins的集成的区别

一、GitOps-CI/CD的流程图与Jenkins的流程图 从上图可以看到&#xff1a; GitOps与基于Jennkins技术栈的CI/CD流程&#xff0c;无法从Jenkins集成其他第三方开源的项目来实现换成了Gitlab来进行集成。 好处在于&#xff1a;CI 一个工具Gitlab就行了&#xff0c;但CD部分依旧是…...

有关OpenBSD, NetBSD, FreeBSD -- 与GPT对话

1 介绍一下 - OpenBSD, NetBSD, FreeBSD 当谈论操作系统时,OpenBSD、NetBSD和FreeBSD都是基于BSD(Berkeley Software Distribution)的操作系统,它们各自是独立开发的,并在BSD许可下发布。这些操作系统有很多共同点,但也有一些差异。以下是对它们的简要介绍: OpenBSD: O…...

RabbitMQ 备份交换机和死信交换机

为处理生产者生产者将消息推送到交换机中&#xff0c;交换机按照消息中的路由键即自身策略无法将消息投递到指定队列中造成消息丢失的问题&#xff0c;可以使用备份交换机。 为处理在消息队列中到达TTL的过期消息&#xff0c;可采用死信交换机进行消息转存。 通过上述描述可知&…...

Linux 中利用设备树学习Ⅳ

系列文章目录 第一章 Linux 中内核与驱动程序 第二章 Linux 设备驱动编写 &#xff08;misc&#xff09; 第三章 Linux 设备驱动编写及设备节点自动生成 &#xff08;cdev&#xff09; 第四章 Linux 平台总线platform与设备树 第五章 Linux 设备树中pinctrl与gpio&#xff08;…...

使用Spring Initializr方式构建Spring Boot项目

除了可以使用Maven方式构建Spring Boot项目外&#xff0c;还可以通过Spring Initializr方式快速构建Spring Boot项目。从本质上说&#xff0c;Spring lnitializr是一个Web应用&#xff0c;它提供了一个基本的项目结构&#xff0c;能够帮助我们快速构建一个基础的Spring Boot项目…...

Sentinel 2.0 微服务零信任的探索与实践

作者&#xff1a;涯客、十眠 从古典朴素的安全哲学谈起 网络安全现状 现在最常见的企业网络安全架构便是在企业网络边界处做安全防护&#xff0c;而在企业网络内部不做安全防范。这确实为企业的安全建设省了成本也为企业提供了一定的防护能力。但是这类比于现实情况的一个小…...

Oracle以逗号分隔的字符串拆分为多行数据实例详解

前言 近期在工作中遇到某表某字段是可扩展数据内容&#xff0c;信息以逗号分隔生成的&#xff0c;现需求要根据此字段数据在其它表查询相关的内容展现出来&#xff0c;第一想法是切割数据&#xff0c;以逗号作为切割符&#xff0c;以下为总结的实现方法&#xff0c;以供大家参…...

harbor仓库安装部署(1.6.1)

目录 1、关闭防火墙 2、安装docker-ce&#xff08;所有主机&#xff09; 3、配置阿里云镜像加速器 4、部署Docker Compose 服务 5、部署 Harbor 服务 6、下载 Harbor 安装程序&#xff08;两台harbor主机&#xff09; 7、配置 Harbor 参数文件 8、启动并安装 Harbor …...

FastAPI 构建 API 高性能的 web 框架(一)

如果要部署一些大模型一般langchainfastapi&#xff0c;或者fastchat&#xff0c; 先大概了解一下fastapi,本篇主要就是贴几个实际例子。 官方文档地址&#xff1a; https://fastapi.tiangolo.com/zh/ 1 案例1:复旦MOSS大模型fastapi接口服务 来源&#xff1a;大语言模型工程…...

Spring框架中的Bean的生命周期

Spring Bean 的生命周期总体分为四个阶段&#xff1a;实例化 》属性注入》初始化》销毁 实例化&#xff1a; &#xff08;1&#xff09;实例化bean&#xff1a;根据配置文件中Bean的定义&#xff0c;利用java Reflection 反射技术创建Bean的实例&#xff01; 属性注入&#…...

vue3-ts-vite:vue 项目 配置 多页面应用

一、Vue项目&#xff0c;什么是多页面应用 Vue是一种单页面应用程序&#xff08;SPA&#xff09;框架&#xff0c;这意味着Vue应用程序通常只有一个HTML页面&#xff0c;而在该页面上进行动态的内容更改&#xff0c;而不是每次都加载新的HTML页面。 但是&#xff0c;有时候我…...

docker部署jenkins且jenkins中使用docker去部署项目

docker部署jenkins且jenkins中使用docker去部署项目 1、确定版本 2.346.1是最后一个支持jdk8的 2、编写docker-compose.yml并执行 在这个目录中新增data文件夹&#xff0c;注意data是用来跟docker中的文件进行映射的 docker-compose.yml version: "3.1" service…...

无锚框原理 TOOD:Task-aligned One-stage Object Detection

无锚框原理 TOOD&#xff1a;Task-aligned One-stage Object Detection 一 摘要二 引言TOOD设计 三 具体设计Task-aligned Head任务对齐的预测器 TAP预测对齐 TAL 任务对齐学习Task-aligned Sample Assignment多任务损失 一 摘要 一阶段目标检测通常通过优化两个子任务来实现&…...

配置Picgo图床之COS、OSS、Github图床

简介 PicGo是一款开源的图片上传和管理工具&#xff0c;它提供了简单易用的界面和丰富的功能&#xff0c;方便用户上传、管理和分享图片。 以下是PicGo的一些主要特点和功能&#xff1a; 图片上传&#xff1a;PicGo支持将本地图片快速上传到云存储服务&#xff0c;如七牛云、…...

【LangChain】Prompts之自定义提示模板

LangChain学习文档 【LangChain】向量存储(Vector stores)【LangChain】向量存储之FAISS【LangChain】Prompts之Prompt templates【LangChain】Prompts之自定义提示模板 概要 假设我们希望LLM生成给定函数名称的英语解释。为了实现此任务&#xff0c;我们将创建一个自定义提示…...

EFLFK——ELK日志分析系统+kafka+filebeat架构(3)

zookeeperkafka分布式消息队列集群的部署 紧接上期&#xff0c;在ELFK的基础上&#xff0c;添加kafka做数据缓冲 附kafka消息队列 nginx服务器配置filebeat收集日志&#xff1a;192.168.116.40&#xff0c;修改配置将采集到的日志转发给kafka&#xff1b; kafka集群&#xff…...

支付总架构解析

一、支付全局分层 一笔支付以用户为起点&#xff0c;经过众多支付参与者之后&#xff0c;到达央行的清算账户&#xff0c;完成最终的资金清算。那么我们研究支付宏观&#xff0c;可以站在央行清算账户位置&#xff0c;俯视整个支付金字塔&#xff0c;如图1所示&#xff1a; 图…...

【HCIP】OSPF综合实验

题目&#xff1a; 配置&#xff1a; R1 //ip分配 [r1]int g0/0/0 [r1-GigabitEthernet0/0/0]ip add 172.16.0.1 27 [r1-GigabitEthernet0/0/0]q [r1]int lo [r1]int LoopBack 0 [r1-LoopBack0]ip add 172.16.1.1 24//配置缺省 [r1]ip route-static 0.0.0.0 0 172.16.0.3 //启动…...

PyTorch深度学习实战(10)——过拟合及其解决方法

PyTorch深度学习实战&#xff08;10&#xff09;——过拟合及其解决方法 0. 前言1. 过拟合基本概念2. 添加 Dropout 解决过拟合3. 使用正则化解决过拟合3.1 L1 正则化3.2 L2 正则化 4. 学习率衰减小结系列链接 0. 前言 过拟合 (Overfitting) 是指在机器学习中&#xff0c;模型…...

【工作记录】week7

day3 1.本地切换分支 本地切换分支时&#xff0c;可以直接用 vscode 集成的工具 点击后直接选择即可&#xff1a; 其中红框中为本地分支&#xff0c;蓝框中则是远程分支&#xff01; 当在本地切换到一个本地不存在的远程分支时&#xff0c;会在本地创建一个同名的分支&…...

安防监控视频融合EasyCVR平台接入RTSP流后设备显示离线是什么原因?

安防监控视频EasyCVR视频汇聚融合平台基于云边端智能协同架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台支持海量视频汇聚管理、全网分发、按需调阅、鉴权播放、智能分析等视频能力与服务。平台开放度高、兼容性强、可支持灵活拓展与第三方集成&#xff…...

MongoDB:Linux环境全套安装指南

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; MongoDB&#xff1a;Linux环境全套安装指南 ⏱️ 创作时间&#xff1a…...

PostgreSql 启停

一、启动 直接运行 postgres 进程启动。使用 pg_ctl 命令启动。&#xff08;pg_ctl 命令实际也是封装的 postgres 进程&#xff09; 示例&#xff1a; pg_ctl -D /data/pg13/data start 或 postgres -D /data/pg13/data &二、停止 使用 pg_ctl 命令停止&#xff0c;优先…...

中介者模式(C++)

定义 用一个中介对象来封装(封装变化)一系列的对象交互。中介者使各对象不需要显式的相互引用(编译时依赖->运行时依赖)&#xff0c;从而使其耦合松散(管理变化)&#xff0c;而且可以独立地改变它们之间的交互。 应用场景 在软件构建过程中&#xff0c;经常会出现多个对象…...

LeetCode热题 100整理

53. 最大子数组和 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。子数组是数组中的一个连续部分。 示例 1&#xff1a; 输入&#xff1a;nums [-2,1,-3,4,-1,2,1,-5,4] 输…...

SDE与ODE

看这篇文章不错https://spaces.ac.cn/archives/9209 然后在结合https://www.bilibili.com/video/BV1814y1n7Eh/?spm_id_from333.788&vd_sourceeb433c8780bdd700f49c6fc8e3bd0911这个B站的视频...

AWK实战案例——筛选给定时间范围内的日志

时间戳与当地时间 概念&#xff1a; 1.时间戳&#xff1a; 时间戳是指格林威治时间自1970年1月1日&#xff08;00:00:00 GMT&#xff09;至当前时间的总秒数。它也被称为Unix时间戳&#xff08;Unix Timestamp&#xff09;。通俗的讲&#xff0c;时间戳是一份能够表示一份数据…...