史上最详细的webrtc-streamer访问摄像机视频流教程

news2024/11/19 5:57:28

目录

前言

一、webrtc-streamer的API

二、webrtc-streamer的启动命令介绍

1.原文

2.译文 

三、webrtc-streamer的安装部署

1.下载地址

    https://github.com/mpromonet/webrtc-streamer/releases

2.windows版本部署

3.Linux版本部署

四、springboot整合webrtc-streamer

五、公网使用webrtc-streamer访问相机视频


前言

最近公司在搞流媒体,我推荐了webrtc-streamer进行搭建,使用了一段时间后,出现新的需求,需要将内网的摄像机进行公网访问,我查询了几乎所有的帖子和github的问题回复,都没有给我一个准确的答案,经过不断尝试和摸索,我终于成功了,我希望将我的过程记录下来,让更多的中国开发者可以少走弯路,我对于webrtc不是很了解,但是这并不影响我使用开源的webrtc-streamer进行开发。

一、webrtc-streamer的API

webrtc-streamer的服务地址:192.168.1.8:8000
查询所有api:http://192.168.1.8:8000/api/help
[
	"/api/addIceCandidate",
	"/api/call",
	"/api/createOffer",
	"/api/getAudioDeviceList",
	"/api/getIceCandidate",
	"/api/getIceServers",
	"/api/getMediaList",
	"/api/getPeerConnectionList",
	"/api/getStreamList",
	"/api/getVideoDeviceList",
	"/api/hangup",
	"/api/help",
	"/api/log",
	"/api/setAnswer",
	"/api/version"
]

关键api:/api/getPeerConnectionList

我使用它来判断当前的webrtc-streamer正在连接的通道

2个通道:

ICE: 交互式连接建立(Interactive Connectivity Establishment)

ice_state:交互式连接状态(2:已连接/5:断开连接)

pc_state:客户端连接状态(2:正常/3:断开)

  • 已连接:

"ice_state": 2

"pc_state": 2

  • 正在断开:

"ice_state": 5

"pc_state": 3

  • 这种状态未知:

"ice_state": 0

"pc_state": 0

  • 断开:

无任何json数据

正常连接的json如下(sdp内容过多已删除):

[

  {

    "0.07123060004985127": {

      "ice_state": 2,

      "pc_state": 2,

      "sdp": "",

      "signaling_state": 0,

      "streams": {

        "15661718658374446496": {

          "15661718658374446496_video": {

            "kind": "video",

            "state": 1

          }

        }

      }

    }

  }

  ]

二、webrtc-streamer的启动命令介绍

1.原文


./webrtc-streamer [-H http port] [-S[embeded stun address]] -[v[v]]  [url1]...[urln]
./webrtc-streamer [-H http port] [-s[external stun address]] -[v[v]] [url1]...[urln]
./webrtc-streamer -V
    	-v[v[v]]           : verbosity
    	-V                 : print version
    	-H [hostname:]port : HTTP server binding (default 0.0.0.0:8000)
	-w webroot         : path to get files
	-c sslkeycert      : path to private key and certificate for HTTPS
	-N nbthreads       : number of threads for HTTP server
	-A passwd          : password file for HTTP server access
	-D authDomain      : authentication domain for HTTP server access (default:mydomain.com)

	-S[stun_address]                   : start embeded STUN server bind to address (default 0.0.0.0:3478)
	-s[stun_address]                   : use an external STUN server (default:stun.l.google.com:19302 , -:means no STUN)
	-t[username:password@]turn_address : use an external TURN relay server (default:disabled)
	-T[username:password@]turn_address : start embeded TURN server (default:disabled)

	-a[audio layer]                    : spefify audio capture layer to use (default:0)		
	-q[filter]                         : spefify publish filter (default:.*)
	-o                                 : use null codec (keep frame encoded)

	-C config.json                     : load urls from JSON config file 
	-R [Udp port range min:max]        : Set the webrtc udp port range (default 0:65535)

	-n name -u videourl -U audiourl    : register a name for a video url and an audio url
[url]                              : url to register in the source list

2.译文 

