Linux平台x86_64|aarch64架构RTMP推送|轻量级RTSP服务模块集成说明

news2024/12/29 11:22:44

系统要求

支持x64_64架构、aarch64架构(需要glibc-2.21及以上版本的Linux系统, 需要libX11.so.6, 需要GLib–2.0, 需安装 libstdc++.so.6.0.21、GLIBCXX_3.4.21、 CXXABI_1.3.9)。

功能支持

Linux平台x64_64架构|aarch64架构RTMP直播推送SDK

  • 音频编码:AAC/SPEEX;
  • 视频编码:H.264;
  • 推流协议:RTMP;
  • [音视频]支持纯音频/纯视频/音视频推送;
  • 支持X11屏幕采集;
  • 支持部分V4L2摄像头设备采集;
  • [屏幕/V4L2摄像头]支持帧率、关键帧间隔(GOP)、码率(bit-rate)设置;
  • [V4L2摄像头]支持V4L2摄像头设备选择(设备文件名范围:[/dev/video0, /dev/video63])、分辨率设置、帧率设置;
  • [V4L2摄像头]支持水平反转、垂直反转、0° 90° 180° 270°旋转;
  • [音频]支持基于alsa-lib接口的音频采集;
  • [音频]支持基于libpulse接口采集本机PulseAudio服务音频;
  • [预览]支持推送端实时预览;
  • [对接服务器]支持自建标准RTMP服务器或CDN;
  • 支持断网自动重连、网络状态回调;
  • 屏幕和摄像头合成/多层合成;
  • 支持窗口采集(一般不建议使用);
  • 支持实时快照;
  • 支持降噪处理、自动增益控制、VAD端点检测;
  • 支持扬声器和麦克风混音;
  • 支持外部编码前音视频数据对接;
  • 支持外部编码后音视频数据对接;
  • 支持实时音量调节;
  • 支持扩展录像模块;
  • 支持Unity接口;
  • 支持H.264扩展SEI发送模块;
  • 支持x64_64架构、aarch64架构(需要glibc-2.21及以上版本的Linux系统, 需要libX11.so.6, 需要GLib–2.0, 需安装 libstdc++.so.6.0.21、GLIBCXX_3.4.21、 CXXABI_1.3.9);

Linux平台x64_64架构|aarch64架构轻量级RTSP服务SDK

  •  [基础功能]支持Linux(含x86_64|aarch64)平台RTMP直播SDK除RTMP外的常规功能;
  •  [音频格式]AAC;
  •  [视频格式]H.264;
  •  [协议类型]RTSP;
  •  [传输模式]支持单播和组播模式;
  •  [端口设置]支持RTSP端口设置;
  •  [鉴权设置]支持RTSP鉴权用户名、密码设置;
  •  [获取session连接数]支持获取当前RTSP服务会话连接数;
  •  [多服务支持]支持同时创建多个内置RTSP服务;
  •  [RTSP url回调]支持设置后的rtsp url通过event回调到上层。

准备工作

  • 相关so:publisherdemo\libSmartPublisherSDK.so;
  • 相关so:publisherdemo\libSmartLog.so;
  • 头文件:publisherdemo\nt_smart_sdk\linux\include;

编译说明

  1. 1. publisherdemo是个简单的demo,自己可以修改播放url,然后make测试; 
  2. 2. 如果需要在后台运行,请 nohup ./SmartPublisherSDKDemo >/dev/null 2>&1 &
  3. 3. 如果需要正常终止后台demo的话,请执行 kill -s SIGINT pid
  4. 4. 编译demo时请确保安装了gcc和g++.

Linux arm64编译及运行说明:

1. 在arm64 Linux机器上直接编译:

make NT_ENABLE_EXTERNAL_LIB=no NT_CROSS_COMPILE_PREFIX=

2. 在x86_64 Linux机器上交叉编译: make

3. gcc版本要求gcc 5.5及以上版本.

