欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java 基于SSM整合阿里直播服务框架

程序员文章站 2022-04-15 17:51:49
上篇文章介绍了阿里直播服务的前期配置和简单的测试,这篇文章我们来介绍使用java语言进行推流和播流的链接生成。1.首先需要导入maven依赖com.aliyunaliyun-java-sdk-live3.8.0

这篇文章我们来介绍使用java语言进行推流和播流的链接生成。

1.首先需要导入maven依赖

 <!--阿里云直播--> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-live</artifactId> <version>3.8.0</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-vod</artifactId> <version>2.7.0</version> </dependency> <!-- Hutool工具包 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.0.12</version> </dependency> 

2.创建一个AliyunLiveConfig类,设置一些参数

package com.inxedu.os.common.live; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /**
 * 描述:
 *
 * @author gJK
 * @create 2020-07-12 10:55
 */ @Data @Component public class AliYunLiveConfig { /**
     * 推流域名
     * 在上篇文章中我们设置的推流域名
     */ @Value("www.填写自己实设置的.cn") private String aliyunLivePushDomain; /**
     * 拉流域名
     */ @Value("www.填写自己实设置的.cn") private String aliyunLivePullDomain; /**
     * appName
     * 这个根据自己情况设置
     */ @Value("inxedu") private String aliyunLiveAppName; /**
     * 直播流名称streamName{直播类型}_{类型id}:可以给个时间戳
     */ @Value("") private String aliyunLiveStreamName; /**
     * 推流鉴权url key
     */ @Value("r1raw0LhU5") private String aliyunLivePushIdentKey; /**
     * 拉流鉴权url key
     */ @Value("EWAkkktIDhk") private String aliyunLivePullIdentKey; /**
     * 鉴权url的有效时间(秒),默认30分钟,1800秒 key
     * 默认是1800秒,我设置成86400,这是最大值
     */ @Value("86400") private Integer aliyunLiveIdentUrlValidTime; /**
     * OSS-区域代码
     */ @Value("cn-beijing") private String regionId; /**
     * OSS-RAM 访问控制-人员管理-用户 AccessKey
     */ @Value("LQAIJIAyMSll2xis") private String accessKeyId; /**
     * OSS-RAM 访问控制-人员管理-用户 secret
     */ @Value("F8Z8RkNS9WdvZdjx") private String secret; } 

3. 创建推流和播流的工具类