./webrtc-streamer [-H http port] [-S[embeded stun address]] -[v[v]]  [url1]...[urln] 
./webrtc-streamer [-H http port] [-s[external stun address]] -[v[v]] [url1]...[urln]
./webrtc-streamer -V
    -v[v[v]]           : verbosity
    -V                 : 打印版本
    -H [hostname:]port : HTTPServer绑定 (default 0.0.0.0:8000)
	-w webroot         : 获取文件的路径
	-c sslkeycert      : HTTPS的私钥和证书路径
	-N nbthreads       : HTTP服务器的线程数
	-A passwd          : 用于HTTP服务器访问的密码文件
	-D authDomain      : HTTP服务器访问的身份验证域(默认值:mydomain.com)
	-S[stun_address]                   : 使用嵌入的STUN服务器绑定到地址(默认值为0.0.0.0:3478)
	-s[stun_address]                   : 使用外部的STUN服务器绑定到地址(默认值为0.0.0.0:3478)
	-t[username:password@]turn_address : 使用外部TURN中继服务器(默认:禁用)
	-T[username:password@]turn_address : 使用嵌入式TURN中继服务器(默认:禁用)
	-a[audio layer]                    : 指定要使用的音频捕获层(默认值:0)	
	-q[filter]                         : 指定发布筛选器(默认值:.*)
	-o                                 : 使用空编解码器(保持帧编码)
	-C config.json                     : 从JSON配置文件加载URL
	-R [Udp port range min:max]        : 设置webrtc-udp端口范围(默认值为0:65535)
	-n name -u videourl -U audiourl    : 注册视频url和音频url的名称
	[url]                              : 要在源列表中注册的url

举例:

指定绑定ip端口:./webrtc-streamer -H 192.168.1.8:8123

注意几个细节:

1、-o 这个命令务必要加上,不加的话你会发现你的cpu预览几路马上飙升到100%。

2、 -s/-S/-t/-T这几个命令后面不要有空格。

3、只支持H264的视频码流,H265不支持。

三、webrtc-streamer的安装部署

1.下载地址

    https://github.com/mpromonet/webrtc-streamer/releases

     目前最新版本0.7.2版本

     

 红框内分别为windows版本和Linux版本。

2.windows版本部署

下载windows版本压缩包,解压后如下图

 在当前目录下输入命令webrtc-streamer.exe -H 192.168.1.227:8000 -o

再次强调 -o  为了不转码,进而降低cpu负荷。

3.Linux版本部署

         系统环境都正常的情况安装步骤如下:

        1.webrtc-streamer包:webrtc-streamer-v0.7.2-Linux-x86_64-Release.tar.gz

        2.拷贝到root下,解压:tar -xvf webrtc-streamer-v0.7.2-Linux-x86_64-Release.tar.gz

        3.进入webrtc-streamer-v0.7.2-Linux-x86_64-Release:cd webrtc-streamer-v0.7.2-Linux-x86_64-Release

        

        4.执行 ./webrtc-streamer -H 192.168.1.10:8000 -o

        

         Linux大概率会报错缺少环境,这个自行搜索解决。如果实在解决不了,给我留言吧。

四、springboot整合webrtc-streamer

             这部分我就快速贴代码了。

           1、前端部分:

                   项目需要引入的js:webrtcstreamer.js、adapter.min.js、jquery-1.7.1.min.js

                   我这里配置了24个video用来测试,分别支持宇视、大华、海康的RTSP流。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="adapter.min.js"></script>
    <script type="text/javascript" src="webrtcstreamer.js"></script>
    <script type="text/javascript" src="jquery-1.7.1.min.js"></script>
    <style>
        video {
            width: 300px;
            height: 200px;
        }
    </style>
</head>
<body>
<p>视频播放</p>
<div>
    <video id="video1" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video2" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video3" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video4" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video5" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video6" muted autoplay loop controls>muted controls disablePictureInPicture</video>
</div>
<div>
    <video id="video7" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video8" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video9" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video10" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video11" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video12" muted autoplay loop controls>muted controls disablePictureInPicture</video>
</div>
<div>
    <video id="video13" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video14" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video15" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video16" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video17" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video18" muted autoplay loop controls>muted controls disablePictureInPicture</video>
