IM腾讯Trtc与vod云点播:实现合流录制并上传,根据参数返回视频地址

全文目录,一步到位

  • 1.前言简介
    • 1.1 专栏传送门
      • 1.1.1 文档传送门
  • 2. java基础使用
    • 2.1 准备工作
      • 2.1.1 云控制台获取(密钥和密钥secret)
      • 2.1.2 找到trtc控制台
      • 2.1.3 vod云点播控制台
    • 2.2 使用准备的数据进行操作
      • 2.2.0 引入依赖
      • 2.2.1 创建TrtcUtils工具类
      • 2.2.2 TrtcReqDTO 录制请求dto
      • 2.2.3 TrtcCommonReqDto 请求dto
      • 2.2.4 OrderTrtcVideo 数据库存储实体类
      • 2.2.5 获取用户usersig(旧版)
    • 2.3 业务使用方式
      • 2.3.0 json传递数据
      • 2.3.1 创建service方法
      • 2.3.2 TrtcServiceImpl 实现类
      • 2.3.4 上传后视频效果
  • 3. 文章的总结与预告
    • 3.1 本文总结
    • 3.2 代码指正


1.前言简介

腾讯trtc合流模式使用 如果时单流 可在控制台直接设置

1.1 专栏传送门

1.1.1 文档传送门

===> 传送门: api文档-官网地址

2. java基础使用

2.1 准备工作

2.1.1 云控制台获取(密钥和密钥secret)

===> 腾讯云控制台登录 传送门<===
如图所示在这里插入图片描述

2.1.2 找到trtc控制台

===> im控制台 传送门 <===

创建sdkAppId 开通需要的服务
在这里插入图片描述

2.1.3 vod云点播控制台

===> vod云点播控制台地址

  1. 创建视频生成模板
  2. 创建任务流绑定视频模板

--------> 如图所示

在这里插入图片描述

2.2 使用准备的数据进行操作

2.2.0 引入依赖

trtc包和vod包
源码位置: 源码gitee地址

     <!--   # 版本在maven生效需要时间,如获取不到对应的版本,可以调低版本号--><dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java-trtc</artifactId><version>3.1.1218</version></dependency><!--  # 版本在maven生效需要时间,如获取不到对应的版本,可以调低版本号--><dependency><groupId>com.tencentcloudapi</groupId><artifactId>tencentcloud-sdk-java-vod</artifactId><version>3.1.1212</version></dependency>

2.2.1 创建TrtcUtils工具类

