HTTP-FLV详解及分析

文章目录

  • 前言
  • 一、HTTP-FLV 简介
    • 1、市场上使用 http-flv 的商家
    • 2、http-flv、rtmp 和 hls 直播的优缺点
    • 3、http-flv 技术实现
  • 二、Nginx 配置 http-flv
    • 1、Windows 安装 nginx,已经集成 nginx-http-flv-module
    • 2、nginx.conf 配置文件
    • 3、运行 nginx 服务器
    • 4、ffmpeg 推流
    • 5、VLC 播放
    • 6、flv.js 网页播放
  • 三、FLV 格式简介
    • 1、简介
    • 2、FLV 格式解析
      • ①、header
      • ②、body
  • 四、FLV Adobe 官方标准
    • 1、单位说明
    • 2、FLV 文件头和文件体 (E.2, E.3)
    • 3、FLV Tag (E.4)
    • 4、AudioTag (E.4.2)
    • 5、VideoTag (E.4.3)
    • 6、SCRIPTDATA (E.4.4)
    • 7、onMetadata (E.5)
    • 8、keyframes 索引信息
  • 五、FlvAnalyzer 分析 flv 文件


前言

传统的直播协议要么使用 Adobe 的基于 TCP 的 RTMP 协议, 要么使用 Apple 的基于 HTTP 的 HLS 协议。本文介绍另外一种结合了 RTMP 的低延时, 以及可以复用现有 HTTP 分发资源的流式协议 HTTP-FLV


一、HTTP-FLV 简介

HTTP-FLV,即将音视频数据封装成 FLV,然后通过 HTTP 协议传输给客户端。

HLS 其实是一个 “文本协议” ,而并非流媒体协议,(ts0,ts1,…)。 那么,什么样的协议才能称之为流媒体协议呢?
答:流(stream):数据在网络上按时间先后次序传输和播放的连续音/视频数据流。之所以可以按照顺序传输和播放连续是因为在类似 RTMP、FLV 协议中,每一个音视频数据都被封装成了包含时间戳信息头的数据包。而当播放器拿到这些数据包解包的时候能够根据时间戳信息把这些音视频数据和之前到达的音视频数据连续起来播放。

MP4、MKV 等等类似这种封装,必须拿到完整的音视频文件才能播放,因为里面的单个音视频数据块不带有时间戳信息,播放器不能将这些没有时间戳信息数据块连续起来,所以就不能实时的解码播放。

1、市场上使用 http-flv 的商家

优酷的 pc 网页直播,斗鱼、 熊猫 tv、 虎牙 pc 网页上也使用了 http-flv

2、http-flv、rtmp 和 hls 直播的优缺点

  • 三者的延迟性
    • http-flv:低延迟,内容延迟可以做到 2-5 秒;
    • Rtmp:低延迟,内容延迟可以做到 2-5 秒。
    • Hls:延迟较高(ts0,segment-time:5,10s)。
  • 三者的易用性
    • rtmp 和 http-flv:播放端安装率高。只要浏览器支持 FlashPlayer 就能非常简易的播放。
    • hls:最大的优点:HTML5 可以直接打开播放;这个意味着可以把一个直播链接通过微信等转发分享,不需要安装任何独立的 APP,有浏览器即可。
  • rtmp 和 http-flv 比较
    • 穿墙:很多防火墙会墙掉 RTMP,但是不会墙 HTTP,因此 HTTP FLV 出现奇怪问题的概率很小。
    • 调度:RTMP 也有个 302,可惜是播放器 as 中支持的,HTTP FLV 流就支持 302 方便 CDN 纠正 DNS 的错误。
    • 容错:SRS 的 HTTP FLV 回源时可以回多个,和 RTMP 一样,可以支持多级热备。
    • 简单:FLV 是最简单的流媒体封装,HTTP 是最广泛的协议,这两个组合在一起维护性更高,比 RTMP 简单多了。

3、http-flv 技术实现

HTTP 协议中有个约定:content-length 字段,http 的 body 部分的长度。

  • 服务器回复 http 请求的时候如果有这个字段,客户端就接收这个长度的数据然后就认为数据传输完成了。
  • 如果服务器回复 http 请求中没有这个字段,客户端就一直接收数据,直到服务器跟客户端的 socket 连接断开。 (流式传输)

