经历了几天的周折,近期才把项目完成,在这里与大家分享一下踩坑之路,也方便日后有类似项目,可以借阅一番
开发直播前先满足已下条件
1.开通视频直播功能
2.购买好了OSS存储
3.购买两个域名并且备案好,一个用来拉流,一个用来播流,
4.建议CNAM加速也设置好这样直播没那么卡
该项目是一个H5直播,采用m3u8格式完成直播的展示。通过推流地址,借助第三方推流工具实现直播效果,比如:OBS 或者一些微信小程序 小推流。。等等
项目介绍:根据域名生成推流、播流地址,推流回调,检查推流状态。直播视频存储至OSS,视频回调,统计当前在线人数等等
项目需要:需要现在阿里云上配置你的域名,推流域名,播流域名,推流回调地址,OSS存储,播流跨域问题等等
进入正题:
根据推拉域名生成推流地址与播流地址
配置pom文件
<!--阿里云直播-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.4.6</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-live</artifactId>
<version>3.8.0</version>
</dependency>
<!-- Hutool工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.0.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.48</version>
</dependency>
配置你的阿里云参数AliYunConfig streamName这里是自定义的直播类型 根据你的需求而定,我的直播类型这里就没写
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
@Data
public class AliYunConfig {
/**
* 推流域名
*/
@Value("")
private String aliyunLivePushDomain;
/**
* 拉流域名
*/
@Value("")
private String aliyunLivePullDomain;
/**
* 直播测试appName
*/
@Value("")
private String aliyunLiveAppName;
/**
* 直播测试streamName{直播类型}_{类型id}
*/
@Value("")
private String aliyunLiveStreamName;
/**
* 推流鉴权url key
*/
@Value("")
private String aliyunLivePushIdentKey;
/**
* 拉流鉴权url key
*/
@Value("")
private String aliyunLivePullIdentKey;
/**
* 鉴权url的有效时间(秒),默认30分钟,1800秒 key
*/
@Value("1800")
private Integer aliyunLiveIdentUrlValidTime;
/**
* OSS-区域代码
*/
@Value("cn-shanghai")
private String regionId;
/**
* OSS-RAM 访问控制-人员管理-用户 AccessKey
*/
@Value("")
private String accessKeyId;
/**
* OSS-RAM 访问控制-人员管理-用户 secret
*/
@Value("")
private String secret;
}
配置阿里云AliYunUtil
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.gs.body.alilive.AliyunLiveUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class AliYunUtil {
private static final Logger log = LoggerFactory.getLogger(AliyunLiveUtil.class);
/**
* 推拉流地址示例:
* rtmp://www.ttest.ygdjonline.com/a/a?auth_key=1558065152-0-0-c3cb54d946c0590ca9aeee63573201ee
* 播流地址
* 原画
* rtmp://www.btest.ygdjonline.com/a/a?auth_key=1558065152-0-0-fc711455c0815aeb581385f33451d5b4
* http://www.btest.ygdjonline.com/a/a.flv?auth_key=1558065152-0-0-221abff1da1ee32151e365cf0dd42a53
* http://www.btest.ygdjonline.com/a/a.m3u8?auth_key=1558065152-0-0-72124fcc3aee3404b0d65dcc114e207f
*/
/**
* 根据源id创建该id的推流url
*
* @param sourceId
* @param aliyunConfig
* @return
*/
public static String createPushUrl(String sourceId, AliYunConfig aliyunConfig) {
// 推流域名
String pushDomain = aliyunConfig.getAliyunLivePushDomain();
// 应用名称
String appName = aliyunConfig.getAliyunLiveAppName();
// 流名称
String streamName = StrUtil.format(sourceId);
// 推流签名key
String pushIdentKey = aliyunConfig.getAliyunLivePushIdentKey();
// 签名url有效时间
Integer identUrlValidTime = aliyunConfig.getAliyunLiveIdentUrlValidTime();
//log.info("签名url有效时间" + identUrlValidTime);
// 计算过期时间
String timestamp = String.valueOf((System.currentTimeMillis() / 1000) + identUrlValidTime);
// log.info("计算过期时间" + timestamp);
// 组合推流域名前缀
//rtmp://{pushDomain}/{appName}/{streamName}
String rtmpUrl = StrUtil.format("rtmp://{}/{}/{}", pushDomain, appName, streamName);
// 组合md5加密串
///{appName}/{streamName}-{timestamp}-0-0-{pushIdentKey}
String md5Url = StrUtil.format("/{}/{}-{}-0-0-{}", appName, streamName, timestamp, pushIdentKey);
log.info("组合md5加密串"+md5Url);
// md5加密
String md5Str = DigestUtil.md5Hex(md5Url);
// log.info("md5加密串,md5Url=" + md5Url + "------md5加密结果,md5Str=" + md5Str);
// 组合最终鉴权过的推流域名
// {rtmpUrl}?auth_key={timestamp}-0-0-{md5Str}
String finallyPushUrl = StrUtil.format("{}?auth_key={}-0-0-{}", rtmpUrl, timestamp, md5Str);
log.info("最终鉴权过的推流域名=" + finallyPushUrl);
return finallyPushUrl;
}
/**
* 创建拉流域名,key=rtmpUrl、flvUrl、m3u8Url,代表三种拉流类型域名
*
* @param sourceId
* @param aliyunConfig
* @return
*/
public static String createPullUrl(String sourceId, AliYunConfig aliyunConfig) {
// 拉流域名
String pullDomain = aliyunConfig.getAliyunLivePullDomain();
// 应用名称
String appName = aliyunConfig.getAliyunLiveAppName();
// 流名称
String streamName = StrUtil.format(sourceId);
// 拉流签名key
String pullIdentKey = aliyunConfig.getAliyunLivePullIdentKey();
// 签名url有效时间
Integer identUrlValidTime = aliyunConfig.getAliyunLiveIdentUrlValidTime();
// 计算过期时间
String timestamp = String.valueOf((System.currentTimeMillis() / 1000) + identUrlValidTime);
// 组合通用域名
// {pullDomain}/{appName}/{streamName}
String pullUrl = StrUtil.format("{}/{}/{}", pullDomain, appName, streamName);
//log.info("组合通用域名,pullUrl=" + pullUrl);
// 组合md5加密串
// /{appName}/{streamName}-{timestamp}-0-0-{pullIdentKey}
String md5Url = StrUtil.format("/{}/{}-{}-0-0-{}", appName, streamName, timestamp, pullIdentKey);
String md5FlvUrl = StrUtil.format("/{}/{}.flv-{}-0-0-{}", appName, streamName, timestamp, pullIdentKey);
String md5M3u8Url = StrUtil.format("/{}/{}.m3u8-{}-0-0-{}", appName, streamName, timestamp, pullIdentKey);
// md5加密
String md5Str = DigestUtil.md5Hex(md5Url);
String md5FlvStr = DigestUtil.md5Hex(md5FlvUrl);
String md5M3u8Str = DigestUtil.md5Hex(md5M3u8Url);
//log.info("md5加密串,md5Url =" + md5Url + " ------ md5加密结果,md5Str=" + md5Str);
//log.info("md5加密串,md5FlvUrl =" + md5FlvUrl + " ------ md5加密结果,md5FlvStr=" + md5FlvStr);
//log.info("md5加密串,md5M3u8Url=" + md5M3u8Url + " ------ md5加密结果,md5M3u8Str=" + md5M3u8Str);
// 组合三种拉流域名前缀
// rtmp://{pullUrl}?auth_key={timestamp}-0-0-{md5Str}
String rtmpUrl = StrUtil.format("rtmp://{}?auth_key={}-0-0-{}", pullUrl, timestamp, md5Str);
// http://{pullUrl}.flv?auth_key={timestamp}-0-0-{md5FlvStr}
String flvUrl = StrUtil.format("http://{}.flv?auth_key={}-0-0-{}", pullUrl, timestamp, md5FlvStr);
// http://{pullUrl}.m3u8?auth_key={timestamp}-0-0-{md5M3u8Str}
String m3u8Url = StrUtil.format("http://{}.m3u8?auth_key={}-0-0-{}", pullUrl, timestamp, md5M3u8Str);
log.info("最终鉴权过的拉流rtmp域名=" + rtmpUrl);
log.info("最终鉴权过的拉流flv域名 =" + flvUrl);
log.info("最终鉴权过的拉流m3u8域名=" + m3u8Url);
return m3u8Url;
}
}
通过GetMapping 生成推流 拉流地址
@Resource
private AliYunConfig aliyunConfig;
/**
* 生成推流播流地址
* sourceId 在这里我将它设置为房间号
*/
@GetMapping("/save_Live")
public void save_Live(HttpServletRequest request, @RequestParam("sourceId") String sourceId){
try {
//生成推流地址
String pushUrl = AliYunUtil.createPushUrl(sourceId, aliyunConfig);
//生成播流地址
String pullUrl = AliYunUtil.createPullUrl(sourceId, aliyunConfig);
} catch (Exception e) {
e.printStackTrace();
}
}
如果你的播流地址,存在跨域问题,请在阿里云上配置HTTP响应头,这里添加一个*号即可
现在开始走回调接口,这里需要你在阿里云上配置你的回调地址,是以http开头的
推流地址接口 同样也是GET形式的 阿里云返回的参数定义可以参考:https://help.aliyun.com/document_detail/84943.html?spm=a2c4g.11186623.2.27.44c63dd286Dtq1#concept-84943-zh
/**
* 推流地址回调接口 根据返回状态值进行业务处理
*/
@GetMapping("/callBackPath")
public void test(HttpServletRequest request){
/**
* 返回参数
* action:[publish].......
*/
try {
Map<String, String[]> parameterMap = request.getParameterMap();
ApiLiveModel model = JSONObject.parseObject(JSON.toJSONString(parameterMap),ApiLiveModel.class);
// 实现效果 根据回调接口 publish_done:关闭直播 publish 开启直播
if (model != null){
String action = model.getAction().get(0); //获取直播状态值
String houseId = model.getId().get(0); //获取直播房间号
if (action.equals("publish")){
log.info("开启直播状态");
//业务处理
}else if (action.equals("publish_done")){
log.info("关闭直播状态");
//业务处理
}
}
}catch (Exception e){
e.printStackTrace();
}
}
定义返回参数的model类
import java.util.List;
public class ApiLiveModel {
private List<String> action;
private List<String> ip;
private List<String> id;
private List<String> app;
private List<String> appname;
private List<String> time;
private List<String> usrargs;
private List<String> node;
public List<String> getAction() {
return action;
}
public void setAction(List<String> action) {
this.action = action;
}
public List<String> getIp() {
return ip;
}
public void setIp(List<String> ip) {
this.ip = ip;
}
public List<String> getId() {
return id;
}
public void setId(List<String> id) {
this.id = id;
}
public List<String> getApp() {
return app;
}
public void setApp(List<String> app) {
this.app = app;
}
public List<String> getAppname() {
return appname;
}
public void setAppname(List<String> appname) {
this.appname = appname;
}
public List<String> getTime() {
return time;
}
public void setTime(List<String> time) {
this.time = time;
}
public List<String> getUsrargs() {
return usrargs;
}
public void setUsrargs(List<String> usrargs) {
this.usrargs = usrargs;
}
public List<String> getNode() {
return node;
}
public void setNode(List<String> node) {
this.node = node;
}
}
视频存储至阿里云OSS,需要配置Bucket,然后在域名管理,录制配置中添加配置
这样你的直播视频,就存放至阿里云上了,在这里有一个问题需要解决,m3u8格式的在线预览,需要配置一下跨域问题,不然无法播放。参考地址:https://help.aliyun.com/document_detail/31903.html?spm=a2c4g.11174283.6.1124.369f7da2kWLpA2
接下来就是视频回调了,同样也需要在阿里云配置你的视频回调接口,这里也是http开头的
接下来就是代码片段了,具体的返回参数,请参考:https://help.aliyun.com/document_detail/84935.html?spm=5176.13910061.0.0.6b2b7018cRAX1h&aly_as=qJRVAQTxQ
//录制视频存储到OSS 回调接口
@PostMapping("/api_p/addLive")
public void addLive(@RequestBody ApiSaveLiveModel model) throws IOException {
try{
/**
* 返回参数
* {
* "domain": "live.aliyunlive.com",
* "app": "live",
* "stream": "hello",
* "uri": "live/hello/0_2017-03-08-23:09:46_2017-03-08-23:10:40.flv",
* "duration": 69.403,
* "start_time": 1488985786,
* "stop_time": 1488985840
* }
* 具体参数详情请参考:https://help.aliyun.com/document_detail/84935.html?spm=5176.13910061.0.0.6b2b7018cRAX1h&aly_as=qJRVAQTxQ
*/
log.info("保存作品成功");
}catch (Exception e){
log.info("保存作品失败");
e.printStackTrace();
}
}
回调参数model
public class ApiSaveLiveModel {
/**
* domain : live.aliyunlive.com
* app : live
* stream : hello
* uri : live/hello/0_2017-03-08-23:09:46_2017-03-08-23:10:40.flv
* duration : 69.403
* start_time : 1488985786
* stop_time : 1488985840
*/
private String domain;
private String app;
private String stream;
private String uri;
private double duration;
private int start_time;
private int stop_time;
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getApp() {
return app;
}
public void setApp(String app) {
this.app = app;
}
public String getStream() {
return stream;
}
public void setStream(String stream) {
this.stream = stream;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public double getDuration() {
return duration;
}
public void setDuration(double duration) {
this.duration = duration;
}
public int getStart_time() {
return start_time;
}
public void setStart_time(int start_time) {
this.start_time = start_time;
}
public int getStop_time() {
return stop_time;
}
public void setStop_time(int stop_time) {
this.stop_time = stop_time;
}
@Override
public String toString() {
return "ApiSaveLiveModel{" +
"domain='" + domain + '\'' +
", app='" + app + '\'' +
", stream='" + stream + '\'' +
", uri='" + uri + '\'' +
", duration=" + duration +
", start_time=" + start_time +
", stop_time=" + stop_time +
'}';
}
}
接下来就是 根据当前播流地址,统计在线人数,统计HLS直播的在线人数, 我们需要客户端在请求的参数中带上唯一标识用户的uuid,在阿里云cdn使用的默认参数是aliyun_uuid,言下之意就是每当用户访问的时候,会携带这个uuid,通过这个uuid 来获取当前播流域名的在线人数
重要说明:统计m3u8格式的在线人数,需要通过阿里云工单申请
具体的参数可以找阿里云人工要一份,是PDF版,网上也有博客,但是我找不到了
//根据播流地址 查询当前在线人数
public static Integer getPeopleSum() throws ClientException {
/**
* 返回参数
*
* time : 2020-04-20T03:40:00Z
* requestId : A76B853C-AB5A-4F02-96C5-BDAB1A485FAC
* usageData : [{"domainName":"boliu.comwinwin.com","streamInfos":[{"streamName":"/jingbei/82889.m3u8","infos":[{"downFlow":609.5467,"rate":"origin","online":1}]}]}]
*
* online:指的是当前的在线人数
*
*/
try{
DescribeHlsLiveStreamRealTimeBpsDataRequest listRequest2 = new DescribeHlsLiveStreamRealTimeBpsDataRequest();
listRequest2.setDomainName("boliu.comwinwin.com"); //播流域名
listRequest2.setTime(getTime()); //UTC格式当前时间 归属地
DefaultProfile profile = DefaultProfile.getProfile("cn-beijing", "LTAI4G84ApyG4K1x4v9JHaXC", "d4iWslw08vidnqtYB8IpaHLLfsVp9e");
IAcsClient iAcsClient = new DefaultAcsClient(profile);//配置的参数
DescribeHlsLiveStreamRealTimeBpsDataResponse response = iAcsClient.getAcsResponse(listRequest2);//获取直播人数 List<DescribeHlsLiveStreamRealTimeBpsDataResponse.UsageDataPerDomain> usageDatas = usageDatasResponse.getUsageData();//获取直播状态 for (DescribeHlsLiveStreamRealTimeBpsDataResponse.UsageDataPerDomain usageData : usageDatas) { if (usageData.getDomainName().equals("播流域名(补全)")) {
//获取阿里云返回的结果,根据结果处理得到当前播放流下在线人数
String str = new Gson().toJson(response);
ApiPersonSumModel mode = JSON.parseObject(str, ApiPersonSumModel.class);
return 0;
}catch (Exception e){
return 0;
}
}
/**
* 获取当前在线时间 UTC 格式时间
* @return
*/
public static String getTime(){
Date date = new Date();// 获取当前时间
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int zoneOffset = calendar.get(Calendar.ZONE_OFFSET);
int dstOffset = calendar.get(Calendar.DST_OFFSET);
calendar.add(Calendar.MILLISECOND, -(zoneOffset + dstOffset));
long timeInMillis = calendar.getTimeInMillis();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
return df.format(timeInMillis);
}
返回参数的model类
import java.util.List;
public class ApiPersonSumModel {
/**
* time : 2020-04-20T03:40:00Z
* requestId : A76B853C-AB5A-4F02-96C5-BDAB1A485FAC
* usageData : [{"domainName":"boliu.comwinwin.com","streamInfos":[{"streamName":"/jingbei/82889.m3u8","infos":[{"downFlow":609.5467,"rate":"origin","online":1}]}]}]
*/
private String time;
private String requestId;
private List<UsageDataApiPersonSumModel> usageData;
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getRequestId() {
return requestId;
}
public void setRequestId(String requestId) {
this.requestId = requestId;
}
public List<UsageDataApiPersonSumModel> getUsageData() {
return usageData;
}
public void setUsageData(List<UsageDataApiPersonSumModel> usageData) {
this.usageData = usageData;
}
public static class UsageDataApiPersonSumModel {
/**
* domainName : boliu.comwinwin.com
* streamInfos : [{"streamName":"/jingbei/82889.m3u8","infos":[{"downFlow":609.5467,"rate":"origin","online":1}]}]
*/
private String domainName;
private List<StreamInfosApiPersonSumModel> streamInfos;
public String getDomainName() {
return domainName;
}
public void setDomainName(String domainName) {
this.domainName = domainName;
}
public List<StreamInfosApiPersonSumModel> getStreamInfos() {
return streamInfos;
}
public void setStreamInfos(List<StreamInfosApiPersonSumModel> streamInfos) {
this.streamInfos = streamInfos;
}
public static class StreamInfosApiPersonSumModel {
/**
* streamName : /jingbei/82889.m3u8
* infos : [{"downFlow":609.5467,"rate":"origin","online":1}]
*/
private String streamName;
private List<InfosApiPersonSumModel> infos;
public String getStreamName() {
return streamName;
}
public void setStreamName(String streamName) {
this.streamName = streamName;
}
public List<InfosApiPersonSumModel> getInfos() {
return infos;
}
public void setInfos(List<InfosApiPersonSumModel> infos) {
this.infos = infos;
}
public static class InfosApiPersonSumModel {
/**
* downFlow : 609.5467
* rate : origin
* online : 1
*/
private double downFlow;
private String rate;
private int online;
public double getDownFlow() {
return downFlow;
}
public void setDownFlow(double downFlow) {
this.downFlow = downFlow;
}
public String getRate() {
return rate;
}
public void setRate(String rate) {
this.rate = rate;
}
public int getOnline() {
return online;
}
public void setOnline(int online) {
this.online = online;
}
}
}
}
}
定时器查询录制保存的视频
/**
* 每隔30分钟执行一次 直播录制视频没有回调的
* 要重新调用阿里云录制视频查询接口:
* 参考地址 https://help.aliyun.com/document_detail/35421.html?spm=a2c4g.11186623.6.757.30f151e7YjXnFO
*/
@Scheduled(cron = "0 */30 * * * ?")
public void updatePublisPushTime() {
List<CourseItem> courseItemList = courseItemDao.getLiveList();
if(courseItemList != null && !courseItemList.isEmpty()){
for(CourseItem courseItem :courseItemList){
//封装录制视频查询接口需要的参数
DefaultProfile profile = DefaultProfile.getProfile(aliYunLiveConfig.getRegionId(),
aliYunLiveConfig.getAccessKeyId(), aliYunLiveConfig.getSecret());
IAcsClient client = new DefaultAcsClient(profile);
DescribeLiveStreamRecordIndexFilesResponse response = null;
List<RecordIndexInfo> recordIndexInfoList = null;
DescribeLiveStreamRecordIndexFilesRequest request = new DescribeLiveStreamRecordIndexFilesRequest();
request.setRegionId(aliYunLiveConfig.getRegionId());
request.setAppName(aliYunLiveConfig.getAliyunLiveAppName()); //直播流所属应用名称。
request.setStreamName(courseItem.getId().toString()); //直播流名称。 也是课节id
/**
* 开始时间,格式:UTC时间。示例:2015-12-01T17:36:00Z
*/
request.setStartTime(DateUtil.utcDateStr(courseItem.getBeginDate()));
/**
* 结束时间。与StartTime的间隔时间不能超过4天。格式:UTC时间。示例:2015-12-01T17:36:00Z。
*/
request.setEndTime(DateUtil.utcDateStr(courseItem.getEndDate()));
request.setDomainName(aliYunLiveConfig.getAliyunLivePullDomain()); //您的加速域名
try {
//调用查询接口
response = client.getAcsResponse(request);
log.info("调用阿里云录制视频查询接口返回: " + new Gson().toJson(response));
recordIndexInfoList = response.getRecordIndexInfoList();
if(recordIndexInfoList != null && !recordIndexInfoList.isEmpty() ){
courseItem.setItemUrl(recordIndexInfoList.get(0).getRecordUrl());
courseItemDao.update(courseItem);
}
} catch (ClientException e) {
log.error("调用阿里云录制视频查询接口错误ErrCode: " + e.getErrCode());
log.error("调用阿里云录制视频查询接口错误ErrMsg: " + e.getErrMsg());
log.error("调用阿里云录制视频查询接口错误RequestId: " + e.getRequestId());
} catch (Exception e1){
log.error("调用阿里云录制视频查询接口错误: " + e1.getMessage());
}
}
}
}
/**
*
* <p>Description: 北京时间转化为UTC时间</p>
* @param date 指定时间
* @return
*
*/
public static String utcDateStr(Date date) {
try{
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
long localTimeInMillis=date.getTime();
/** long时间转换成Calendar */
Calendar calendar= Calendar.getInstance();
calendar.setTimeInMillis(localTimeInMillis);
/** 取得时间偏移量 */
int zoneOffset = calendar.get(java.util.Calendar.ZONE_OFFSET);
/** 取得夏令时差 */
int dstOffset = calendar.get(java.util.Calendar.DST_OFFSET);
/** 从本地时间里扣除这些差量,即可以取得UTC时间*/
calendar.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));
/** 取得的时间就是UTC标准时间 */
Date utcDate=new Date(calendar.getTimeInMillis());
String utcDateStr = format.format(utcDate);
return utcDateStr;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
/**
* 同一个推流 多个视频文件合并成一个 只支持m3u8录制格式
* 创建某个时间范围的M3U8索引文件
* 参考地址 https://help.aliyun.com/document_detail/35417.html
*/
public void createLiveStreamRecordIndexFiles(){
DefaultProfile profile = DefaultProfile.getProfile(aliYunLiveConfig.getRegionId(),
aliYunLiveConfig.getAccessKeyId(), aliYunLiveConfig.getSecret());
IAcsClient client = new DefaultAcsClient(profile);
CreateLiveStreamRecordIndexFilesRequest request = new CreateLiveStreamRecordIndexFilesRequest();
request.setRegionId(aliYunLiveConfig.getRegionId());
request.setAppName(aliYunLiveConfig.getAliyunLiveAppName());
request.setStreamName("61");
request.setOssEndpoint("oss-cn-shenzhen.aliyuncs.com");
request.setOssBucket("fssh-video");
request.setOssObject("course/live/record/live/record/61.m3u8");
request.setStartTime("2020-07-12T17:36:00Z");
request.setEndTime("2020-07-14T17:36:00Z");
request.setDomainName(aliYunLiveConfig.getAliyunLivePullDomain());
try {
CreateLiveStreamRecordIndexFilesResponse response = client.getAcsResponse(request);
log.info(new Gson().toJson(response));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
log.info("ErrCode:" + e.getErrCode());
log.info("ErrMsg:" + e.getErrMsg());
log.info("RequestId:" + e.getRequestId());
}
}