缺少的包可以忽略 删除都可以

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import com.google.common.base.Objects;
import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.trtc.v20190722.TrtcClient;
import com.tencentcloudapi.trtc.v20190722.models.*;
import com.tencentcloudapi.vod.v20180717.VodClient;
import com.tencentcloudapi.vod.v20180717.models.*;import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.util.CollectionUtils;import java.util.List;/*** trtc工具类* 这里的常量就不大写了* @author pzy* @version 0.1.1*/
@Slf4j
public class TrtcUtils {/*** 密钥key*/private static final String secretId = "";/*** 密钥secret*/private static final String secretKey = "";/*** 请求节点*/private static final String trtcEndPoint = "trtc.tencentcloudapi.com";/*** sdk 的 appid*/public static final String SDKAppID = "";//vod-------------------------------------------------------->private static final String vodEndPoint = "vod.tencentcloudapi.com";/*** vod任务模板名称*/public static final String vodTaskTemplateName = "";/*** vod的subAppId*/public static final Long vodSubAppId = ;/*** 0. 获取trtc客户端对象(不对外)*/private static TrtcClient getTrtcClient() {// 实例化一个client选项,可选的,没有特殊需求可以跳过ClientProfile clientProfile = new ClientProfile();// 实例化一个http选项,可选的,没有特殊需求可以跳过HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(trtcEndPoint);clientProfile.setHttpProfile(httpProfile);// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取Credential cred = new Credential(secretId, secretKey);return new TrtcClient(cred, "ap-beijing", clientProfile);}/*** 1. 开启TRTC云录制功能*/@SneakyThrowspublic static CreateCloudRecordingResponse sendTrtcRecord(CreateCloudRecordingRequest req) {//获取trtc客户端对象TrtcClient trtcClient = getTrtcClient();// 返回的resp是一个CreateCloudRecordingResponse的实例,与请求对象对应CreateCloudRecordingResponse resp = trtcClient.CreateCloudRecording(req);// 输出json格式的字符串回包log.info("===> 开启TRTC云录制功能-响应信息: {}" + AbstractModel.toJsonString(resp));return resp;}/*** 2. 停止TRTC云端录制任务*/@SneakyThrowspublic static Object functionCloudRecording(TrtcCommonReqDto trtcCommonReqDto) {String taskId = trtcCommonReqDto.getTaskId();Assert.notNull(taskId, () -> new ServiceException("请传递任务id后重试~"));// 实例化要请求产品的client对象,clientProfile是可选的TrtcClient client = getTrtcClient();/* 功能类型 1 停止录制(默认) 2查询录制状态  */Long sdkAppId = Long.valueOf(SDKAppID);if (Objects.equal(trtcCommonReqDto.getFunctionType(), "1")) {DeleteCloudRecordingRequest req = new DeleteCloudRecordingRequest();req.setSdkAppId(sdkAppId);req.setTaskId(taskId);// 返回的resp是一个DeleteCloudRecordingResponse的实例,与请求对象对应DeleteCloudRecordingResponse resp = client.DeleteCloudRecording(req);// 输出json格式的字符串回包log.info("===> 停止TRTC云端录制任务-响应信息: {}" , AbstractModel.toJsonString(resp));return resp;}/* 功能类型 1 停止录制(默认) 2查询录制状态  */if (Objects.equal(trtcCommonReqDto.getFunctionType(), "2")) {// 实例化一个请求对象,每个接口都会对应一个request对象DescribeCloudRecordingRequest req = new DescribeCloudRecordingRequest();req.setSdkAppId(sdkAppId);req.setTaskId(taskId);// 返回的resp是一个DescribeCloudRecordingResponse的实例,与请求对象对应DescribeCloudRecordingResponse resp = client.DescribeCloudRecording(req);log.info("===> 查询TRTC云端录制任务状态-响应信息: {}" + AbstractModel.toJsonString(resp));return resp;}throw new ServiceException("抱歉,类型不存在,请重试呦~");}/*** 3. vod云点播地址获取 通过roomId(暂不优化)*/@SneakyThrowspublic static SearchMediaResponse getVodAddressUrl(TrtcCommonReqDto trtcCommonReqDto) {Credential cred = new Credential(secretId, secretKey);// 实例化一个http选项,可选的,没有特殊需求可以跳过HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(vodEndPoint);// 实例化一个client选项,可选的,没有特殊需求可以跳过ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);// 实例化要请求产品的client对象,clientProfile是可选的VodClient client = new VodClient(cred, "ap-guangzhou", clientProfile);// 实例化一个请求对象,每个接口都会对应一个request对象SearchMediaRequest req = new SearchMediaRequest();req.setSubAppId(vodSubAppId);List<String> roomIds = trtcCommonReqDto.getRoomIds();if (CollectionUtils.isEmpty(roomIds)) {return new SearchMediaResponse();}String[] trtcRoomIds1 = roomIds.toArray(new String[0]);req.setTrtcRoomIds(trtcRoomIds1);// 返回的resp是一个SearchMediaResponse的实例,与请求对象对应SearchMediaResponse resp = client.SearchMedia(req);// 输出json格式的字符串回包log.info("===> 查询Vod云端视频信息: {}", AbstractModel.toJsonString(resp));return resp;}/*** 查询vod云点播地址并封装对象 (根据订单和房间号存入)* <p>* ps: 失败也存,最好异步或者延时调用, 不是立即生成的* -> 优化: 增加重试机制,现在默认好用*/public static List<OrderTrtcVideo> getVodUrlByRoomInOrder(TrtcCommonReqDto trtcCommonReqDto) {String orderRegisterId = trtcCommonReqDto.getOrderRegisterId();SearchMediaResponse searchMediaResponse = TrtcUtils.getVodAddressUrl(trtcCommonReqDto);//处理数据List<OrderTrtcVideo> orderTrtcVideoList = Lists.newArrayList();/*校验: totalCounts是0 则查询失败*/MediaInfo[] mediaInfoSet = searchMediaResponse.getMediaInfoSet();if (Objects.equal(searchMediaResponse.getTotalCount(), 0L) || mediaInfoSet.length <= 0) {log.error("===> 云点播数据查询失败,获取失败~~~");//失败了也存记录trtcCommonReqDto.getRoomIds().forEach(roomId ->orderTrtcVideoList.add(new OrderTrtcVideo(orderRegisterId, roomId, trtcCommonReqDto.getTaskId(), null, "0")));} else {log.error("===> 云点播数据查询成功,获取成功~~~");for (MediaInfo mediaInfo : mediaInfoSet) {MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();String mediaUrl = basicInfo.getMediaUrl();MediaSourceData sourceInfo = basicInfo.getSourceInfo();TrtcRecordInfo trtcRecordInfo = sourceInfo.getTrtcRecordInfo();orderTrtcVideoList.add(new OrderTrtcVideo(orderRegisterId,trtcRecordInfo.getRoomId(), trtcRecordInfo.getTaskId(), mediaUrl));}}return orderTrtcVideoList;}public static void main(String[] args) {List<String> list = Lists.newArrayList();list.add("2807212226");getVodAddressUrl(new TrtcCommonReqDto().setRoomIds(list));}
}