4. 运行环境要求glibc 2.21及以上, 需要安装 libstdc++.so.6.0.21, GLIBCXX_3.4.21, CXXABI_1.3.9

5. 交叉编译需要相应的gcc,例如: aarch64-linux-gnu-gcc, gcc版本要5.5及以上.

SDK调用说明

请在 push_api.Init 之前添加下面的代码:

NT_PB_SetSDKClientKey("xxx", "xxxx", 0, nullptr);

auto ret = push_api.Init(0, nullptr);
设置log路径
void LogInit()
{
	SmartLogAPI log_api;
	memset(&log_api, 0, sizeof(log_api));
	GetSmartLogAPI(&log_api);

	log_api.SetLevel(SL_INFO_LEVEL);
	log_api.SetPath((NT_PVOID)"./");
}
推送SDK初始化
bool PushSDKInit(NT_SmartPublisherSDKAPI& push_api)
{
	memset(&push_api, 0, sizeof(push_api));
	NT_GetSmartPublisherSDKAPI(&push_api);

	auto ret = push_api.Init(0, nullptr);
	if (NT_ERC_OK != ret)
	{
		fprintf(stderr, "push_api.Init failed!\n");
		return false;
	}
	else
	{
		fprintf(stdout, "push_api.Init ok!\n");
	}

	return true;
}
创建|关闭实例

RTMP直播推送模块,每次调用Open()会返回个推送实例,与之对应的是Close()接口,关闭实例。

/*
这个是最后一个调用的接口
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API *UnInit)();

/*
video_option 请参考 NT_PB_E_VIDEO_OPTION,
auido_option 请参考 NT_PB_E_AUDIO_OPTION
flag目前传0,后面扩展用, pReserve传NULL,扩展用,
获取Handle
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API *Open)(NT_PHANDLE pHandle, NT_UINT32 video_option, NT_UINT32 auido_option, NT_UINT32 flag, NT_PVOID pReserve);

/*
调用这个接口之后handle失效,
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API *Close)(NT_HANDLE handle);

这里,video_option和audio_option,决定采集视音频数据类型:

/*定义Video源选项*/
typedef enum _NT_PB_E_VIDEO_OPTION
{
	NT_PB_E_VIDEO_OPTION_NO_VIDEO = 0x0,
	NT_PB_E_VIDEO_OPTION_SCREEN   = 0x1, // 采集屏幕
	NT_PB_E_VIDEO_OPTION_CAMERA	  = 0x2, // 摄像头采集
	NT_PB_E_VIDEO_OPTION_LAYER    = 0x3, // 视频合并,比如桌面叠加摄像头等
	NT_PB_E_VIDEO_OPTION_ENCODED_DATA = 0x4, // 已经编码的视频数据,目前支持H264
	NT_PB_E_VIDEO_OPTION_WINDOW   = 0x5, // 采集窗口
} NT_PB_E_VIDEO_OPTION;

/*定义Auido源选项*/
typedef enum _NT_PB_E_AUDIO_OPTION
{
	NT_PB_E_AUDIO_OPTION_NO_AUDIO					= 0x0,
	NT_PB_E_AUDIO_OPTION_CAPTURE_MIC				= 0x1, // 采集麦克风音频
	NT_PB_E_AUDIO_OPTION_CAPTURE_SPEAKER			= 0x2, // 采集扬声器
	NT_PB_E_AUDIO_OPTION_CAPTURE_MIC_SPEAKER_MIXER	= 0x3, // 麦克风扬声器混音
	NT_PB_E_AUDIO_OPTION_ENCODED_DATA				= 0x4, // 编码后的音频数据,目前支持AAC, speex宽带(wideband mode)
	NT_PB_E_AUDIO_OPTION_EXTERNAL_PCM_DATA			= 0x5, /*外部PCM数据*/
	NT_PB_E_AUDIO_OPTION_MIC_EXTERNAL_PCM_MIXER     = 0x6, /* 麦克风和外部PCM数据混音 当前只支持一路外部音频和内置麦克风混音*/
	NT_PB_E_AUDIO_OPTION_TWO_EXTERNAL_PCM_MIXER     = 0x7, /* 两路外部PCM数据混音*/
} NT_PB_E_AUDIO_OPTION;
推送参数初始化