package com.inxedu.os.common.live; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.DigestUtil; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.IAcsClient; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.exceptions.ServerException; import com.aliyuncs.profile.DefaultProfile; import java.util.*; import com.aliyuncs.live.model.v20161101.*; /**
 * 描述:
 *
 * @author gJK
 * @create 2020-07-12 12:25
 */ public class AliYunLiveUtil{ /**
     * 我这里传入了一个主播用户的ID,根据用户id创建该id的推流url
     * 假设传入的sysUserId = 1
     * @param aliYunLiveConfig
     * @return
     */ public static String createLivePushUrl(Integer sysUserId,AliYunLiveConfig aliYunLiveConfig) { // 推流域名 String pushDomain = aliYunLiveConfig.getAliyunLivePushDomain(); // 应用名称 String appName = aliYunLiveConfig.getAliyunLiveAppName(); // 流名称streamNameDemo String streamName = StrUtil.format(sysUserId+""); // 推流签名 String pushIdentKey = aliYunLiveConfig.getAliyunLivePushIdentKey(); // 签名url有效时间 Integer identUrlValidTime = aliYunLiveConfig.getAliyunLiveIdentUrlValidTime(); // 计算过期时间 String timestamp = String.valueOf((System.currentTimeMillis() / 1000) + identUrlValidTime); //rtmp://{pushDomain}/{appName}/{streamName} //拼接后输出rtmp://www.video2.zhuyueedu.cn/inxedu/1 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); // md5加密 String md5Str = DigestUtil.md5Hex(md5Url); // 组合最终鉴权过的推流域名 // {rtmpUrl}?auth_key={timestamp}-0-0-{md5Str} String finallyPushUrl = StrUtil.format("{}?auth_key={}-0-0-{}", rtmpUrl, timestamp, md5Str); //会返回我们上片文章中的完整的推流url地址, //我们通过各个参数的拼接,最终拼接成阿里要求的格式即可 return finallyPushUrl; } /**
     *播流有三种格式,我只需要拼接不同的类型就行
     * 创建拉流域名,key=rtmpUrl、flvUrl、m3u8Url,代表三种拉流类型域名
     * @param
     * @return
     */ public static Map<String,Object> createLivePullUrl(Integer sysUserId,AliYunLiveConfig aliYunLiveConfig) { Map<String,Object> map = new HashMap(); // 拉流域名 String pullDomain = aliYunLiveConfig.getAliyunLivePullDomain(); // 应用名称inxedu String appName = aliYunLiveConfig.getAliyunLiveAppName(); // 流名称 String streamName = StrUtil.format(sysUserId+""); // 拉流签名 String pullIdentKey = aliYunLiveConfig.getAliyunLivePullIdentKey(); // 签名url有效时间 Integer identUrlValidTime = aliYunLiveConfig.getAliyunLiveIdentUrlValidTime(); // 计算过期时间 String timestamp = String.valueOf((System.currentTimeMillis() / 1000) + identUrlValidTime); // 组合通用域名 // {pullDomain}/{appName}/{streamName} String pullUrl = StrUtil.format("{}/{}/{}", pullDomain, appName, streamName); // 组合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); // 组合三种拉流域名前缀 //        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); map.put("rtmpUrl",rtmpUrl); map.put("flvUrl",flvUrl); map.put("m3u8Url",m3u8Url); return map; } 

推流和播流的工具类写完之后,其他地方调用即可。剩下就是业务逻辑了,根据自己项目的需要在合理的地方进行调用。

----------------------------------------华丽的分割---------------------------------------

在项目中浪费时间最长的就是推流地址回调接口的 使用。

这个回调有上面用呢?就是当主播在OBS上点击‘开始推流’或者‘停止推流’时,返回给我们的数据。
这些数据里包括当前直播流是否关闭,当我得到这些就可以更改数据库直播状态的字段,来通知用户当前直播是否结束或者是否正在直播。
1.首先去阿里官方进行配置回调地址
Java 基于SSM整合阿里直播服务框架
2.这里地址是你项目域名的地址,后面的/live/callBackPath,是你在后台controller中方法@GetMapping("/live/callBackPath")对应的地址;
Java 基于SSM整合阿里直播服务框架

3.这个回调地址唯一不好的是,在本地调试的话根本进不来,所以我们需要想办法。这里当时用的花生壳,有免费的1G流量进行测试,足够了。注册后把阿里域名管理里面的配置回调地址换成花生的域名即可,切记项目上线后记得换诚自己项目的域名。这样配置后,你在本地项目debug就可以调试了
Java 基于SSM整合阿里直播服务框架
4.这是我本地回调接口方法

 /**
     * 推流地址回调接口 根据返回状态值进行业务处理
     *
     *action是直播的状态,‘publish’则是直播中, 'publish_done‘直播关闭
     * {
     *   'action': 'publish',  
     *   'ip': {回调地址ip},   
     *   'id': {推流流名},
     *   'app': {推流域名},
     *   'appname': {推流app名},
     *   'time': {timestamp},
     *   'usrargs': {用户参数},
     *   'node': {内部节点ip}
     * }
     *
     */ @GetMapping("/live/callBackPath") public void callBackPath(HttpServletRequest request){ try { //Live是自己定义的实体类 Live live = new Live(); // 接收回调得到参数 Map<String, String[]> parameterMap = request.getParameterMap(); //将接收的map转为我们写的ApiLiveModel,下面就可以直接通过变量获取 ApiLiveModel model = JSONObject.parseObject(JSON.toJSONString(parameterMap),ApiLiveModel.class); // 实现效果   根据回调接口 publish_done:关闭直播   publish 开启直播 if (model != null){ //直播状态值:publish:正在直播,publish_done:关闭直播 String action = model.getAction().get(0); //获取直播状态值 String sysUserId = model.getId().get(0);//老师id if (action.equals("publish")){ log.info("开启直播状态"); //更新状态 并生成拉流地址 live.setStatus(1);//直播状态;1:直播中;2:待开始;3:已结束 //生成拉流URL Map<String, Object> livePullUrl = AliYunLiveUtil.createLivePullUrl(Integer.valueOf(sysUserId).intValue(), aliYunLiveConfig); /*String rtmpUrl = livePullUrl.get("rtmpUrl").toString();*/ String flvUrl = livePullUrl.get("flvUrl").toString(); String m3u8Url = livePullUrl.get("m3u8Url").toString(); live.setPullM3u8Url(m3u8Url);//保存移动拉流url live.setPullFlvUrl(flvUrl);//PC端拉流 liveService.updateStatusAndPullUrlByUserId(Integer.valueOf(sysUserId).intValue(),live); log.info("更新状态、拉流url成功"); }else if (action.equals("publish_done")){ //更新状态 并生成拉流地址 live.setStatus(3);//直播状态;1:直播中;2:待开始;3:已结束 //liveService.updateStatusByUserId(Integer.valueOf(sysUserId).intValue(),live); liveService.deleteByUserId(Integer.valueOf(sysUserId).intValue()); log.info("关闭直播状态"); } } }catch (Exception e){ e.printStackTrace(); } } 

5.这是Live实体类,对应数据库表和字段

package com.inxedu.os.edu.entity.live; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import java.util.Date; /**
 * 描述:
 *
 * @author gJK
 * @create 2020-07-14 10:53
 */ @Data @EqualsAndHashCode(callSuper = false) @AllArgsConstructor @NoArgsConstructor public class Live { private Integer liveId;//直播主键ID private Integer userId;//管理员id private Date startTime;//直播开始时间 private Integer duration;//直播时长 private Integer status;//直播状态 private Integer totalNum;//在线人数 private String pushUrl;//推流地址 private String pullM3u8Url;//移动端拉流地址 private String pullFlvUrl;//PC端拉流地址 private String liveDescribe;//直播介绍 private String title;//直播标题 private String liver;//直播老师姓名 private String roomKey;//房间密码 private String liveType;//直播课类型 } 

差不多我就用到这些了,还有在线人数统计,但是我没有用,我用的webSocekt统计的在线人数。阿里的在线人数也需要设置回调地址,原理一样,缺点就是5分钟更新一次人数,太慢了,所以就没有用阿里的。

以下这是我的效果图,聊天室是用的webSocket进行实现的,实时统计在线人数。
Java 基于SSM整合阿里直播服务框架

----------------------------------------华丽的分割---------------------------------------

分享基本就到此结束了,第一次做文章,在格式上和美观上都有很多欠缺。内容应该些的也不是很详细,如果我哪里些的不是很明白的可以私聊或者在评论中讨论。

如果文章对你有 一丁点的帮助,就多多支持吧!

文章地址:https://blog.csdn.net/q0505123/article/details/108239523