2.2.2 TrtcReqDTO 录制请求dto

官方提供了请求对象 但是部分方法没有set方法, 调整如此

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import com.tencentcloudapi.trtc.v20190722.models.MixLayoutParams;
import com.tencentcloudapi.trtc.v20190722.models.MixTranscodeParams;
import com.tencentcloudapi.trtc.v20190722.models.RecordParams;
import com.tencentcloudapi.trtc.v20190722.models.StorageParams;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;/*** trtc请求dto* @author pzy*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class TrtcReqDTO {/*** TRTC的[SdkAppId](https://cloud.tencent.com/document/product/647/46351#sdkappid),和录制的房间所对应的SdkAppId相同。*/private Long SdkAppId;/*** TRTC的[RoomId](https://cloud.tencent.com/document/product/647/46351#roomid),录制的TRTC房间所对应的RoomId。注:房间号类型默认为整型,若房间号类型为字符串,请通过RoomIdType指定。*/private String RoomId;/*** 录制机器人的UserId,用于进房发起录制任务。【*注意】这个UserId不能与当前房间内的主播观众[UserId](https://cloud.tencent.com/document/product/647/46351#userid)重复。如果一个房间发起多个录制任务时,机器人的userid也不能相互重复,否则会中断前一个录制任务。建议可以把房间ID作为UserId的标识的一部分,即录制机器人UserId在房间内唯一。*/private String UserId;/*** 录制机器人UserId对应的校验签名,即UserId和UserSig相当于录制机器人进房的登录密码,具体计算方法请参考TRTC计算[UserSig](https://cloud.tencent.com/document/product/647/45910#UserSig)的方案。*/private String UserSig;/*** 云端录制控制参数。*/private RecordParams RecordParams;/*** 云端录制文件上传到云存储的参数(不支持同时设置云点播VOD和对象存储COS)*/private StorageParams StorageParams;/*** TRTC房间号的类型。【*注意】必须和录制的房间所对应的RoomId类型相同:0: 字符串类型的RoomId1: 32位整型的RoomId(默认)*/private Long RoomIdType;/*** 合流的转码参数,录制模式为合流的时候可以设置。*/private MixTranscodeParams MixTranscodeParams;/*** 合流的布局参数,录制模式为合流的时候可以设置。*/private MixLayoutParams MixLayoutParams;/*** 接口可以调用的时效性,从成功开启录制并获得任务ID后开始计算,超时后无法调用查询、更新和停止等接口,但是录制任务不会停止。 参数的单位是小时,默认72小时(3天),最大可设置720小时(30天),最小设置6小时。举例说明:如果不设置该参数,那么开始录制成功后,查询、更新和停止录制的调用时效为72个小时。*/private Long ResourceExpiredHour;/*** TRTC房间权限加密串,只有在TRTC控制台启用了高级权限控制的时候需要携带,在TRTC控制台如果开启高级权限控制后,TRTC 的后台服务系统会校验一个叫做 [PrivateMapKey] 的“权限票据”,权限票据中包含了一个加密后的 RoomId 和一个加密后的“权限位列表”。由于 PrivateMapKey 中包含 RoomId,所以只提供了 UserSig 没有提供 PrivateMapKey 时,并不能进入指定的房间。*/private String PrivateMapKey;}