视频编码参数如下:

/*
 * nt_linux_smart_publisher_sdk.h
 * Author: daniusdk.com
 * WeChat: xinsheng120
 */
/*
设置软硬编码类型, 编码器, codec_id, 编码器其他参数.
type: 0为软编码, 1为硬编码, 默认是软编码. linux当前不支持硬编码
encoder_id: 如果是软编码, 并且用h264, 可以设置0, 0用默认编码器, 也可以设置1, 设置1将使用OpenH264编码.
param1: 如果是软编码,请设置0;
codec_id: 设置h264或h265编码, 默认是h264, 请参考NT_MEDIA_CODEC_ID,  h264填 NT_MEDIA_CODEC_ID_H264, h265填 NT_MEDIA_CODEC_ID_H265.
注意: 软编码不支持h265, 硬编码根据实际硬件情况决定是否支持h265.
如果调用了这个接口,请不要再调用SetVideoEncoderType接口
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API *SetVideoEncoder)(NT_HANDLE handle, NT_INT32 type, NT_INT32 encoder_id, NT_UINT32 codec_id, NT_INT32 param1);

/*
注意,码率控制两种方式,要么是 SetVideoQuality(或者 SetVideoQualityV2) + SetVideoMaxBitRate
要么是 SetVideoMaxBitRate  + SetVideoBitRate
对于OpenH264, 只支持 SetVideoMaxBitRate  + SetVideoBitRate方式
*/

/*
设置视频质量, 范围[1-50], 值越小视频质量越好,但码率会越大. 请优先考虑默认值,
对于H264, 默认值23
对于H265, 默认值28
注意:用OpenH264编码器时调用这个接口无用
*/
NT_UINT32(NT_API *SetVideoQuality)(NT_HANDLE handle, NT_INT32 quality);


/*
设置最大视频码率, 单位kbps
*/
NT_UINT32(NT_API *SetVideoMaxBitRate)(NT_HANDLE handle, NT_INT32 kbit_rate);

/*
设置视频码率, 单位kbps, 默认是0,不使用平均码率方式
注意:用OpenH264编码器时调需要设置适当的值
*/
NT_UINT32(NT_API *SetVideoBitRate)(NT_HANDLE handle, NT_INT32 kbit_rate);


/*
* 在一些特殊场景下, 视频分辨率会改变, 如果设置一个固定码率的的话,当视频分辨率变大的时候会变的模糊,变小的话又会浪费码率
* 所以提供可以设置一组码率的接口,满足不同分辨率切换的需求
* 规则: 比如设置两组分辨率 640*360, 640*480, 那么当分辨率小于等于640*360时都使用640*360的码率,
* 当分辨率大于640*360且小于等于640*480时,就使用640*480的码率,如果分辨率大于640*480 那就使用640*480的分辨率
* 为了设置的更准确, 建议多划分几组, 让区间变小
* 调用这个接口每次设置一组,设置多组就调用多次
*
*/
NT_UINT32(NT_API* AddVideoEncoderBitrateGroupItem)(NT_HANDLE handle, const NT_PB_VideoEncoderBitrateGroupItem* item);


/*
清除视频码率组
*/
NT_UINT32(NT_API* ClearVideoEncoderBitrateGroup)(NT_HANDLE handle);


/*
设置关键帧间隔, 比如1表示所有帧都是关键帧,10表示每10帧里面一个关键帧,25表示每25帧一个关键帧
*/
NT_UINT32(NT_API *SetVideoKeyFrameInterval)(NT_HANDLE handle, NT_INT32 interval);


