通过java代码生成阿里云直播推流和播流地址 rtmpm3u8flvAliyun Live
程序员文章站
2024-01-30 12:41:16
...
1、阿里云推流和播流地址生成逻辑
1> 通过 req_auth 请求对象。http://cdn.example.com/video/standard/1K.html
2> 密钥设为:aliyuncdnexp1234(由用户自行设置)。
3> 鉴权配置文件失效日期为:2015年10月10日00:00:00,计算出来的秒数为 1444435200。
4> 服务器会构造一个用于计算 Hashvalue 的签名字符串。/video/standard/1K.html-1444435200-0-0-aliyuncdnexp1234
5> 服务器会根据该签名字符串计算 HashValue。HashValue = md5sum("/video/standard/1K.html-1444435200-0-0-aliyuncdnexp1234") = 80cd3862d699b7118eed99103f2a3a4f
6> 请求时 URL 为 http://cdn.example.com/video/standard/1K.html?auth_key=1444435200-0-0-80cd3862d699b7118eed99103f2a3a4f
8> 计算出来的 HashValue 与用户请求中带的 md5hash = 80cd3862d699b7118eed99103f2a3a4f 值一致,于是鉴权通过。
2、Java代码示例如下:
1> AliyunLiveUtil.java
2> 配置信息,AliyunLiveConfigInfo.java
3> maven配置文件片段
4> application.yml配置文件片段
1> 通过 req_auth 请求对象。http://cdn.example.com/video/standard/1K.html
2> 密钥设为:aliyuncdnexp1234(由用户自行设置)。
3> 鉴权配置文件失效日期为:2015年10月10日00:00:00,计算出来的秒数为 1444435200。
4> 服务器会构造一个用于计算 Hashvalue 的签名字符串。/video/standard/1K.html-1444435200-0-0-aliyuncdnexp1234
5> 服务器会根据该签名字符串计算 HashValue。HashValue = md5sum("/video/standard/1K.html-1444435200-0-0-aliyuncdnexp1234") = 80cd3862d699b7118eed99103f2a3a4f
6> 请求时 URL 为 http://cdn.example.com/video/standard/1K.html?auth_key=1444435200-0-0-80cd3862d699b7118eed99103f2a3a4f
8> 计算出来的 HashValue 与用户请求中带的 md5hash = 80cd3862d699b7118eed99103f2a3a4f 值一致,于是鉴权通过。
2、Java代码示例如下:
1> AliyunLiveUtil.java
package com.cnd.iov.utils; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.DigestUtil; /** * 阿里云直播工具类 */ public class AliyunLiveUtil { private static Logger logger = 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 */ /** * 根据配置信息生成推流地址,一般appName相同,streamName不同 * 此处将streamName作为独立参数传入 * * @param paramStreamName * @param configInfo * @return String */ public static String createPushUrl(AliyunLiveConfigInfo configInfo, String paramStreamName) { // 推流域名 String pushDomain = configInfo.getPushStreamDomain(); // 应用名称 String appName = configInfo.getAppName(); // 流名称 String streamName = paramStreamName; // 推流签名key String pushIdentKey = configInfo.getAuthKey(); // 签名url有效时间 Integer identUrlValidTime = configInfo.getValidTime(); // 计算过期时间 String timestamp = String.valueOf((System.currentTimeMillis() / 1000) + identUrlValidTime); // 组合推流域名前缀 // rtmp://{pushDomain}/{appName}/{streamName} String rtmpUrl = StrUtil.format("rtmp://{}/{}/{}", pushDomain, appName, streamName); logger.info("推流域名前缀,rtmpUrl=" + rtmpUrl); // 组合md5加密串 // /{appName}/{streamName}-{timestamp}-0-0-{pushIdentKey} String md5Url = StrUtil.format("/{}/{}-{}-0-0-{}", appName, streamName, timestamp, pushIdentKey); // md5加密 String md5Str = DigestUtil.md5Hex(md5Url); logger.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); logger.info("最终鉴权过的推流域名=" + finallyPushUrl); return finallyPushUrl; } /** * 根据配置信息生成创建播流(拉流)地址,key=rtmpUrl、flvUrl、m3u8Url,代表三种播流方式 * * @param configInfo * @param paramStreamName * @return */ public static Map<String, String> createPlayUrl(AliyunLiveConfigInfo configInfo, String paramStreamName) { // 播流域名 String pullDomain = configInfo.getPlayStreamDomin(); // 应用名称 String appName = configInfo.getAppName(); // 流名称 String streamName = paramStreamName; // 拉流签名key String pullIdentKey = configInfo.getAuthKey(); // 签名url有效时间 Integer identUrlValidTime = configInfo.getValidTime(); // 计算过期时间 String timestamp = String.valueOf((System.currentTimeMillis() / 1000) + identUrlValidTime); // 组合通用域名 // {pullDomain}/{appName}/{streamName} String pullUrl = StrUtil.format("{}/{}/{}", pullDomain, appName, streamName); logger.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); logger.info("md5加密串,md5Url =" + md5Url + " ------ md5加密结果,md5Str=" + md5Str); logger.info("md5加密串,md5FlvUrl =" + md5FlvUrl + " ------ md5加密结果,md5FlvStr=" + md5FlvStr); logger.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); logger.info("最终鉴权过的拉流rtmp域名=" + rtmpUrl); logger.info("最终鉴权过的拉流flv域名 =" + flvUrl); logger.info("最终鉴权过的拉流m3u8域名=" + m3u8Url); HashMap<String, String> urlMap = new HashMap<>(); urlMap.put("rtmpUrl", rtmpUrl); urlMap.put("flvUrl", flvUrl); urlMap.put("m3u8Url", m3u8Url); return urlMap; } }
2> 配置信息,AliyunLiveConfigInfo.java
package com.cnd.iov.utils; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "aliyunlive") public class AliyunLiveConfigInfo { String pushStreamDomain; String playStreamDomin; String appName; String streamNameInside; String streamNameOutside; String authKey; Integer validTime; public String getPushStreamDomain() { return pushStreamDomain; } public void setPushStreamDomain(String pushStreamDomain) { this.pushStreamDomain = pushStreamDomain; } public String getPlayStreamDomin() { return playStreamDomin; } public void setPlayStreamDomin(String playStreamDomin) { this.playStreamDomin = playStreamDomin; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getStreamNameInside() { return streamNameInside; } public void setStreamNameInside(String streamNameInside) { this.streamNameInside = streamNameInside; } public String getStreamNameOutside() { return streamNameOutside; } public void setStreamNameOutside(String streamNameOutside) { this.streamNameOutside = streamNameOutside; } public String getAuthKey() { return authKey; } public void setAuthKey(String authKey) { this.authKey = authKey; } public Integer getValidTime() { return validTime; } public void setValidTime(Integer validTime) { this.validTime = validTime; } }
3> maven配置文件片段
<!-- Hutool工具包 --> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>4.0.12</version> </dependency>
4> application.yml配置文件片段
aliyunlive: push-stream-domain: live.yourcompany.com play-stream-domin: liveplay.yourcompany.com app-name: yourAppNamexxyyzz stream-name-inside: yourStreaNameaabbcc stream-name-outside: yourStreamName112233 auth-key: yourpassword valid-time: 3600