</div>
<div>
    <video id="video19" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video20" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video21" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video22" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video23" muted autoplay loop controls>muted controls disablePictureInPicture</video>
    <video id="video24" muted autoplay loop controls>muted controls disablePictureInPicture</video>
</div>
<script>
    var cameralist = new Array();
    var camera64 = {type: "hik", ipaddr: "192.168.1.64", username: "admin", password: "hik12345", port: 554};
    window.onload = function () {
        // 初始化内容
        cameralist.push(camera64);
        console.log(cameralist);
    }
    let num = 0;

    function getCamera() {
        let obj = cameralist[num];
        console.log(obj);
        num++;
        if (num == 1) {
            num = 0;
        }
        return obj;
    }

    let webRtcServer = null;
    let videoMap = new Map();
    $('video').click(function (e) {
        let ID = e.target.id;//获取当前点击事件的元素
        console.log(ID);
        if (videoMap.get(ID) != null) {
            closeVideo(ID, videoMap.get(ID));
        } else {
            let camera = getCamera();
            console.log(camera);
            if (camera.type == "ys") {
                realViewYs("192.168.1.11", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            } else if (camera.type == "dh") {
                realViewDh("192.168.1.11", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            } else {
                realViewHik("112.98.126.2", ID, camera.username, camera.password, camera.ipaddr, camera.port);
            }
        }
    });


    //预览海康相机
    function realViewHik(serverip, elem, username, password, ipaddr, port) {
        webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":28000");
        let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/ch1/main/av_stream";
        let option = "rtptransport=tcp";
        console.log("rtsp地址:" + rtspUrl);
        webRtcServer.connect(rtspUrl, null, option, null);
        videoMap.set(elem, webRtcServer);
    }

    //预览大华相机
    function realViewDh(serverip, elem, username, password, ipaddr, port) {
        webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":8000");
        let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/cam/realmonitor?channel=1&subtype=0";
        let option = "rtptransport=tcp";
        console.log("rtsp地址:" + rtspUrl);

        webRtcServer.connect(rtspUrl, null, option, null);
        videoMap.set(elem, webRtcServer);
    }

    //预览宇视相机
    function realViewYs(serverip, elem, username, password, ipaddr, port) {
        webRtcServer = new WebRtcStreamer(elem, "http://" + serverip + ":8000");
        let rtspUrl = "rtsp://" + username + ":" + password + "@" + ipaddr + ":" + port + "/media/video1/multicast";
        console.log("rtsp地址:" + rtspUrl);
        let option = "rtptransport=tcp";
        webRtcServer.connect(rtspUrl, null, option, null);
        videoMap.set(elem, webRtcServer);
    }

    function closeVideo(id, webrtc) {
        webrtc.disconnect();
        videoMap.delete(id);
    }

    //页面退出时销毁
    // window.onbeforeunload = function () {
    //     alert("页面关闭");
    //     webRtcServer.disconnect();
    // }
    //页面离开或者浏览器关闭的时候触发
    window.onbeforeunload = function (event) {
        $.ajax({
            // url: "../getIp",
            url: "http://127.0.0.1:12344/ard/videocall",
            type: "post",
            contentType: "application/json",
            dataType: "json",
            data: JSON.stringify({"cmd": "close", "url": "https://anruida.app.zihai.shop/?id=zns&pass=ard"}),
            success: function (data) {
            }
        });
        webRtcServer.disconnect();
    };

</script>

        2、后端部分

        后端部分简单多了,初学者应该都会吧,直接配置个controller找这个html就行了。

@GetMapping("/")
    String index() {
        return "view";
    }

启动项目打开127.0.0.1:8080

至此,局域网内访问相机视频就完成了。

五、公网使用webrtc-streamer访问相机视频

通过上面的步骤局域网内访问相机视频流已经可以实现了,但是如果你想把项目部署到公网中进行访问就不行了。

公网部署步骤:

1、配置webrtc-streamer所在服务器的内网穿透地址,例如内网192.168.1.8:8000 映射到公网为110.154.21.14:18000

2、部署一个本地coturn服务器,配置conturn服务器配置文件,同时将conturn服务器的3478的tcp和udp端口进行公网映射。