/*
设置H264 profile.
profile: 1: H264 baseline(默认值). 2: H264 main. 3. H264 high
注意:用OpenH264编码器时不支持main profile, 如果设置成main profile的话,会回落到baseline profile.
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API *SetVideoEncoderProfile)(NT_HANDLE handle, NT_INT32 profile);

/*
设置视频编码速度
speed: 范围是 1 到 6,  值越小,速度越快,质量也越差
*/
NT_UINT32(NT_API *SetVideoEncoderSpeed)(NT_HANDLE handle, NT_INT32 speed);

/*
设置视频编码量化范围, 设置最小值
qp_min: h264和h265设置范围都是[0, 51], 设置-1的话,编码器使用默认值;
注意目前只对OpenH264有效
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API *SetVideoEncoderQPMin)(NT_HANDLE handle, NT_INT32 qp_min);


/*
设置视频编码量化范围, 设置最小值
qp_max: h264和h265设置范围都是[0, 51], 设置-1的话,编码器使用默认值;
注意目前只对OpenH264有效
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API *SetVideoEncoderQPMax)(NT_HANDLE handle, NT_INT32 qp_max);


/*
不同的视频编码器一般会有一些特定的选项, 这个接口可以设置这些选项
option_name: 选项名称
option_value: 选项值
成功返回 NT_ERC_OK
********************************************
***********OpenH264选项说明******************
可以设置的选项有: "usage_type", "rc_mode", "enable_frame_skip" 
"usage_type": 编码场景, 可以设置0和1, 0是实时摄像头编码, 1是实时屏幕编码, sdk默认是0;
"rc_mode": 码率控制模式, 可以设置0和1, 0是质量模式, 1是码率模式, sdk默认是1;
"enable_frame_skip": 通过跳帧的方式来控制码率, 设置0是关闭跳帧, 1是打开跳帧, sdk默认是0;
***********OpenH264选项说明******************
********************************************
*/
NT_UINT32(NT_API *SetVideoEncoderSpecialInt32Option)(NT_HANDLE handle, NT_PCSTR option_name, NT_INT32 option_value);


/*
清除编码器所有设置的特定选项
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API *ClearVideoEncoderSpecialOptions)(NT_HANDLE handle);

音频参数配置如下:

/*
 * nt_linux_smart_publisher_sdk.h
 * Author: daniusdk.com
 * WeChat: xinsheng120
 */
/*
获取系统麦克风输入设备数
audio_input_layer: 1:alsa lib, 2:PulseAudio, 其他值返回错误, 优先推荐使用PulseAudio
注意:当使用alsa lib, 可能会返回很多PCM设备, 具体可以用 "arecord -L" 命令自己比对下
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* GetAuidoInputDeviceNumber)(NT_INT32 audio_input_layer, NT_INT32* pNumer);

/*
获取麦克风设备名称
audio_input_layer: 1:alsa lib, 2:PulseAudio, 其他值返回错误.
device_id: 设备ID,需要输入, 从0开始,最大值不能超过设备数, 注意: 这个id一定要和audio_input_layer对应
device_name: 设备名称,返回的字符串以0结尾
device_name_size: 设备名称buffer的大小,建议512
成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* GetAuidoInputDeviceName)(NT_INT32 audio_input_layer, NT_INT32 device_id, NT_PSTR device_name, NT_UINT32 device_name_size);


/*
*设置麦克风采集层
*audio_input_layer: 1:使用alsa lib采集麦克风, 2:使用PulseAudio采集麦克风, 其他值返回失败, SDK默认使用PulseAudio采集麦克风
*成功返回NT_ERC_OK
*/
NT_UINT32(NT_API *SetAudioInputLayer)(NT_HANDLE handle, NT_INT32 audio_input_layer);