2.2.3 TrtcCommonReqDto 请求dto

import com.google.common.collect.Lists;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;import java.util.List;/*** trtc停止请求dto* @author pzy* @version 0.1.1*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class TrtcCommonReqDto {/*** 录制任务的唯一Id,在启动录制成功后会返回。*/private String TaskId;/*** 功能类型 1 停止录制(默认) 2查询录制状态*/private String functionType = "1";/*** roomIds房间号*/private List<String> roomIds = Lists.newLinkedList();/** 挂号订单id  */private String orderRegisterId;}

2.2.4 OrderTrtcVideo 数据库存储实体类

视频对应订单号对应房间号 对应taskId 进行存储
如果失败可以重试(也存数据库)

import com.baomidou.mybatisplus.annotation.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;/*** 订单trtc视频对象 order_trtc_video** @author pzy*/
@Data
@NoArgsConstructor
@AllArgsConstructor
//@Accessors(chain = true)
@EqualsAndHashCode(callSuper = true)
@TableName("order_trtc_video")
@Schema(title = "订单trtc视频对象 order_trtc_video")
public class OrderTrtcVideo {private static final long serialVersionUID=1L;@Schema(description = "主键id")@TableId(value = "id")private Long id;@Schema(description = "订单id")private String orderRegisterId;@Schema(description = "房间id")private String roomId;@Schema(description = "任务id")private String taskId;@Schema(description = "云点播视频url")private String vodVideoUrl;@Schema(description = "云点播状态(0失败 1成功)")private String vodStatus;public OrderTrtcVideo(String orderRegisterId, String roomId, String taskId, String vodVideoUrl) {this.orderRegisterId = orderRegisterId;this.roomId = roomId;this.taskId = taskId;this.vodVideoUrl = vodVideoUrl;}public OrderTrtcVideo(String orderRegisterId, String roomId, String taskId, String vodVideoUrl, String vodStatus) {this.orderRegisterId = orderRegisterId;this.roomId = roomId;this.taskId = taskId;this.vodVideoUrl = vodVideoUrl;this.vodStatus = vodStatus;}
}

2.2.5 获取用户usersig(旧版)

:> 依赖如下

        <dependency><groupId>com.github.tencentyun</groupId><artifactId>tls-sig-api-v2</artifactId><version>1.1</version></dependency>

import com.tencentyun.TLSSigAPIv2;

public static String getUserSig(Long userId){
TLSSigAPIv2 api = new TLSSigAPIv2(sdkAppId, secretKey);return api.genSig(userId, expire);
}

2.3 业务使用方式

2.3.0 json传递数据

{"userId": "123456","userSig": "eJwtzF0LgjAYhuH-stNC5tpHCh0tsKgOIiM9nGzFS8xNE*mD-ntLPXyuG54PyvenqDctShGJMJoPG7SpO7jCwDFZUMan8tB35T1olMYcYyzIkvOxmKeH1gRnjJGQRu3A-k1QQgRNsJhe4BaOE36*OCurfrdWjUxw5qQtsk3JlXaMinxW*uL9OjT1cbtC3x*78zBl","roomId": "123","mixLayoutParams": {"backGroundColor": "#FF0000","backgroundImageRenderMode": 1,"maxResolutionUserId": "user_1","mediaId": 0,"mixLayoutList": [{"alpha": 100,"height": 100,"imageLayer": 2,"left": 100,"mediaId": 1,"renderMode": 1,"top": 100,"userId": "user_1","width": 100}],"mixLayoutMode": 3,"renderMode": 1},"recordParams": {"maxIdleTime": 60,"maxMediaFileDuration": 1440,"recordMode": 2,"streamType": 0},"storageParams": {"cloudVod": {"tencentVod": {"classId": 0,"mediaType": 0,"sessionContext": "任务流上下文,任务完成回调时透传","sourceContext": "上传上下文,上传完成回调时透传"}}}
}