3、前端js页面使用公网地址也就是110.154.21.14:18000配置webrtc-streamer

4、启动命令增加turn和stun服务器:webrtc-streamer.exe -o -H 192.168.1.8:8000 -S110.154.21.14:3478 -Tadmin:123456@110.154.21.14:3478

正式开始:

第一步,使用路由器将webrtc内网映射到公网,这个我相信你玩这个肯定会,不同的交换机配置不同。

第二步,Linux下WebRTC搭建私有turn/stun服务,目前coturn只支持linux。

            coturn是一个免费的开源的TURN/STUN服务器。coturn 服务器完整的实现了STUN/TURN/ICE协议,支持P2P穿透防火墙。
            STUN 服务器用于获取设备的外部网络地址。
            TURN 服务器是在点对点失败后用于通信中继。
            WebRTC 建立连接的步骤大概是这样的:
            客户端(浏览器)直接尝试直连;
            如果如果直连则通过 STUN 服务器进行穿透;
            如果无法穿透则通过 TURN 服务器进行中转。

1. 安装前准备
	http://libevent.org/ 下载 libevent-2.1.12-stable.tar.gz
	wget https://github.com/coturn/coturn/archive/4.5.1.1.tar.gz 下载 conturn-4.5.1.1.tar.gz (稳定版本)
	(如果undefined reference to `SSL_CTX_up_ref'的错误换用稳定版本就好了。)
2. 安装gcc
	yum install gcc-c++
3. 安装openssl-devel 
	yum -y install openssl-devel
4. 安装libevent2
	在http://libevent.org/下载libevent-2.1.8-stable.tar.gz
	tar -zxvf libevent-2.1.8-stable.tar.gz
	cd libevent-2.1.8-stable
	./configure --prefix=/usr --libdir=/usr/lib64 (如果报错试试这个方式:./configure --prefix=/usr/local/coturn)
	make
	make install
	成功没有出现报错信息
5. 安装conturn-4.5.1.1
	tar -zxvf 4.5.1.1.tar.gz
	cd coturn-4.5.1.1
	./configure
	make
	make install

	可以通过which turnserver验证。如果出现路径即为成功
	
6. 配置文件和签名,然后进入文件夹:
	cd /usr/local/etc/ 会看到一个叫做 turnserver.conf.default的配置文件。将它备份:
	cp turnserver.conf.default turnserver.conf
7. 在当前文件夹生成签名(自行输入):
	openssl req -x509 -newkey rsa:2048 -keyout /usr/local/etc/turn_server_pkey.pem -out /usr/local/etc/turn_server_cert.pem -days 99999 -nodes
8. 修改配置文件
	Vim turnserver.conf  参考如下
	relay-device=eth0
	listening-ip=#内网IP
	listening-port=3478
	tls-listening-port=5349
	relay-ip=#内网IP
	external-ip=#公网IP
	relay-threads=50
	lt-cred-mech
	min-port=49152
	max-port=65535
	cert=/usr/local/etc/turn_server_cert.pem
	pkey=/usr/local/etc/turn_server_pkey.pem
	pidfile=”/var/run/turnserver.pid”
	user=admin:123456
	cli-password=123456
	将配置文件更新如上。
	   请一定要设置cli-password这一项,不设置会报错。
	   注意检查cert和pkey的路径和名称。检查内网ip和公网ip是否填写准确。
	   注意文本格式准确。
9. 启动turnserver
	turnserver -o -a -f -user=admin:123456 -c /usr/local/etc/turnserver.conf -r xiamen
	-o 是让程序在后台启动
	-r 后面填个地区就行。
	-user 一定要和配置文件中一样。
	
	ps -ef|grep turnserver 指令查看是否启动服务,如果有
10. 验证
	Trickle ICE:https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/
	1、stun:+公网IP+端口,测试出现公网IP则代表部署成功
	2、turn:+公网IP+端口,测试出现公网IP则代表部署成功

    可能出现的问题:

1、libevent configure: error: OpenSSL could not be found. You should add the directory解决办法

        直接在线安装:yum -y install openssl-devel

2、yum 安装软件报错 : There are no enabled repos.

        可能是相关yum源被删除了:

        wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

        yum clean all && yum makecache


 只需要做webrtc-streamer服务器的tcp:8000端口、coturn服务器的tcp/udp:3478端口的映射即可。

相机的地址不需要映射。

至此公网访问视频流完成!有问题请留言。

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

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

相关文章

技术不断变革,亚马逊云科技中国峰会引领企业重塑业务

过去十年&#xff0c;数字化转型的浪潮携带着机遇和挑战席卷而来&#xff0c;几乎每个企业都在做数字化转型&#xff0c;开始向大数据、人工智能等新技术寻求生产力的突破。但随着数字化转型深入&#xff0c;很多企业开始感受到数字化投入的成本压力&#xff0c;加之新技术正带…

Alibi:Attention With Linear Biases Enables Input Length Extrapolation

Alibi:Attention With Linear Biases Enables Input Length Extrapolation IntroductionMethodResult参考 Introduction 假设一个模型在512token上做训练&#xff0c;在推理的时候&#xff0c;模型在更长的序列上表现叫做模型的外推性。作者表明以前的位置编码如Sin、Rotary、…

JS 数据变化监听函数封装

文章目录 监听函数使用用例重复添加函数&#xff0c;只有最后一个监听函数有效 监听函数 /*** 监听函数* param {对象} vm * param {键值} key * param {触发函数} action */ function WatchValueChange(vm, key, action) {var val vm[key]Object.defineProperty(vm, key, {e…

阿里内部流传出来的《1000 道互联网大厂 Java 工程师面试题》来袭,面试必刷,跳槽大厂神器

眼看着"金九银十"也快到来了&#xff0c;很多小伙伴都蠢蠢欲动想要刚给自己涨一波薪资&#xff1b;面试作为涨薪最直接最有效的方式&#xff0c;我们需要花费巨大的精力和时间来准备。除了自身的技术积累之外&#xff0c;掌握一定的面试技巧和熟悉最常见的面试题&…

掌握imgproc组件:opencv-图像轮廓与图像分割修复

图像轮廓与图像分割修复 1.查找并绘制轮廓1.1 寻找轮廓&#xff1a;findContours()函数1.2 绘制轮廓&#xff1a;drawContours()函数1.3 案例程序&#xff1a;轮廓查找 2. 寻找物体的凸包2.1 凸包2.2 寻找凸包&#xff1a;convexHull()函数2.3 案例&#xff1a;寻找和绘制物体的…

【前端|CSS系列第1篇】CSS零基础入门之CSS的基本概念和选择器

欢迎来到CSS零基础入门系列的第一篇博客&#xff01;在这个系列中&#xff0c;我们将一起学习CSS&#xff08;层叠样式表&#xff09;的基础知识&#xff0c;探索如何为网页添加样式和布局。本篇博客将重点介绍CSS的基本概念和选择器&#xff0c;帮助你理解CSS的核心概念。 1.…

MAYA活塞(使用骨骼)

复制骨骼 P父子关系 创建组

根据数组中对象的某个字段分组最简洁方式

使用map数据结构的&#xff0c;键值唯一性进行操作 //根据年龄分组&#xff0c;获取目标数据格式//[{key:key,data:[{}]}]//{key:[]}const arr [{ name:test1,age:10},{ name:test2,age:20},{ name:test3,age:10},{ name:test4,age:20},{ name:test5,age:10},{ name:test6,age…

群晖 NAS WebDAV服务手机ES文件浏览器远程访问

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址6. 使用固定地址测试连接 转载自cpolar极点云文章&#xff1a;群晖NAS搭建WebDAV服务手机ES文件浏览器远程访问 有时候我们想通过移动设备访问群晖NAS 中的文件,以满足特殊需求,…

centos7安装zabbix v4

1.获取rpm包 wget -c https://mirrors.aliyun.com/zabbix/zabbix/4.0/rhel/7/x86_64/zabbix-release-4.0-2.el7.noarch.rpm 2.安装 yum install zabbix-release-4.0-2.el7.noarch.rpm -y 3.关防火墙和selinux 4.下载数据库 yum install mariadb -y 5.启动数据库设置密码 …

UE4 Cesium离线生成地形

地理空间数据云 首先进这个网址&#xff0c;下载对应的tif以及高程&#xff08;DEM&#xff09; 下载CesiumLab2 在地形切片中点击添加&#xff0c;将黑白图像数据&#xff0c;添加&#xff0c;选择存储类型为散列文件&#xff0c;选择输出路径 再选择影像切片&#xff0c;选择…

Redis 数据类型 | Navicat 数据编辑器

Redis 有别于其他键值&#xff08;key-value&#xff09;存储的一个关键特性是它支持多种数据类型&#xff0c;包括字符串&#xff08;string&#xff09;、列表&#xff08;list&#xff09;、集合&#xff08;set&#xff09;、排序集合&#xff08;sorted set&#xff09;和…

Sparse Fuse Dense: 向高质量的深度补全3D目标检测迈进

点云的稀疏性&#xff1a;在远距离和遮挡区域提供的信息较差&#xff0c;导致难以生成精确的3D边界框。 出现了多模态融合。 图像和点云的不同表示方式使得它们难以融合&#xff0c;导致性能不佳。 论文提出了一种新颖的多模态框架SFD&#xff08;Sparse Fuse Dense&#xf…

Docker学习笔记14

容器镜像在Docker host的存储位置&#xff1a; 最上面的层&#xff08;layer&#xff09;为读写层&#xff0c;也就是容器。下面的其他的层都是只读层的镜像层。并且除了最下面的一层外&#xff0c;其他的层都有一个指针指向自己下面的一层镜像&#xff08;联合文件系统&#…

SpringMVC入门篇2 --- 请求与响应

目录 1.请求映射路径 在类上面统一设置RequestMapping注解&#xff0c;统一设置访问路径前缀。 在上文案例的基础上进行修改。 src/main/java/org/example/controller/UserController.java package org.example.controller;import org.springframework.stereotype.Controll…

寻寻觅觅,彩电厂商能否“智”取未来?

彩电业&#xff0c;还能不能好&#xff1f; 电视行业的发展&#xff0c;一直伴随着漫长的价格战。从黑白到彩电再到超大屏&#xff0c;从CRT到平板再到液晶&#xff0c;在每一轮技术革新之后&#xff0c;市场总会经历从落到起&#xff0c;从起到落的循环&#xff0c;然后陷入价…

重磅!2023年影响因子正式发布 , Nature/Science等顶刊普遍下降 (附名单下载)~

2023年6月28日&#xff0c;科睿唯安&#xff08;Clarivate Analytics&#xff09;发布了最新年度期刊引证报告(JCR), 其中包含我们所关注的最新影响因子(Impact Factor, IF). 科研界对每年影响因子发布可谓是翘首以待&#xff0c;据小编统计发现&#xff0c;今年的影响因子普遍…

安科瑞故障电弧探测器在建筑电气的设计与应用

安科瑞 崔丽洁 【摘要】&#xff1a;电气设备是建筑中不可缺少的一部分&#xff0c;具有较为重要的作用和意义&#xff0c;在应用过程中不仅能够提升建筑本身实用性能&#xff0c;而且可为消费者提供更加优良的生活环境。但设备一旦在运行过程中出现故障&#xff0c;不仅会影响…

使用python3的sqlalchemy+sqlcipher3对sqlite3数据加密,使用pysqlcipher3编译打建环境,并写项目测试

一、背景 最近有个想法&#xff0c;想写一个软件&#xff0c;前期本来想用java的springboot加vue来实现&#xff0c;数据库选sqlite来存储&#xff0c;但在用spingboot框架搭好之后&#xff0c;感觉这款软件更适合用python来写&#xff0c;java不适windows桌面系统&#xff0c…

Spring Boot 中的 Environment

Spring Boot 中的 Environment 在 Spring Boot 中&#xff0c;Environment 是一个重要的组件&#xff0c;用于管理应用程序的配置。它是一个接口&#xff0c;提供了访问应用程序配置属性的方法。在本文中&#xff0c;我们将深入探讨 Spring Boot 中的 Environment&#xff0c;…