/*
设置麦克风采集设备ID
*device_id: 设备id, 一般从0开始, 这个id要根据SetAudioInputLayer设置的值来设置, 
*就是说如果使用alsa lib采集麦克风, 那就对应alsa lib获取到的id,
*如果使用PulseAudio, 那就对应PulseAudio获取到的id,
*不能随意设置,否则采集结果未定义, 或者返回失败
*成功返回NT_ERC_OK
*/
NT_UINT32(NT_API* SetAuidoInputDeviceId)(NT_HANDLE handle, NT_INT32 device_id);


/*
检查是否能采集扬声器音频, 当前SDK只使用PulseAudio采集
audio_input_layer: 2:使用PulseAudio采集扬声器声音, 这个值目前必须是2, 其他返回错误
out_flag: 1表示可以采集扬声器,0:表示不可以采集扬声器
*/
NT_UINT32(NT_API* IsCanCaptureSpeaker)(NT_INT32 audio_input_layer, NT_INT32* out_flag);


/*
*设置推送音频编码类型
*type: 1:使用AAC编码, 2:使用speex编码, 其他值返回错误
*成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* SetPublisherAudioCodecType)(NT_HANDLE handle, NT_INT32 type);


/*
*设置推送Speex编码质量
*quality: 范围是0-10, 默认是8:大约28kbps, 值越大,质量越好,码率也越大
*成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* SetPublisherSpeexEncoderQuality)(NT_HANDLE handle, NT_INT32 quality);


/*
设置推送静音
is_mute: 0表示不静音, 1表示静音
*/
NT_UINT32(NT_API* SetMute)(NT_HANDLE handle, NT_INT32 is_mute);


/*
*设置回音消除
*isCancel: 1表示消除回音, 0表示不消除回音
*delay: 回音时延,单位是毫秒,目前推荐设置100ms, 如果设置为0的话, 系统自动处理
*注意这个只对麦克风捕获有作用,扬声器捕获无效
*成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* SetEchoCancellation)(NT_HANDLE handle, NT_INT32 isCancel, NT_INT32 delay);

	
/*
*设置音频噪音抑制
*isNS: 1表示噪音抑制, 0表示不抑制
*注意,这个一般用在采集麦克风上,采集系统播放声音时必须要性不大
*成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* SetNoiseSuppression)(NT_HANDLE handle, NT_INT32 isNS);

/*
*设置音频自动增益控制
*isAGC: 1表示增益控制, 0表示不控制
*注意,这个一般用在采集麦克风上,采集系统播放声音时必须要性不大
*成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* SetAGC)(NT_HANDLE handle, NT_INT32 isAGC);


/*
*设置端点检测(Voice Activity Detection (VAD))
*isVAD: 1表示端点检测, 0表示不检测
*注意,这个一般用在采集麦克风上,采集系统播放音乐时不要使用
*成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* SetVAD)(NT_HANDLE handle, NT_INT32 isVAD);


/*
*设置输入音量, 这个接口一般不建议调用, 在一些特殊情况下可能会用, 一般不建议放大音量, 优先考虑AGC
*index: 一般是0和1, 如果没有混音的只用0, 有混音的话, 0,1分别设置音量
*volume: 音量,默认是1.0,范围是[0.0, 2.0], 设置成0静音, 1音量不变
*成功返回 NT_ERC_OK
*/
NT_UINT32(NT_API* SetInputAudioVolume)(NT_HANDLE handle, NT_INT32 index, float volume);
设置Event回调
push_api->SetEventCallBack(push_handle, nullptr, OnSDKEventHandle);

Event事件ID如下:

/*事件ID*/
typedef enum _NT_PB_E_EVENT_ID
{
	NT_PB_E_EVENT_ID_BASE = NT_EVENT_ID_SMART_PUBLISHER_SDK,

	NT_PB_E_EVENT_ID_CONNECTING			= NT_PB_E_EVENT_ID_BASE | 0x2,	/*连接中, param5表示推送URL */
	NT_PB_E_EVENT_ID_CONNECTION_FAILED	= NT_PB_E_EVENT_ID_BASE | 0x3,	/*连接失败, param5表示推送URL*/
	NT_PB_E_EVENT_ID_CONNECTED			= NT_PB_E_EVENT_ID_BASE | 0x4,	/*已连接, param5表示推送URL*/
	NT_PB_E_EVENT_ID_DISCONNECTED		= NT_PB_E_EVENT_ID_BASE | 0x5,	/*断开连接, param5表示推送URL*/
	
	NT_PB_E_EVENT_ID_RECORDER_START_NEW_FILE    = NT_PB_E_EVENT_ID_BASE | 0x7,	/*录像写入新文件, param5表示录像文件名*/
	NT_PB_E_EVENT_ID_ONE_RECORDER_FILE_FINISHED = NT_PB_E_EVENT_ID_BASE | 0x8,	/*一个录像文件完成, param5表示录像文件名*/

	NT_PB_E_EVENT_ID_CAPTURE_WINDOW_INVALID = NT_PB_E_EVENT_ID_BASE | 0xd, /*捕获窗口时,如果窗口句柄无效则通知用户, param1为窗口句柄*/

	NT_PB_E_EVENT_ID_RTSP_URL = NT_PB_E_EVENT_ID_BASE | 0xe, /* 通知rtsp url, param1表示rtsp server handle, param5 表示rtsp url */

	NT_PB_E_EVENT_ID_PUSH_RTSP_SERVER_RESPONSE_STATUS_CODE = NT_PB_E_EVENT_ID_BASE | 0xf,  /* 推送rtsp时服务端相应的status code上报,目前只上报401, param1表示status code,  param5表示推送URL */
	NT_PB_E_EVENT_ID_PUSH_RTSP_SERVER_NOT_SUPPORT = NT_PB_E_EVENT_ID_BASE | 0x10,  /* 推送rtsp时服务器不支持rtsp推送,  param5表示推送URL */

} NT_PB_E_EVENT_ID;
推送RTMP
bool start_rtmp(NT_SmartPublisherSDKAPI* push_api, NT_HANDLE handle, const std::string& rtmp_url) {
	if (NT_ERC_OK != push_api->SetURL(handle, rtmp_url.c_str(), NULL))
		return false;

	if (NT_ERC_OK != push_api->StartPublisher(handle, NULL))
		return false;

	return true;
}

push_api->StopPublisher(handle);
轻量级RTSP服务-启动|停止RTSP服务
NT_HANDLE start_rtsp_server(NT_SmartPublisherSDKAPI* push_api, int port, std::string user_name, std::string password) {

	NT_HANDLE rtsp_server_handle = nullptr;
	if (NT_ERC_OK != push_api->OpenRtspServer(&rtsp_server_handle, 0)) {
		fprintf(stderr, "OpenRtspServer failed\n");
		return nullptr;
	}

	if (nullptr == rtsp_server_handle) {
		fprintf(stderr, "rtsp_server_handle is null\n");
		return nullptr;
	}

	if (NT_ERC_OK != push_api->SetRtspServerPort(rtsp_server_handle, port)) {
		push_api->CloseRtspServer(rtsp_server_handle);
		return nullptr;
	}

	if (!user_name.empty() && !password.empty())
		push_api->SetRtspServerUserNamePassword(rtsp_server_handle, user_name.c_str(), password.c_str());

	if (NT_ERC_OK == push_api->StartRtspServer(rtsp_server_handle, 0))
		return rtsp_server_handle;

	fprintf(stderr, "StartRtspServer failed\n");
	push_api->CloseRtspServer(rtsp_server_handle);
	
	return nullptr;
}