2.3.1 创建service方法

R是统一返回值 可根据自己业务自行修改

/*** trtc** @author pzy* @version 0.1.1*/
public interface TrtcService {R createCloudRecording(TrtcReqDTO trtcReqDTO);R functionCloudRecording(TrtcCommonReqDto trtcCommonReqDto);R getVodAddressUrl(TrtcCommonReqDto trtcCommonReqDto);
}

2.3.2 TrtcServiceImpl 实现类

依赖包没用特殊的 本地环境没有百度搜就行

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import com.tencentcloudapi.trtc.v20190722.models.*;
import com.tencentcloudapi.vod.v20180717.models.*;import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;import java.util.List;@Slf4j
@Service
@RequiredArgsConstructor
public class TrtcServiceImpl implements TrtcService {@DubboReferenceprivate final A a;/*** 创建TRTC云录制功能(数据处理)*/@Overridepublic R createCloudRecording(TrtcReqDTO trtcReqDTO) {log.info("TRTC 前端入参请求数据===> {}", JSON.toJSONString(trtcReqDTO));//不得使用其他数据业务trtcReqDTO.setSdkAppId(Long.valueOf(TrtcUtils.SDKAppID));trtcReqDTO.setResourceExpiredHour(72L);/*如果是空 默认合流模式 使用默认数据*/RecordParams recordParams = trtcReqDTO.getRecordParams() != null ? trtcReqDTO.getRecordParams() : new RecordParams();recordParams.setRecordMode(2L);recordParams.setMaxIdleTime(30L);recordParams.setStreamType(0L);recordParams.setMaxMediaFileDuration(1440L);trtcReqDTO.setRecordParams(recordParams);//云点播 自动上传模板默认值-------------------->StorageParams storageParams = trtcReqDTO.getStorageParams() != null ? trtcReqDTO.getStorageParams() : new StorageParams();CloudVod cloudVod = storageParams.getCloudVod() != null ? storageParams.getCloudVod() : new CloudVod();TencentVod tencentVod = cloudVod.getTencentVod() != null ? cloudVod.getTencentVod() : new TencentVod();tencentVod.setSubAppId(TrtcUtils.vodSubAppId);tencentVod.setProcedure(TrtcUtils.vodTaskTemplateName);tencentVod.setExpireTime(0L);tencentVod.setClassId(0L);tencentVod.setMediaType(0L);cloudVod.setTencentVod(tencentVod);storageParams.setCloudVod(cloudVod);trtcReqDTO.setStorageParams(storageParams);//--------------------------------------------->log.info("TRTC 后端固定参数覆盖后请求入参数据===> {}", JSON.toJSONString(trtcReqDTO));//数据赋值CreateCloudRecordingRequest req = new CreateCloudRecordingRequest();BeanUtil.copyProperties(trtcReqDTO, req);log.info("TRTC 标准参数<官方要求>请求格式===> {}", JSON.toJSONString(req));return R.ok(TrtcUtils.sendTrtcRecord(req));}@Overridepublic R functionCloudRecording(TrtcCommonReqDto trtcCommonReqDto) {Object resp = TrtcUtils.functionCloudRecording(trtcCommonReqDto);//        /*校验: 如果是停止调用*/if (Objects.equal(trtcCommonReqDto.getFunctionType(), "1")) {// 添加trtc云点播视频urladdOrderTrtcVodUrl(trtcCommonReqDto);}return R.ok(resp);}/*** 添加trtc云点播视频url*/@SneakyThrows@Asyncprotected void addOrderTrtcVodUrl(TrtcCommonReqDto trtcCommonReqDto) {Thread.sleep(15000);//模拟延时队列List<OrderTrtcVideo> orderTrtcVideoList = TrtcUtils.getVodUrlByRoomInOrder(trtcCommonReqDto);//添加Trtc视频log.info("===> 批量添加trtc视频记录中 =====> ");//TODO}@Overridepublic R getVodAddressUrl(TrtcCommonReqDto trtcCommonReqDto) {SearchMediaResponse resp = TrtcUtils.getVodAddressUrl(trtcCommonReqDto);return R.ok(resp);}
}

2.3.4 上传后视频效果

在这里插入图片描述

3. 文章的总结与预告

3.1 本文总结

trtc录制并上传到vod , 录制结束时根据房间号进行查询 存入数据库 设置重试机制

3.2 代码指正

如有遗漏, 代码错误,流程错误,更优方案等 欢迎评论区指正 谢谢



@author: pingzhuyan
@description: ok
@year: 2024

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

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

相关文章

蓝桥杯 数三角

问题描述 小明在二维坐标系中放置了 n 个点&#xff0c;他想从中选出一个包含三个点的子集&#xff0c;使得这三个点能够组成一个三角形。 由于这样的方案太多了&#xff0c;他决定只选择那些可以组成等腰三角形的方案。 请帮他计算出一共有多少种选法可以组成等腰三角形。 …

【Kafka】从理论到实践的深度解析

在当今数字化转型的时代&#xff0c;企业面临着数据量呈指数级增长、业务系统愈发复杂的挑战。在这样的背景下&#xff0c;高效的数据传输与处理技术成为了关键。Kafka&#xff0c;作为一款分布式消息队列系统&#xff0c;凭借其卓越的性能和丰富的特性&#xff0c;在众多企业的…

Linux课程学习一

一.fopen与fclose函数 linux中fopen函数直接用man fopen 去查看 函数原型 FILE * fopen(constchar *path , cost char *mode) /* * description : 打开一个文件 * param ‐ path : 指定文件路径,如&#xff1a;"./test.txt"&#xff0c;也可以直接由文件名 * param …

【区块链安全 | 第十篇】智能合约概述

部分内容与前文互补。 文章目录 一个简单的智能合约子货币&#xff08;Subcurrency&#xff09;示例区块链基础交易区块预编译合约 一个简单的智能合约 我们从一个基础示例开始&#xff0c;该示例用于设置变量的值&#xff0c;并允许其他合约访问它。 // SPDX-License-Identi…

XML标签格式转换为YOLO TXT格式

针对的是多边形&#xff08;<polygon>&#xff09;来描述对象的边界&#xff0c;而不是传统的矩形框&#xff08;<bndbox>&#xff09; import xml.etree.ElementTree as ET import os from pathlib import Path# 解析VOC格式的XML文件&#xff0c;提取目标框的标…

大唐杯02 DTM.PX4.016

01 5G关键技术概述 回传压力大&#xff1a;核心网向基站回传压力大 02 5G关键技术介绍01

CSS3学习教程,从入门到精通, CSS3 盒子模型的详细语法知识点及案例代码(23)

CSS3 盒子模型的详细语法知识点及案例代码 CSS3 盒子模型完整指南 一、盒子模型基础 每个 HTML 元素都被视为一个矩形盒子&#xff0c;由以下部分组成&#xff1a; 内容区 (Content)内边距 (Padding)边框 (Border)外边距 (Margin) 二、语法知识点详解 1. 盒子的宽和高 sel…

《Linux运维实战:Ubuntu 22.04修改root用户默认名并禁止登录》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;Linux运维实战总结 一、背景信息 由于安全方面的考虑&#xff0c;先要求Ubuntu 22.04系统重的root用户禁止登录&#xff0c;并修改用户名root为ad…

docker-compose自定义网络,解决docker-compose网段路由冲突

问题排查 先route一波查看一下路由表 容器路由19和堡垒机路由冲突 解决方案 更改docker网段更改docker生成容器的网段 > 基本操作 docker network ls &#xff1a;查看docker网络列表 docker network inspect <network id/name>&#xff1a;查看某个docker网络详情…

前端 - ts - - declare声明类型

在使用typeScript的项目中 需要声明属性类型 单独的局部属性 可以直接在当前文件中声明 全局属性需要在项目根目录下新建.d.ts文件 vite会自动识别.d.ts类型文件 在该文件中使用declare声明类型有三种写法 1、在某种类型的文件中声明 2、声明window上的属性类型 3、全局声明…

[Mac]利用Hexo+Github Pages搭建个人博客

由于我这台Mac基本没啥环境&#xff0c;因此需要从零开始配置&#xff0c;供各位参考。 注意⚠️&#xff1a;MacBook (M4)使用/bin/zsh作为默认Shell&#xff0c;其对应的配置文件为~/.zshrc 参考文档&#xff1a; HEXO系列教程 | 使用GitHub部署静态博客HEXO | 小白向教程 文…

运维面试题(十一)

1.如果一个硬盘 IO 时阻塞了&#xff0c;会发生什么情况&#xff1f; 进程/线程挂起&#xff1a;发起I/O操作的进程或线程会被操作系统置为阻塞状态&#xff08;等待状态&#xff09;&#xff0c;直到I/O完成。CPU资源释放&#xff1a;阻塞的线程会让出CPU&#xff0c;操作系统…

sql2022 复制 事务级别发布后无法删除

Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission. 用SA用户登录执行下列语句 USE [xxxxx] GO EXEC dbo.sp_changedbowner loginame Nsa, …

合规+增效 正也科技携智能营销产品出席中睿论坛

正也科技作为医药数字化领域的标杆企业&#xff0c;受邀参展第二届中睿医健产业企业家年会暨第十三届中睿医药新春论坛&#xff0c;本次论坛以“合力启新程”为主题&#xff0c;吸引了800多位医药健康企业的董事长、总经理参与&#xff0c;并通过主论坛、分论坛、路演等形式探讨…

ubuntu 安装 postgresql

在 Ubuntu 系统中安装 PostgreSQL 的步骤如下&#xff1a; 步骤 1&#xff1a;更新软件包列表 sudo apt update步骤 2&#xff1a;安装 PostgreSQL Ubuntu 默认仓库包含 PostgreSQL&#xff0c;直接安装&#xff1a; sudo apt install postgresql postgresql-contrib -ypost…

智能巡检机器人:2025年企业安全运维的“数字哨兵“

文章目录 一、2025年&#xff0c;为什么企业需要智能巡检机器人&#xff1f;二、2025年智能巡检机器人的六大核心价值三、2025行业落地实景1. 电网系统——"巡线鹰"集群作战2. 化工园区——"防爆卫士"全天候守护3. 数据中心——"冷血侦探"精准运…

K8S学习之基础五十一:k8s部署jenkins

k8s部署jenkins 创建nfs共享目录&#xff0c; mkdir -p /data/v2 echo /data/v2 *(rw,no_root_squash) > /etc/exports exportfs -arv创建pv、pvc vi pv.yaml apiVersion: v1 kind: PersistentVolume metadata:name: jenkins-k8s-pv spec:capacity:storage: 1GiaccessMod…

Vue实现的表格多选方案支持跨页选择和回显功能

以下是纯Vue实现的表格多选方案&#xff08;不依赖UI库&#xff09;&#xff0c;支持跨页选择和回显功能&#xff1a; <template><div class"custom-table"><!-- 表格主体 --><table><thead><tr><th><input type"…

Oracle 19C 备份

在 Oracle 19c 中&#xff0c;备份数据库通常使用 RMAN&#xff08;Recovery Manager&#xff09; 工具&#xff0c;它是 Oracle 提供的官方备份和恢复工具。以下是通过 RMAN 备份 Oracle 19c 数据库的详细步骤和命令。 一、RMAN 基本概念 RMAN 是 Oracle 的备份和恢复工具&am…

Elasticsearch:人工智能时代的公共部门数据治理

作者&#xff1a;来自 Elastic Darren Meiss 人工智能&#xff08;AI&#xff09;和生成式人工智能&#xff08;GenAI&#xff09;正在迅速改变公共部门&#xff0c;从理论探讨走向实际应用。正确的数据准备、管理和治理将在 GenAI 的成功实施中发挥关键作用。 我们最近举办了…