基于SSM整合阿里直播服务----java代码实现
上篇文章介绍了阿里直播服务的前期配置和简单的测试,这篇文章我们来介绍使用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();// 流名称streamNameDemoString 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/1String 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();// 应用名称inxeduString 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.首先去阿里官方进行配置回调地址
2.这里地址是你项目域名的地址,后面的/live/callBackPath,是你在后台controller中方法@GetMapping("/live/callBackPath")对应的地址;
3.这个回调地址唯一不好的是,在本地调试的话根本进不来,所以我们需要想办法。这里当时用的花生壳,有免费的1G流量进行测试,足够了。注册后把阿里域名管理里面的配置回调地址换成花生的域名即可,切记项目上线后记得换诚自己项目的域名。这样配置后,你在本地项目debug就可以调试了
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);//老师idif (action.equals("publish")){log.info("开启直播状态");//更新状态 并生成拉流地址live.setStatus(1);//直播状态;1:直播中;2:待开始;3:已结束//生成拉流URLMap<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);//保存移动拉流urllive.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;//直播主键IDprivate Integer userId;//管理员idprivate 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进行实现的,实时统计在线人数。
----------------------------------------华丽的分割---------------------------------------
分享基本就到此结束了,第一次做文章,在格式上和美观上都有很多欠缺。内容应该些的也不是很详细,如果我哪里些的不是很明白的可以私聊或者在评论中讨论。
如果文章对你有 一丁点的帮助,哪怕一点点,请给个
课程设计-基于SSM的在线课程教学系统代码-基于java的线上课程资源共享论坛系统 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架:SSM 前端框架 ... 基于ssm整合的网上书城 采用当前最流行的框架Spring-SpringMVC-MyBatis设计,分为前后台,前台用户可以购买书籍,后台管理员可以对书籍进行分类,增删改查 注意:本系统不支持jdk1 ... 1 简介 今天向大家介绍一个帮助往届学生完成的毕业设计项目,计算机毕业设计之基于ssm的大学生志愿者服务平台. 计算机毕业生设计,课程设计需要帮助的可以找我 2 设计概要 21世纪是信息化时代,随着信 ... 基于SSM的学生会管理系统-基于ssm的社团信息管理系统-java项目 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 1.开发环境 开发语言:Java 后台框架:SSM 前端技术:HTML+ ... 基于SSM整合的驾照在线考试系统 项目描述 主要功能有: 1.用户功能模块 用户注册登 用户可以通过用户名邮箱注册网站,并且通过注册的用户登陆网站. 2.随机练习 从题库中随机取出指定数量的题目供学员 ... [Activity学习五]--基于SSM整合Activiti之请假流程实现(二) 1.部署流程资源 2.查询流程定义信息 3.发布请假流程 4.查询用户任务 5.提出请假 6.老板查看请假任务 7.老 ... 项目介绍 能够为学生尽可能全面的了解教师的基本情况,找到自己心中认为最合适的教师来指导自己学习,教师也可以知道自己的辅导的学生,为了更能够完善自己,了解家教教师,学生的特点,我们开发了这个家教信息管理 ... 能够为学生尽可能全面的了解教师的基本情况,找到自己心中认为最合适的教师来指导自己学习,教师也可以知道自己的辅导的学生,为了更能够完善自己,了解家教教师,学生的特点,我们开发了这个家教信息管理系统.系统 ... 能够为学生尽可能全面的了解教师的基本情况,找到自己心中认为最合适的教师来指导自己学习,教师也可以知道自己的辅导的学生,为了更能够完善自己,了解家教教师,学生的特点,我们开发了这个家教信息管理系统.系统 ... 目 录 摘要 1 1 绪论 1 1.1 研究背景与意义 1 1.2研究现状与趋势 1 1.3论文结构与章节安排 1 2 养老智慧服务平台系统分析 3 2.1 可行性分析 3 2.2 系统流程分析 ...基于SSM整合阿里直播服务----java代码实现相关推荐
最新文章
热门文章