欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > IM腾讯Trtc与vod云点播:实现合流录制并上传,根据参数返回视频地址

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

2025/3/31 5:45:39 来源:https://blog.csdn.net/pingzhuyan/article/details/146529706  浏览:    关键词: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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词