百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

janus对webRTC封装的api相关属性,方法的说明

toyiye 2024-07-06 00:15 19 浏览 0 评论

1.JavaScript API的核心是Janus对象。

第一次在页面中使用该对象时,需要对其进行初始化。可以使用init对象的静态方法来完成此操作,该方法接受以下选项:

  • debug:
  • 是否应在JavaScript控制台上启用调试,以及在什么级别上进行调试
    • true或"all":启用所有调试器(Janus.trace,Janus.debug,Janus.log,Janus.warn,Janus.error)
    • 数组(例如["trace", "warn"]):仅启用选定的调试器(允许的令牌:跟踪,调试,日志,警告,错误)
    • false: 禁用所有调试器
  • callback: 初始化完成时调用的用户提供的函数
  • dependencies: 用户提供的Janus库依赖关系的实现

这是一个例子:

import * as Janus from './janus.es.js'
Janus.init({
debug: true,
dependencies: Janus.useDefaultDependencies(), 
// or: Janus.useOldDependencies() to get the behaviour of previous Janus versions
callback: function() {
// Done!
});

库初始化后,就可以开始创建会话了。通常,每个浏览器选项卡都需要与服务器进行单个会话:实际上,每个Janus会话可以同时包含多个不同的插件句柄,这意味着您可以使用相同或不同的插件为同一用户启动多个不同的WebRTC会话,以便使用相同的Janus会议。也就是说,您可以随意在同一页面上设置不同的Janus会话。

创建会话非常容易。您只需要使用new构造函数来创建一个新Janus对象即可处理与服务器的交互。考虑到Janus会话的动态和异步性质(事件可能随时发生),在创建会话时可以配置一些属性和回调:

  • server:服务器的地址作为特定地址(例如,使用纯HTTP API的http:// yourserver:8088 / janus或对于WebSockets使用ws:// yourserver:8188 /)或作为地址数组以顺序尝试在设置过程中自动进行回退/故障转移;
  • iceServers: 要使用的STUN / TURN服务器列表(如果跳过此属性,将使用默认的STUN服务器);
  • ipv6: 是否应收集IPv6候选人;
  • withCredentials:是否withCredentials应启用XHR请求的属性(默认情况下为false,仅在将HTTP用作传输方式时有效,而对于WebSockets则无效);
  • max_poll_events:轮询时应返回的事件数;默认值是1(轮询返回一个对象),传递一个更大的数字将使后端返回一个对象数组(再次,仅对HTTP使用有效,因为它与长轮询严格相关,对于WebSockets则被忽略);
  • destroyOnUnload:是否应在销毁时通过Janus API自动销毁并尝试销毁此会话onbeforeunload(默认情况下为true);
  • token,apisecret:可选参数,仅在验证Janus API时才需要;
  • 一组用于通知事件的回调,即:
    • success: 会话已成功创建并可以使用;
    • error: 会话未成功创建;
    • destroyed: 会话已被破坏,无法再使用。

这些属性和回调作为单个参数对象的属性传递给方法:即,Janus构造函数采用单个参数,尽管该参数充当所有可用选项的容器。该success回调您一般在其中启动应用程序逻辑,例如,对等连接到一个插件,并开始媒体会话。

这是一个例子:

var janus = new Janus(
{
server: 'http://yourserver:8088/janus',
//server: 'ws://yourserver:8188/',
//server: ['ws://yourserver:8188/','http://yourserver:8088/janus'],
success: function() {
// Done! attach to plugin XYZ
},
error: function(cause) {
// Error, can't go on...
},
destroyed: function() {
// I should get rid of this
}
});

创建后,该对象代表您与服务器的会话。您可以通过Janus几种不同的方式与对象进行交互。特别是,定义了以下属性和方法:

  • getServer():返回服务器的地址;
  • isConnected():true如果Janus实例已连接到服务器,false则返回;否则返回;否则返回false 。
  • getSessionId():返回唯一的Janus会话标识符;
  • attach(parameters):将会话附加到插件,创建一个句柄;可以同时创建更多相同或不同插件的句柄;
  • destroy(parameters):销毁与服务器的会话,并关闭该会话与任何插件可能具有的所有句柄(和相关的PeerConnections)。

2.最重要的属性显然是attach()方法:(如:janus.attach(arg))

因为它是使您能够利用插件的功能来操纵网页中PeerConnection发送和/或接收的媒体的方法。此方法将创建一个可用于此目的的插件句柄,可以在调用该attach()方法本身时为其配置属性和回调。对于Janus构造函数,该attach()方法采用单个参数,该参数可以包含以下任何属性和回调:

  • plugin:插件的唯一软件包名称(例如janus.plugin.echotest);
  • opaqueId: 一个对您的应用程序有意义的可选不透明字符串(例如,映射同一用户的所有句柄);
  • 一组用于通知事件的回调,即:
    • success: 该句柄已成功创建并可以使用;
    • error: 句柄未成功创建;
    • consentDialog:该回调在getUserMedia调用(parameter = true)之前和完成之后(parameter = false)触发;这意味着它可以用来相应地修改UI,例如,提示用户需要接受设备访问同意请求;
    • webrtcState:从Janus角度来看,当与句柄关联的PeerConnection处于活动状态(因此ICE,DTLS和其他所有操作都成功)时,此回调以true值触发,而当PeerConnection断开时触发false。找出WebRTC何时在您和Janus之间真正启动和运行时很有用(例如,通知用户他们实际上已经在会议中处于活动状态);注意,如果为,则原因字符串可以作为可选参数出现;
    • iceState: 当与句柄关联的PeerConnection的ICE状态更改时,将触发此回调:回调的参数是字符串形式的新状态(例如,“ connected”或“ failed”);
    • mediaState:当Janus开始或停止接收您的媒体时,将触发此回调:例如,mediaStatetype = audio和on = true的a表示Janus开始接收您的音频流(或在暂停一秒钟以上后开始重新获取它们);一个mediaState与类型=视频和=手段詹纳斯没有收到从在上一个第二任何视频,之前检测到一个启动之后; 有助于弄清楚Janus实际何时开始处理您的媒体,或检测媒体路径上的问题(例如,媒体从未启动或在某个时间停止);
    • slowLink:当Janus报告在指定的PeerConnection上发送或接收媒体发生故障时触发此回调,通常是由于最后一秒从用户接收到的NACK过多或发送给用户的NACK的结果:例如,aslowLink带有uplink = true表示您已通知多个来自Janus的数据包丢失,而上行链路= false则意味着Janus没有收到您的所有数据包;找出媒体路径上何时存在问题(例如,过多的丢失),以便可能做出相应的反应(例如,如果我们的大多数数据包丢失,则降低比特率)很有用;
    • onmessage: 从插件收到消息/事件;
    • onlocalstream:本地MediaStream可用并且准备显示;
    • onremotestream:遥控器MediaStream可用并准备显示;
    • ondataopen: 数据通道可用并准备使用;
    • ondata: 数据已通过数据通道接收;
    • oncleanup: 与插件的WebRTC PeerConnection已关闭;
    • detached: 插件句柄已被插件本身分离,因此不应再使用。

这是一个例子:

//使用先前创建的janus实例附加到回声测试插件
janus.attach(
{ 
plugin:“ janus.plugin.echotest”,
success:function(pluginHandle){ 
//附加的插件!'pluginHandle'是我们的句柄
},
error:function(cause){ 
//无法连接到插件
},
consentDialog:function(on){ 
//例如,如果on = true(使getUserMedia传入)则使屏幕变暗,否则将其还原
},
onmessage:function(msg ,jsep){
// //我们从插件获得了消息/事件(msg)
// //如果jsep不为null,则涉及WebRTC协商
},
onlocalstream:function(stream){ 
//我们要显示一个本地流(getUserMedia工作!)
},
onremotestream:function(stream){ 
//我们要显示一个远程流(正在运行PeerConnection!)
},
oncleanup:function(){ 
// PeerConnection关闭了插件,清理了UI 
//插件句柄仍然有效所以我们可以创建一个新的
},
detached:function(){ 
//与插件的连接已关闭,摆脱了其功能
//插件句柄不再有效
} 
});

因此,该attach()方法允许您附加到插件,并指定在此交互中发生任何相关事件时要调用的回调。要与插件进行主动交互,可以使用回调(在示例中为pluginHandle)Handle返回的对象success。

该Handle对象有几种方法可用于与插件交互或检查会话句柄的状态:

  • getId():返回唯一的句柄标识符;
  • getPlugin():返回附加插件的唯一软件包名称;
  • send(parameters):向插件发送一条消息(使用jsep或不使用jsep来协商PeerConnection);
  • createOffer(callbacks):要求图书馆创建符合WebRTC的优惠;
  • createAnswer(callbacks):要求图书馆创建符合WebRTC的ANSWER;
  • handleRemoteJsep(callbacks):要求库处理传入的符合WebRTC的会话描述;
  • dtmf(parameters):在PeerConnection上发送DTMF音调;
  • data(parameters):通过数据通道(如果可用)发送数据;
  • getBitrate():获取当前接收到的流比特率的详细描述;
  • hangup(sendRequest):告诉库关闭PeerConnection;如果将可选sendRequest参数设置为true,则hangup还将Janus API请求也发送到Janus(默认情况下处于禁用状态,Janus通常可以通过DTLS警报等来解决此问题,但有时启用它可能很有用);
  • detach(parameters):与插件分离并销毁句柄,并删除相关的PeerConnection(如果存在)。

尽管HandleAPI看起来很复杂,但是一旦您理解了这个概念,它实际上就非常简单了。可能需要更多努力才能理解的唯一步骤是PeerConnection协商,但是同样,如果您熟悉WebRTC API,Handle实际上会使它变得容易得多。

其用法背后的想法如下:

  1. 您attach()用来创建Handle对象;
  2. 在success回调中,您的应用程序逻辑可以开始:您可能想向插件(send({msg}))发送消息,立即与插件协商PeerConnection(createOffer后跟send({msg, jsep})),或等待发生任何事情来做任何事情;
  3. 该onmessage回调告诉你,当你有来自插件的消息; 如果jsep参数不为空,则将其传递给库,库将为您处理;如果是OFFER使用createAnswer(后跟asend({msg, jsep})来关闭与插件的循环),否则使用handleRemoteJsep;
  4. 无论您是主动设置PeerConnection还是插件进行设置,onlocalstreamand和/或onremotestream回调都将为您提供可以在页面中显示的流;
  5. each plugin may allow you to manipulate what should flow through the PeerConnection channel: the send method and onmessage callback will allow you to handle this interaction (e.g., to tell the plugin to mute your stream, or to be notified about someone joining a virtual room), while the ondata callback is triggered whenever data is received on the Data Channel, if available (and the ondataopen callback will tell you when a Data Channel is actually available).

3.HandleAPI提供的协商机制:janus.attach({success:function(handle){

// handle api提供的协商机制

}})

以下段落将更深入地探讨HandleAPI提供的协商机制,特别是描述可能涉及的属性和回调。为了遵循W3C WebRTC API概述的方法,此协商机制也很大程度上基于异步方法。请注意,以下段落介绍了第一个协商步骤,即从头开始创建新的PeerConnection的步骤:知道如何发起或处理重新协商(例如,添加/删除/替换媒体源,或强制执行ICE)重新启动),而是检查“更新现有的PeerConnection(重新协商)”部分。

3.1createOffer对象

  • createOffer
  • 采用单个参数,该参数可以包含以下任何属性和回调:
    • media:
    • 您可以使用此属性来告知图书馆您感兴趣的媒体(音频/视频/数据),以及是否要发送和/或接收它们中的任何一种;默认情况下,双向都启用了音频和视频,而禁用了数据通道;该选项是一个对象,可以采用以下任何属性:
      • audioSend: true/false (发送或不发送音频);
      • audioRecv: true/false (是否接收音频);
      • audio: true/false(执行或不发送接收音频,优先于以上所述);
      • audio:具有deviceId属性的对象(指定要捕获的音频设备的ID,在上面具有优先权;可以使用访问设备列表Janus.listDevices(callback));
      • videoSend: true/false (发送或不发送视频);
      • videoRecv: true/false (接收或不接收视频);
      • video: true/false(无论是否发送接收视频,优先于以上所述);
      • video: "lowres"/"lowres-16:9"/"stdres"/"stdres-16:9"/"hires"/"hires-16:9"(发送320x240 / 320x180 / 640x480 / 640x360 / 1280x720视频,优先于上述视频;默认值为"stdres")。此属性将影响库将发出的最终getUserMedia;请注意,Firefox不支持这些"16:9"变体,这些变体将回退到这些变体;此外,"hires"并且"hires-16:9"目前是同义词,因为目前尚无4:3的高分辨率约束;
      • video: "screen" (为视频使用屏幕共享,禁用音频,同时在音频和视频上都具有优先权);
      • video:用对象deviceId,width和/或height属性(指定视频设备的ID,以捕获和任选在使用分辨率,是鉴于上述的优先级上;设备列表可以与被访问Janus.listDevices(callback));
      • data: true/false (使用或不使用数据通道,默认为false)
      • failIfNoAudio: true/false (如果请求音频发送,但没有可用的音频设备,则getUserMedia是否应该失败,默认为false)
      • failIfNoVideo: true/false (如果请求视频发送,但没有可用的视频设备,则getUserMedia是否应该失败,默认为false)
      • screenshareFrameRate: 如果您要共享屏幕/应用程序,则可以指定帧率(默认值= 3);
    • trickle: true/false,告诉图书馆是否要使用Trickle ICE(true,默认)或不使用(false);
    • stream:可选的,仅当您通过getUserMedia请求自己获取MediaStream对象,并且希望该库使用而不是让它自己获取一个库时才传递(使该media属性无用,因为访问任何该属性都不会被读取设备);
    • 一组有关结果的通知回调,即:
      • success: 会话描述已创建(作为参数附加),可以发送给插件了;
      • error: 会话描述未成功创建;
      • customizeSdp: 您可以根据需要修改由webrtc引擎生成的sdp;
  • createAnswer
  • 采用与createOffer相同的选项,但在单个参数参数中还需要一个附加选项:
    • jsep:插件发送的会话描述(例如,在onmessage回调中接收到)作为其OFFER。

3.2createAnswer对象

无论使用createOffer还是createAnswer根据方案,您都应该jsep在success回调中返回一个有效的对象。您可以将此jsep对象附加到send请求中的消息上,以将其传递给插件,并使Janus与您的应用程序协商PeerConnection。

这是一个使用方法的示例createOffer,摘自Echo Test演示页面:

// Attach to echo test plugin
janus.attach(
{
plugin: "janus.plugin.echotest",
success: function(pluginHandle) {
// Negotiate WebRTC
echotest = pluginHandle;
var body = { "audio": true, "video": true };
echotest.send({"message": body});
echotest.createOffer(
{
// No media property provided: by default,
// it's sendrecv for audio and video
success: function(jsep) {
// Got our SDP! Send our OFFER to the plugin
echotest.send({"message": body, "jsep": jsep});
},
error: function(error) {
// An error occurred...
},
customizeSdp: function(jsep) {
// if you want to modify the original sdp, do as the following
// oldSdp = jsep.sdp;
// jsep.sdp = yourNewSdp;
}
});
},
[..]
onmessage: function(msg, jsep) {
// Handle msg, if needed, and check jsep
if(jsep !== undefined && jsep !== null) {
// We have the ANSWER from the plugin
echotest.handleRemoteJsep({jsep: jsep});
}
},
[..]
onlocalstream: function(stream) {
// Invoked after createOffer
// This is our video
},
onremotestream: function(stream) {
// Invoked after handleRemoteJsep has got us a PeerConnection
// This is the remote video
},
[..]
相反,这是一个如何使用的示例createAnswer,摘自Streaming演示页面:
// Attach to echo test plugin
janus.attach(
{
plugin: "janus.plugin.streaming",
success: function(pluginHandle) {
// Handle created
streaming = pluginHandle;
[..]
},
[..]
onmessage: function(msg, jsep) {
// Handle msg, if needed, and check jsep
if(jsep !== undefined && jsep !== null) {
// We have an OFFER from the plugin
streaming.createAnswer(
{
// We attach the remote OFFER
jsep: jsep,
// We want recvonly audio/video
media: { audioSend: false, videoSend: false },
success: function(ourjsep) {
// Got our SDP! Send our ANSWER to the plugin
var body = { "request": "start" };
streaming.send({"message": body, "jsep": ourjsep});
},
error: function(error) {
// An error occurred...
}
});
}
},
[..]
onlocalstream: function(stream) {
// This will NOT be invoked, we chose recvonly
},
onremotestream: function(stream) {
// Invoked after send has got us a PeerConnection
// This is the remote video
},
[..]

当然,这些只是几个示例,其中的场景假设一个插件只能接收(回声测试)或生成(流式)报价。一个更复杂的示例(例如,视频通话插件)将同时涉及这两者,从而允许您将报价发送给插件,或从插件中接收报价。处理这只是一个检查的事type了的jsep目的,并相应反应。

更新现有的PeerConnection(重新协商)

尽管上述JavaScript API对于大多数常见方案而言已足够,但在某些情况下,可能需要在PeerConnection上进行更新。例如,当您想要添加新的媒体源(例如,将视频添加到仅音频呼叫中),替换现有的媒体源(例如,从捕获摄像头切换到共享屏幕)或触发ICE时,就会发生这种情况由于网络更改而重新启动。所有这些操作都需要进行重新协商,这意味着需要进行新的SDP提供/答复回合以更新现有的PeerConnection。

自version以来0.2.6,Janus确实支持重新协商,并且janus.js库提供了轻松处理媒体会话更新过程的方法。更具体地讲,也有可以传递到其他属性createOffer,并createAnswer为宗旨:最上一节中所介绍的属性将仍然是可用的,因为它会在接下来的段落更清晰。

你可以传递给新的属性media在createOffer和createAnswer主要有以下几种:

  • addAudio: 如果已设置,则开始捕获音频(如果尚未捕获)(如果已经发送音频,则将失败);
  • addVideo: 如果已设置,则如果不是,则开始捕获视频(如果已经发送视频,则将失败);
  • addData:如果已设置,请协商一个不存在的数据通道(实际上只是的同义词data:true);
  • removeAudio: 如果已设置,请停止捕获音频并删除本地音频轨道;
  • removeVideo: 如果已设置,请停止捕获视频并删除本地视频轨道;
  • replaceAudio: 如果已设置,则停止捕获当前音频(删除本地音频轨道),并捕获新的音频源;
  • replaceVideo: 如果已设置,则停止捕获当前视频(删除本地视频轨道),然后捕获新的视频源。

请注意,只有在尝试重新协商时才会处理这些属性,而在创建新的PeerConnection时将忽略这些属性。

这些属性不会替换现有media属性,而是将它们一起使用。例如,当添加新的视频流或替换现有的视频流时,您仍可以像以前一样使用与视频相关的属性,例如,传递特定的设备ID或要求屏幕共享而不是摄像机。此外,请注意,您当前还必须在想要保留的流上传递信息,否则它们可能会被删除:这意味着,例如,如果您要替换视频源,但希望将音频保留为是的,传递audio:false给新的createOffer可能会禁用音频。

重要的是要指出,至于首先导致创建新PeerConnection的协商,实践中如何进行重新协商通常会因要尝试使用的插件而异。一些插件可能允许您提供重新协商,而另一些插件可能需要您发送其他请求,才能触发该插件的重新协商。稍后将更加清楚,对于ICE重新启动尤其如此。因此,除了本节介绍的通用定义和与核心相关的定义之外,请参考每个插件的文档,以获取有关如何在特定用例中进行重新协商的更多信息。

这是一个简单的示例,说明如何使用removeVideo它在会话中(例如在EchoTest演示中)删除本地视频捕获:

//删除本地视频
echotest.createOffer(
{
media: { removeVideo: true },
success: function(jsep) {
Janus.debug(jsep);
echotest.send({message: {audio: true, video: true}, "jsep": jsep});
},
error: function(error) {
bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
});

此其他示例显示了如何将新视频流添加到仅音频PeerConnection中:

//添加本地视频
echotest.createOffer(
{
media: { addVideo: true },
success: function(jsep) {
Janus.debug(jsep);
echotest.send({message: {audio: true, video: true}, "jsep": jsep});
},
error: function(error) {
bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
});

最后,此示例通过显示如何将其与上一节中已经介绍的属性之一结合起来,展示了如何替换视频轨道:

//替换本地视频
echotest.createOffer(
{
media: {
video: {
deviceId: "44f4740bee234ce6ddcfea8e59e8ed7505054f75edf27e3a12294686b37ff6a7"
},
replaceVideo: true
},
success: function(jsep) {
Janus.debug(jsep);
echotest.send({message: {audio: true, video: true}, "jsep": jsep});
},
error: function(error) {
bootbox.alert("WebRTC error... " + JSON.stringify(error));
}
});

请注意,涉及媒体更改(本地和远程)的重新协商可能会导致对onlocalstream和onremotestream应用程序回调的新调用:因此,准备好在媒体会话过程中看到这些回调针对同一PeerConnection多次调用。

ICE重启

尽管可以通过重新协商来重新启动ICE,但它们的复杂性足以应有专门的小节。实际上,ICE重新启动并不能解决媒体中的更改,而只能解决基础传输本身中的更改。例如,当网络发生变化(例如IP地址已更改,或者用户从WiFi切换到4G)时,就会使用它们。为了使它起作用,必须交换新的候选者,并且必须重新启动连接性检查才能找到新的最佳路径。

使用janus.js,您只能在发送新报价时强制ICE重新启动。为此,您需要做的就是将其添加iceRestart:true到createOffer呼叫中,并且将要求ICE重新启动。以下示例显示了如何使用EchoTest完成此操作:

echotest.createOffer({
iceRestart: true,
media: { data: true },
success: function(jsep) {
echotest.send({message: {audio: true, video: true}, jsep: jsep});
}
});

在此特定示例中,我们不要求对媒体流进行任何更改,而只是要求ICE重新启动。如果成功,则客户端和Janus将在收到答案后立即重新启动ICE进程,并为媒体数据包找到新路径。

请注意,使用Janus及其插件,您将无法始终通过自己发送新的SDP报价来强制ICE重新启动:某些插件(例如Streaming插件)将希望始终自己发送报价,这意味着从协商的角度来看,它们实际上是迫使ICE重新启动的人。为了仍然允许用户实际发起该过程,所有假定他们将为其部分或全部媒体流发送报价的库存Janus插件还公开了API,以强制从服务器端重新启动ICE。您可以在此处和此处在插件级别上了解有关此内容的更多信息。此外,请确保您已阅读了有关使用ICE重启感兴趣的每个插件的文档,因为那里通常会提供有关如何正确执行它的详细信息。

就是这个!有关API的更多信息,请查看此软件包html文件夹中的演示页面。

相关推荐

如何用 coco 数据集训练 Detectron2 模型?

随着最新的Pythorc1.3版本的发布,下一代完全重写了它以前的目标检测框架,新的目标检测框架被称为Detectron2。本教程将通过使用自定义coco数据集训练实例分割模型,帮助你开始使...

CICD联动阿里云容器服务Kubernetes实践之Bamboo篇

本文档以构建一个Java软件项目并部署到阿里云容器服务的Kubernetes集群为例说明如何使用Bamboo在阿里云Kubernetes服务上运行RemoteAgents并在agents上...

Open3D-ML点云语义分割实验【RandLA-Net】

作为点云Open3D-ML实验的一部分,我撰写了文章解释如何使用Tensorflow和PyTorch支持安装此库。为了测试安装,我解释了如何运行一个简单的Python脚本来可视化名为...

清理系统不用第三方工具(系统自带清理软件效果好不?)

清理优化系统一定要借助于优化工具吗?其实,手动优化系统也没有那么神秘,掌握了方法和技巧,系统清理也是一件简单和随心的事。一方面要为每一个可能产生累赘的文件找到清理的方法,另一方面要寻找能够提高工作效率...

【信创】联想开先终端开机不显示grub界面的修改方法

原文链接:【信创】联想开先终端开机不显示grub界面的修改方法...

如意玲珑成熟度再提升,三大发行版支持教程来啦!

前期,我们已分别发布如意玲珑在deepinV23与UOSV20、openEuler24.03发行版的操作指南,本文,我们将为大家详细介绍Ubuntu24.04、Debian12、op...

118种常见的多媒体文件格式(英文简写)

MP4[?mpi?f??]-MPEG-4Part14(MPEG-4第14部分)AVI[e?vi??a?]-AudioVideoInterleave(音视频交错)MOV[m...

密码丢了急上火?码住7种console密码紧急恢复方式!

身为攻城狮的你,...

CSGO丨CS2的cfg指令代码分享(csgo自己的cfg在哪里?config文件位置在哪?)

?...

使用open SSL生成局域网IP地址证书

某些特殊情况下,用户内网访问多可文档管理系统时需要启用SSL传输加密功能,但只有IP,没有域名和证书。这种情况下多可提供了一种免费可行的方式,通过openSSL生成免费证书。此方法生成证书浏览器会提示...

Python中加载配置文件(python怎么加载程序包)

我们在做开发的时候经常要使用配置文件,那么配置文件的加载就需要我们提前考虑,再不使用任何框架的情况下,我们通常会有两种解决办法:完整加载将所有配置信息一次性写入单一配置文件.部分加载将常用配置信息写...

python开发项目,不得不了解的.cfg配置文件

安装软件时,经常会见到后缀为.cfg、.ini的文件,一般我们不用管,只要不删就行。因为这些是程序安装、运行时需要用到的配置文件。但对开发者来说,这种文件是怎么回事就必须搞清了。本文从.cfg文件的创...

瑞芯微RK3568鸿蒙开发板OpenHarmony系统修改cfg文件权限方法

本文适用OpenHarmony开源鸿蒙系统,本次使用的是开源鸿蒙主板,搭载瑞芯微RK3568芯片。深圳触觉智能专注研发生产OpenHarmony开源鸿蒙硬件,包括核心板、开发板、嵌入式主板,工控整机等...

Python9:图像风格迁移-使用阿里的接口

先不多说,直接上结果图。#!/usr/bin/envpython#coding=utf-8importosfromaliyunsdkcore.clientimportAcsClient...

Python带你打造个性化的图片文字识别

我们的目标:从CSV文件读取用户的文件信息,并将文件名称修改为姓名格式的中文名称,进行规范资料整理,从而实现快速对多个文件进行重命名。最终效果:将原来无规律的文件名重命名为以姓名为名称的文件。技术点:...

取消回复欢迎 发表评论:

请填写验证码