http-flv 直播就是利用第二个原理,服务器回复客户端请求的时候不加 content-length 字段,在回复了 http 内容之后,紧接着发送 flv 数据,客户端就一直接收数据了。

二、Nginx 配置 http-flv

1、Windows 安装 nginx,已经集成 nginx-http-flv-module

RTMP 服务器:Nginx+rtmp(windows)的环境搭建如有需要可自取:

链接:https://pan.baidu.com/s/1AcIVERWUPbJL1zu8yCcAzw
提取码:mtdf

2、nginx.conf 配置文件

nginx.conf 配置文件如下:

worker_processes  1;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#error_log  logs/error.log  debug;#pid        logs/nginx.pid;events {worker_connections  1024;
}# 添加RTMP服务
rtmp {server {listen 1935; # 监听端口chunk_size 4000;application live {live on;gop_cache on;hls on;hls_path html/hls;}}
}# HTTP服务
http {include       mime.types;default_type  application/octet-stream;#access_log  logs/access.log  main;server {listen       8080; # 监听端口location /flv {flv_live on;chunked_transfer_encoding on;	add_header 'Access-Control-Allow-Origin' '*';add_header "Access-Control-Allow-Credentials" "true";add_header "Access-Control-Allow-Methods" "*";add_header "Access-Control-Allow-Headers" "Content-Type,Access-Token";add_header "Access-Control-Expose-Headers" "*";	}location /stat.xsl {root html;}location /stat {rtmp_stat all;rtmp_stat_stylesheet stat.xsl;}location / {root html;}}
}

其中涉及到跨域问题:#http-flv

 location /flv {flv_live on;chunked_transfer_encoding on;	add_header 'Access-Control-Allow-Origin' '*';add_header "Access-Control-Allow-Credentials" "true";add_header "Access-Control-Allow-Methods" "*";add_header "Access-Control-Allow-Headers" "Content-Type,Access-Token";add_header "Access-Control-Expose-Headers" "*";	}

3、运行 nginx 服务器

双击 nginx8080.exe
在这里插入图片描述
在任务管理器可以看到目前 nginx 已开始工作
在这里插入图片描述

4、ffmpeg 推流

ffmpeg -re -i SampleVideo_1280x720_20mb.mp4 -vcodec libx264 -acodec aac -f flv -y rtmp://127.0.0.1:1935/live/test1

这个命令使用 FFmpeg 工具来将输入视频文件 SampleVideo_1280x720_20mb.mp4 转换为 FLV 格式并通过 RTMP 协议流式传输到指定的 URL 地址 rtmp://127.0.0.1:1935/live/test1;

  • -re:以实时模式(real-time)读取输入文件,模拟实时流传输的速度。
  • -i SampleVideo_1280x720_20mb.mp4:指定输入文件名为 SampleVideo_1280x720_20mb.mp4。
  • -vcodec libx264:选择 H.264 编码器作为视频编码器;
  • -acodec aac:选择 AAC 编码器作为音频编码器;
  • -f flv:指定输出格式为FLV(Flash Video);
  • -y:自动覆盖输出文件,如果存在同名文件则会被替换;
  • rtmp://127.0.0.1:1935/live/test1:指定输出的 URL 地址,以 RTMP 协议传输到 192.168.36.176 服务器的 1935 端口的 live 应用程序中的 test1 流

在这里插入图片描述

5、VLC 播放

  • http-flv:http://localhost:8080/flv?port=1935&app=live&stream=test1
    对应关系如下:
    在这里插入图片描述
    VLC 进行拉流
    在这里插入图片描述
    在这里插入图片描述
  • rtmp:rtmp://127.0.0.1:1935/live/test1
    在这里插入图片描述
    在这里插入图片描述
  • Hls:http://localhost:8080/hls/test1.m3u8
    在这里插入图片描述
    在这里插入图片描述

此外,视频和音频内容分割为小的 TS 文件,并生成相应的 M3U8 文件,以便客户端能够获取和播放这些文件。M3U8 文件可以通过 HTTP 服务器提供给客户端,并使用流媒体播放器(如VLC、HLS播放器等)进行解析和播放。
在这里插入图片描述
这个目录是由 nginx.conf 配置文件决定的:
在这里插入图片描述

6、flv.js 网页播放

前面我们已经解决了跨域问题
在这里插入图片描述
html.flv 文件内容如下:

worker_processes  1;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#error_log  logs/error.log  debug;#pid        logs/nginx.pid;events {worker_connections  1024;
}# 添加RTMP服务
rtmp {server {listen 1935; # 监听端口chunk_size 4000;application live {live on;gop_cache on;hls on;hls_path html/hls;}}
}# HTTP服务
http {include       mime.types;default_type  application/octet-stream;#access_log  logs/access.log  main;server {listen       8080; # 监听端口location /flv {flv_live on;chunked_transfer_encoding on;	add_header 'Access-Control-Allow-Origin' '*';add_header "Access-Control-Allow-Credentials" "true";add_header "Access-Control-Allow-Methods" "*";add_header "Access-Control-Allow-Headers" "Content-Type,Access-Token";add_header "Access-Control-Expose-Headers" "*";	}location /stat.xsl {root html;}location /stat {rtmp_stat all;rtmp_stat_stylesheet stat.xsl;}location / {root html;}}
}

因此双击 flv.html 文件,可以看到网页播放成功
在这里插入图片描述

三、FLV 格式简介

1、简介

FLV(Flash Video)是现在非常流行的流媒体格式,由于其视频文件体积轻巧、封装播放简单等特点,使其很适合在网络上进行应用,目前主流的视频网站无一例外地使用了 FLV 格式。另外由于当前浏览器与 Flash Player 紧密的结合,使得网页播放 FLV 视频轻而易举,也是 FLV 流行的原因之一。

FLV 是流媒体封装格式,我们可以将其数据看为二进制字节流。总体上看,FLV 包括文件头(File Header:9 字节)和文件体(File Body)两部分,其中文件体由一系列的 TagTag Size 对组成。
在这里插入图片描述

注意这个大小关系:PreviosTagSize = TagDataSize + 11;

2、FLV 格式解析

先来一张图,这是上面我们播放的视频文转换为 FLV 文件
在这里插入图片描述
使用 Notepad++ 进行查看二进制数据(注:这里要求 Notepad++ 安装了 HexEditor 插件

可以参考我以前的博客:notepad++安装HexEditor插件查看二进制文件

SampleVideo_1280x720_20mb.flv 文件二进制内容如下:
在这里插入图片描述

①、header

头部分由以下几部分组成:Signature(3 Byte)+Version(1 Byte)+Flags(1 Bypte)+DataOffset(4 Byte)

  • signature 占 3 个字节:固定 FLV 三个字符作为标示。一般发现前三个字符为 FLV 时就认为他是 flv 文件。
  • Version 占 1 个字节:标示 FLV 的版本号。 这里我们看到是 1
  • Flags 占 1 个字节:内容标示。第 0 位和第 2 位,分别表示 video 与 audio 存在的情况。(1 表示存在,0 表示不存在)。截图看到是 0x05,也就是 00000101,代表既有视频,也有音频。
  • DataOffset 4 个字节:表示 FLV 的 header 长度。 这里可以看到固定是 9

②、body

FLV 的 body 部分是由一系列的 back-pointers( 后向指针) + tag 构成

  • back-pointers 固定 4 个字节,表示前一个 tag 的 size。
    • 从上图可以看到前一个 tag 的 size 为 0
  • tag 分三种类型:video、audio、scripts。
    • tag 组成tag type[1B]+tag data size[3B]+Timestamp[3B]+TimestampExtended[1B]+stream id[3B]+ tag data
      • type 1 个字节。8 为 Audio,9 为 Video,18 为 scripts
        • 从上图可以看到 type0x123 = 18 --> scripts
      • tag data size 3 个字节。表示 tag data 的长度:从 streamd id 后算起
        • 从上图可以看到 tag data size0x123 = 297
      • Timestreamp 3 个字节。 时间戳
        • 从上图可以看到 Timestreamp0x000000 = 0
      • TimestampExtended 1 个字节。 时间戳扩展字段
        • 从上图可以看到 TimestampExtended0x00 = 0
      • stream id 3 个字节。 总是 0
      • tag data 数据部分
    • tag 头伪代码
      在这里插入图片描述

四、FLV Adobe 官方标准

FLV 文件格式标准是写在 F4V/FLV file format spec v10.1 的附录 E 里面的 FLV File Format。

1、单位说明

在这里插入图片描述

2、FLV 文件头和文件体 (E.2, E.3)

从整个文件上看,FLV = FLV File Header + FLV File Body
在这里插入图片描述
通常,FLV 的前 13 个字节(flv header + PreviousTagSize0)完全相同,所以,程序中会单独定义一个常量来指定。特殊,比如有的视频文件没有视频流或没有音频流。

3、FLV Tag (E.4)

在这里插入图片描述
Timestamp 和 TimestampExtended 组成了这个 TAG 包数据的 PTS 信息,PTS =Timestamp | TimestampExtended << 24

4、AudioTag (E.4.2)

由于 AAC 编码的特殊性, 这里着重说明了 AAC 编码的 Tag 格式。
在这里插入图片描述
AudioTagHeader 的第一个字节,也就是接跟着 StreamID 的 1 个字节包含了音频类型,采样率等的基本信息。

AudioTagHeader 之后跟着的就是 AUDIODATA 部分了。但是,这里有个特例,如果音频格式(SoundFormat)是 AAC,AudioTagHeader 中会多出 1 个字节的数据 AACPacketType,这个字段来表示 AACAUDIODATA 的类型:0 = AAC sequence header,1 = AAC raw。

AudioSpecificConfig 结构描述非常复杂,在标准文档中是用伪代码描述的,这里先假定要编码的音频格式,做一下简化。

音频编码为:AAC-LC,音频采样率为 44100。
在这里插入图片描述
在 FLV 的文件中,一般情况下 AAC sequence header 这种包只出现 1 次,而且是第一个 audio tag,为什么需要这种 tag,因为在做 FLV demux 的时候,如果是 AAC 的音频,需要在每帧 AAC ES 流前边添加 7 个字节 ADST 头, ADST 是解码器通用的格式,也就是说 AAC 的纯 ES 流要打包成 ADST 格式的 AAC 文件,解码器才能正常播放。 就是在打包 ADST 的时候,需要 samplingFrequencyIndex 这个信息,samplingFrequencyIndex 最准确的信息是在 AudioSpecificConfig 中,这样,你就完全可以把 FLV 文件中的音频信息及数据提取出来, 送给音频解码器正常播放了。

5、VideoTag (E.4.3)

由于 AVC(H.264) 编码的特殊性, 这里着重说明了 AVC(H.264) 编码的 Tag 格式。
在这里插入图片描述
VideoTagHeader 的第一个字节,也就是接跟着 StreamID 的 1 个字节包含着视频帧类型及视频 CodecID 等最基本信息。

VideoTagHeader 之后跟着的就是 VIDEODATA 部分了。但是,这里有个特例,如果视频格式(CodecID)是 AVC, VideoTagHeader 会多出 4 个字节的信息。

AVCDecoderConfigurationRecord 包含着是 H.264 解码相关比较重要的 SPS 和 PPS 信息,在给 AVC 解码器送数据流之前一定要把 SPS 和 PPS 信息送出,否则的话,解码器不能正常解码。而且在解码器 stop 之后再次 start 之前, 如 seek,快进快退状态切换等,都需要重新送一遍 SPS 和 PPS 的信息。AVCDecoderConfigurationRecord 在 FLV 文件中一般情况也只出现 1 次,也就是第一个 video tag。

AVCDecoderConfigurationRecord 长度为 sizeof(UI8) * (11 + sps_size + pps_size)。
在这里插入图片描述

6、SCRIPTDATA (E.4.4)

ScriptTagBody 内容用 AMF 编码
在这里插入图片描述
一个 SCRIPTDATAVALUE 记录包含一个有类型的 ActionScript 值。

7、onMetadata (E.5)

FLV metadata object 保存在 SCRIPTDATA 中,叫 onMetaData。不同的软件生成的 FLV 的 properties 不同。
在这里插入图片描述

8、keyframes 索引信息

官方的文档中并没有对 keyframes index 做描述,但是,flv 的这种结构每个 tag 又不像 TS 有同步头,如果没有 keyframes index 的话,需要按顺序读取每一个 tag,seek 及快进快退的效果会非常差。后来在做 flv 文件合成的时候,发现网上有的 flv 文件将 keyframes 信息隐藏在 Script Tag 中。

keyframes 几乎是一个非官方的标准,也就是民间标准。两个常用的操作 metadata 的工具是 flvtool2 和 FLVMDI, 都是把 keyframes 作为一个默认的元信息项目。在 FLVMDI 的主页上有描述:
在这里插入图片描述
也就是说 keyframes 中包含着 2 个内容 “filepositions” 和 “times”分别指的是关键帧的文件位置和关键帧的 PTS。通过 keyframes 可以建立起自己的 Index,然后在 seek 和快进快退的操作中,快速有效地跳转到你想要找的关键帧位置进行处理。

五、FlvAnalyzer 分析 flv 文件

参考我之前的博客:音视频开发常用工具

查看其中第三章的内容:
在这里插入图片描述


我的qq:2442391036,欢迎交流!


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

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

相关文章

K8S知识点(十)

&#xff08;1&#xff09;Pod详解-启动命令 创建Pod&#xff0c;里面的两个容器都正常运行 &#xff08;2&#xff09;Pod详解-环境变量 &#xff08;3&#xff09;Pod详解-端口设置 &#xff08;4&#xff09;Pod详解-资源配额 修改&#xff1a;memory 不满足条件是不能正常…

leetcode:2935. 找出强数对的最大异或值 II【最大异或值还是得看01Trie树啊!】

题目截图 题目分析 排序后&#xff0c;限定了x和y的相对位置 假设y > x&#xff0c;随着y的移动&#xff0c;必须要保证2x > y 所以可以使用滑动窗口维护一堆满足条件的x 这些x的异或值记录在Trie树中即可 ac code class Node:__slots__ children, cntdef __init__(s…

Pandas画图报错:ValueError: signal only works in main thread

Pandas画图报错&#xff1a;ValueError: signal only works in main thread 基于Django 解决方法 按如下方式运行服务器 python manage.py runserver --nothreading --noreload

SpringCloud Alibaba(上):注册中心-nacos、负载均衡-ribbon、远程调用-feign

Nacos 概念&#xff1a;Nacos是阿里巴巴推出的一款新开源项目&#xff0c;它是一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos致力于帮助用户发现、配置和管理微服务&#xff0c;它提供了一组简单易用的特性集&#xff0c;包括动态服务发现、服务配置…

【Pytorch和深度学习】栏目导读

一、栏目说明 本栏目《pytorch实践》是为初学者入门深度学习准备的。本文是该栏目的导读部分&#xff0c;因为计划本栏目在明年完成&#xff0c;因此&#xff0c;导读部分&#xff0c;即本文也在持续更新中。 本栏目设计目标是将深度学习全面用pytorch实践一遍&#xff0c;由浅…

上机实验四 图的最小生成树算法设计 西安石油大学数据结构

实验名称&#xff1a;图的最小生成树算法设计 &#xff08;1&#xff09;实验目的&#xff1a; 掌握最小生成树算法&#xff0c;利用kruskal算法求解最小生成树。 &#xff08;2&#xff09;主要内容&#xff1a; 利用kruskal算法求一个图的最小生成树&#xff0c;设计Krus…

Xilinx Artix7-100T低端FPGA解码MIPI视频,基于MIPI CSI-2 RX Subsystem架构实现,提供工程源码和技术支持

目录 1、前言免责声明 2、我这里已有的 MIPI 编解码方案3、本 MIPI CSI2 模块性能及其优缺点4、详细设计方案设计原理框图OV5640及其配置权电阻硬件方案MIPI CSI-2 RX SubsystemSensor Demosaic图像格式转换Gammer LUT伽马校正VDMA图像缓存AXI4-Stream toVideo OutHDMI输出 5、…

数据校验:Spring Validation

Spring Validation概述 在开发中&#xff0c;我们经常遇到参数校验的需求&#xff0c;比如用户注册的时候&#xff0c;要校验用户名不能为空、用户名长度不超过20个字符、手机号是合法的手机号格式等等。如果使用普通方式&#xff0c;我们会把校验的代码和真正的业务处理逻辑耦…

K8S篇之etcd数据备份与恢复

一、etcd备份与恢复 基本了解&#xff1a; 1、k8s 使用etcd数据库实时存储集群中的数据&#xff0c;安全起见&#xff0c;一定要备份。 2、备份只需要在一个节点上备份就可以了&#xff0c;每个节点上的数据是同步的&#xff1b;但是数据恢复是需要在每个节点上进行。 3、etcd…

系统韧性研究(4)| 系统韧性的技术分类

系统韧性技术是任何提高系统韧性的架构、设计或实现技术。这些技术&#xff08;例如缓解措施&#xff0c;如冗余、保障措施和网络安全对策&#xff09;或被动地抵御逆境或主动检测逆境&#xff0c;并对其做出反应&#xff0c;亦或者从它们造成的伤害中恢复过来。系统韧性技术是…

ArcGIS实现矢量区域内所有要素的统计计算

1、任务需求&#xff1a;统计全球各国所有一级行政区相关属性的总和。 &#xff08;1&#xff09;有一个全球一级行政区的矢量图&#xff0c;包含以下属性&#xff08;洪灾相关属性 province.shp&#xff09; &#xff08;2&#xff09;需要按照国家来统计各个国家各属性的总值…

突然消失的桌面文件如何恢复?详细教程让你轻松解决问题!

桌面文件突然消失&#xff0c;对于很多人来说&#xff0c;可能是个令人头疼的问题。这些文件可能包含重要的信息&#xff0c;也可能是数日甚至数周的努力成果。那么&#xff0c;当这种情况发生时&#xff0c;我们如何恢复丢失的文件呢&#xff1f;本文将提供一些实用的建议。 1…

【ArcGIS Pro微课1000例】0031:las点云提取(根据范围裁剪点云)

本文讲解ArcGIS Pro3.0中,las点云数据的提取(根据范围裁剪点云)方法。 文章目录 一、加载数据二、工具介绍三、点云裁剪一、加载数据 打开ArcGIS Pro,新建地图,加载配套实验数据包中的0031.rar中的点云数据point.las与范围bound.shp,如下图所示: 二、工具介绍 名称:提…

一张图搞懂什么是BCD8421编码

如图所示 BCD8421编码的意义是 用四位二进制数表达一位的十进制数 因此十进制下的0&#xff5e;9在BCD8421编码下与其二进制表达是一样的 而多位的十进制数 比如说“10” 则需要将它拆分成两个单独的数“1”和“0” 分别用BCD8421编码表示这两个数 十进制“1” -> 0001 十进…

内衣洗衣机和手洗哪个干净?好用的内衣洗衣机推荐

在日常生活中&#xff0c;我们的衣服不可避免地会沾染上各种细菌、毛发和污渍&#xff0c;将它们与贴身衣物混合清洗&#xff0c;很容易发生交叉感染&#xff0c;而被感染后&#xff0c;贴身衣物也有可能导致我们人体引起皮肤病。这也是为什么大部分人都喜欢用手洗的原因&#…

@CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思

@CacheInvalidate 注解是 JetCache 框架提供的注解,它是由阿里巴巴开源的组织 Alibaba Group 开发和维护的。JetCache 是一款基于注解的缓存框架,提供了丰富的缓存功能和灵活的配置选项,可用于增强应用程序的性能和可扩展性。JetCache 支持多种缓存后端,包括内存缓存、Redi…

矩阵的除法

B/A 如果矩阵A可逆&#xff0c;那么 证明&#xff1a; A/AB 如果矩阵A和B都可逆&#xff0c;那么 证明&#xff1a;

基于回溯搜索算法优化概率神经网络PNN的分类预测 - 附代码

基于回溯搜索算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于回溯搜索算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于回溯搜索优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

优雅的Java编程:将接口对象作为方法参数

theme: smartblue 目录 概述 在Java编程中&#xff0c;方法的参数传递方式通常是通过基本类型、对象引用或者集合等方式。然而&#xff0c;一种更加优雅且灵活的设计模式是将接口对象作为方法的参数。这种方式为我们带来了许多好处&#xff0c;包括降低耦合性、实现多态性和可…

Jenkins 构建CICD

GitLab GitLab安装 https://gitlab.cn/install/?versionce CentOS 下安装 1. 安装和配置必须的依赖项 在 CentOS 7上&#xff0c;下面的命令也会在系统防火墙中打开 HTTP、HTTPS 和 SSH 访问。这是一个可选步骤&#xff0c;如果您打算仅从本地网络访问极狐GitLab&#xf…