void stop_rtsp_server(NT_SmartPublisherSDKAPI* push_api, NT_HANDLE& rtsp_server_handle) {
	if (nullptr == rtsp_server_handle)
		return;

	NT_HANDLE handle = rtsp_server_handle;
	rtsp_server_handle = nullptr;

	push_api->StopRtspServer(handle);
	push_api->CloseRtspServer(handle);
}
发布|停止RTSP流
bool start_rtsp_stream(NT_SmartPublisherSDKAPI* push_api, NT_HANDLE rtsp_server_handle, NT_HANDLE handle, const std::string stream_name) {

	push_api->SetRtspStreamName(handle, stream_name.c_str());

	push_api->ClearRtspStreamServer(handle);

	push_api->AddRtspStreamServer(handle, rtsp_server_handle, 0);
	
	if (NT_ERC_OK != push_api->StartRtspStream(handle, 0))
		return false;

	return true;
}

push_api.StopRtspStream(push_handle);

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

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

相关文章

UDP服务端、TCP的c/s模式

一、UDP服务端 socket bind //绑定 recvfrom ssize_t recvfrom(int sockfd, socket的fd void *buf, 保存数据的一块空间的地址 …

网络编程TCP与UDP

TCP与UDP UDP头: 包括源端口、目的地端口、用户数据包长度,检验和 数据。 typedef struct _UDP_HEADER {unsigned short m_usSourPort;    // 源端口号16bitunsigned short m_usDestPort;    // 目的端口号16bitunsigned short m_usLen…

一款B to B Connector的仿真结果与开发样品实测的结果对比

下面是一款B to B 连接器开发初期的CST仿真结果: 回波损耗 插入损耗 时域阻抗 开发样品出来后第三方测试机构的实测结果

Auto CAD 常用指令汇总 [持续更新]

简介 AutoCAD是由美国Autodesk公司开发的一款自动计算机辅助设计软件,广泛应用于建筑、工程、城市规划等多个领域。自1982年发布以来,AutoCAD不断进化,成为行业标准之一。它支持二维绘图和三维建模功能,用户可以精确绘制各种图形&…

BSCI(Business Social Compliance Initiative)验厂

在当今全球化的经济环境中,企业社会责任(Corporate Social Responsibility, CSR)已成为衡量企业成功与否的重要标尺之一。而BSCI(Business Social Compliance Initiative)验厂,作为国际间广泛认可的社会责任…

服务器Ubuntu22.04系统 使用dcocker部署安装ollama和搭配open_webui使用

服务器Ubuntu22.04系统 使用dcocker部署安装ollama和搭配open_webui使用 一、ubuntu和docker基本环境配置 1.更新包列表: 打开终端,输入以下命令: sudo apt-get updatesudo apt upgrade更新时间较长,请耐心等待 2. 安装docke…

[MOCO] Momentum Contrast for Unsupervised Visual Representation Learning

1、目的 无监督表示学习在自然图像领域已经很成功,因为语言任务有离散的信号空间(words, sub-word units等),便于构建tokenized字典 现有的无监督视觉表示学习方法可以看作是构建动态字典,字典的“keys”则是从数据&am…

测评了几百款素材管理软件,新手设计师如何进行高效的素材管理?附教程

设计师朋友们,大家在日常工作中肯定积累了各种各样的素材,大家都保存在哪里呢?是散落在电脑磁盘里,还是用一个专门的素材管家管理呢?作为新手设计师,目前是在使用一款经典好用的素材管理软件—Eagle&#x…

Java学习_17_集合综合练习(待更新)

文章目录 前言一、自动点名器二、斗地主小游戏1、准备牌2、洗牌3、发牌4、理牌 总结 前言 博客仅记录个人学习进度和一些查缺补漏。 学习内容:BV17F411T7Ao 部分内容因没有学到,等待后续更新 一、自动点名器 /**** 点名器1,N个学生随机点名…

Edge-TTS:微软推出的,免费、开源、支持多种中文语音语色的AI工具[工具版]

Edge-TTS,由微软推出的这款免费、开源的AI工具,为用户带来了丰富多样的中文语音体验。它不仅支持多种中文语音语色,还能实现流畅自然的语音合成。Edge-TTS凭借其高度可定制化的特点,广泛应用于智能助手、语音播报、教育培训等领域…

商业软件许可证介绍|简单原理探究

个人博客:无奈何杨(wnhyang) 个人语雀:wnhyang 共享语雀:在线知识共享 Github:wnhyang - Overview 引入话题 既然是商业软件,涉及到商业,那目的就是赚钱。 就拿IDEA举例&#x…

Linux系统中的常见操作命令

目录 命令总结: 一、目录处理命令 二、文件处理命令 三、权限管理命令 四、其它实用命令 命令总结: (目录) ls [参数] 目录、(查看目录)pwd、(切换目录)cd [目录路径]、&…

4.1栈和队列基本概念+经典OJ题

本篇博客来梳理栈和队列基本概念以及一道经典OJ题,题目已插入超链接,点击即可跳转~ 一、栈的相关概念 1.栈 一种特殊的线性表,只允许在固定的一端插入和删除元素,栈中的数据遵循后进先出原则 (1&#x…

Pytorch添加自定义算子之(12)-开闭原则设计tensorrt和onnxruntime推理语义分割模型

一、开闭原则 开闭原则是SOLID原则中的一个,指的是尽量使用开放扩展,关闭修改的设计原则。 在C++中如何使用开闭原则导出动态库,可以按照以下步骤进行: 定义抽象基类:定义动态库中的抽象基类,该基类应该封装可扩展的接口。 实现派生类:实现基类的派生类,这些派生类将封…

Vue 导航条+滑块效果

目录 前言代码效果展示导航实现代码导航实现代码导航应用代码前言 总结一个最近开发的需求。设计稿里面有一个置顶的导航条,要求在激活的项目下面展示个下划线。我最先开始尝试的是使用 after 的伪类选择器,直接效果一样,但是展示的时候就会闪现变化,感觉不够自然,参考了一…

继承(下)【C++】

文章目录 子类继承父类之后,子类的默认成员函数的变化构造函数编译器自动生成的构造函数程序员手动写的构造函数 拷贝构造编译器自动生成的拷贝构造函数程序员手动写的拷贝构造函数 赋值重载编译器自动生成的赋值重载程序员手动写的赋值重载 析构函数 继承与友元菱形…

vm安装mac虚拟机

vm安装mac虚拟机 简介实操 简介 教程:完全面向萌新的黑苹果安装教学:黑苹果安装从入门到入白,借助VMware虚拟机给实体机硬盘按照macOS黑苹果系统 实操 下载unlocker,之后运行vm就可以新建mac虚拟机了 新建一个没有选择镜像的…

【Electron】桌面应用开发快速入门到打包Windows应用程序

electron 实现桌面应用开发快速入门到打包Windows应用程序 一、基本介绍 ‌‌Electron 是一个使用‌ JavaScript、‌HTML 和‌ CSS 构建桌面应用程序的框架。它通过将‌Chromium和‌Node.js嵌入到其二进制文件中,允许开发者使用JavaScript代码库创建跨平台的桌面应…

汽车冷却液温度传感器

1、冷却液温度传感器的功能 发动机冷却液温度传感器,也称为ECT,是帮助保护发动机,提高发动机工作效率以及帮助发动机稳定运行的非常重要的传感器之一。 发动机冷却液温度 (ECT) 传感器用于测量发动机的冷却液温度&…

IO进程线程 0822作业

作业 使用write和read完成文件的拷贝。 将1.txt文件内容拷贝到2.txt中 #include <myhead.h> int main(int argc, const char *argv[]) {if(argc ! 3){printf("外部传参错误\n");return -1;}int fd1;fd1 open(argv[1],O_RDONLY);if(fd1 -1){perror("op…