zoukankan      html  css  js  c++  java
  • 阿里云直播鉴权java代码示例

    段时间公司需要做直播服务,所以就研究了一下阿里云的直播,在直播里面,最重要的就是url的鉴权操作(验证推流或者拉流的有效性),在网上找了很多代码,都没有发现java的demo,所以就写篇播客记录一下,方便以后的使用和记忆,如果哪里有误,请指出改正。

    阿里云直播提供的是触发式的推流与播放,您无需提前创建资源,只要添加经过备案的推流域名和播流域名,并完成域名解析、鉴权等操作,即可根据地址拼接规则手动拼接,以快速获取对应的推流地址和播流地址。本文介绍未设置转码的直播活动的推流地址和播流地址的拼接方法。
    原文章地址:https://help.aliyun.com/document_detail/87396.html?spm=a2c4g.11174283.6.609.7eb3454eniwqXA
    这句话的意思就是用户无需提前创建资源,在有直播场景的时候,直接生成一个直播url并且通过鉴权就可以开始直播了(看直播也是类似的)。

    1,推拉流工具类:
    /**
    * 阿里云直播工具类
    */
    public class AliyunLiveUtil {

    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 aliyunLiveConfig
    * @return
    */
    public static String createPushUrl(Integer sourceId, LiveTypeEnum liveTypeEnum, AliyunLiveConfig aliyunLiveConfig) {

    // 推流域名
    String pushDomain = aliyunLiveConfig.getAliyunLivePushDomain();
    // 应用名称
    String appName = aliyunLiveConfig.getAliyunLiveAppName();
    // 流名称
    String streamName = StrUtil.format(aliyunLiveConfig.getAliyunLiveStreamName(), liveTypeEnum.getValue(), sourceId);
    // 推流签名key
    String pushIdentKey = aliyunLiveConfig.getAliyunLivePushIdentKey();
    // 签名url有效时间
    Integer identUrlValidTime = aliyunLiveConfig.getAliyunLiveIdentUrlValidTime();

    // 计算过期时间
    String timestamp = String.valueOf((System.currentTimeMillis() / 1000) + identUrlValidTime);

    // 组合推流域名前缀
    // rtmp://{pushDomain}/{appName}/{streamName}
    String rtmpUrl = StrUtil.format("rtmp://{}/{}/{}", pushDomain, appName, streamName);
    log.debug("推流域名前缀,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);
    log.debug("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.debug("最终鉴权过的推流域名=" + finallyPushUrl);

    return finallyPushUrl;
    }

    /**
    * 创建拉流域名,key=rtmpUrl、flvUrl、m3u8Url,代表三种拉流类型域名
    *
    * @param sourceId
    * @param aliyunLiveConfig
    * @return
    */
    public static Map<String, String> createPullUrl(Integer sourceId, LiveTypeEnum liveTypeEnum, AliyunLiveConfig aliyunLiveConfig) {

    // 拉流域名
    String pullDomain = aliyunLiveConfig.getAliyunLivePullDomain();
    // 应用名称
    String appName = aliyunLiveConfig.getAliyunLiveAppName();
    // 流名称
    String streamName = StrUtil.format(aliyunLiveConfig.getAliyunLiveStreamName(), liveTypeEnum.getValue(), sourceId);
    // 拉流签名key
    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);
    log.debug("组合通用域名,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.debug("md5加密串,md5Url =" + md5Url + " ------ md5加密结果,md5Str=" + md5Str);
    log.debug("md5加密串,md5FlvUrl =" + md5FlvUrl + " ------ md5加密结果,md5FlvStr=" + md5FlvStr);
    log.debug("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.debug("最终鉴权过的拉流rtmp域名=" + rtmpUrl);
    log.debug("最终鉴权过的拉流flv域名 =" + flvUrl);
    log.debug("最终鉴权过的拉流m3u8域名=" + m3u8Url);

    HashMap<String, String> urlMap = new HashMap<>();
    urlMap.put("rtmpUrl", rtmpUrl);
    urlMap.put("flvUrl", flvUrl);
    urlMap.put("m3u8Url", m3u8Url);

    return urlMap;
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    2,阿里云直播配置参数:
    /**
    * 阿里云直播配置参数
    */
    @Component
    @Data
    public class AliyunLiveConfig {

    /**
    * 推流域名
    */
    @Value("${aliyun.live.push.domain}")
    private String aliyunLivePushDomain;

    /**
    * 拉流域名
    */
    @Value("${aliyun.live.pull.domain}")
    private String aliyunLivePullDomain;

    /**
    * 直播测试appName
    */
    @Value("${aliyun.live.appName}")
    private String aliyunLiveAppName;

    /**
    * 直播测试streamName{直播类型}_{类型id}
    */
    @Value("${aliyun.live.streamName}")
    private String aliyunLiveStreamName;

    /**
    * 推流鉴权url key
    */
    @Value("${aliyun.live.push.ident.key}")
    private String aliyunLivePushIdentKey;

    /**
    * 拉流鉴权url key
    */
    @Value("${aliyun.live.pull.ident.key}")
    private String aliyunLivePullIdentKey;

    /**
    * 鉴权url的有效时间(秒),默认30分钟,1800秒 key
    */
    @Value("${aliyun.live.ident.url.validTime}")
    private Integer aliyunLiveIdentUrlValidTime;

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    3,直播类型:
    /**
    * 直播类型
    */
    @ApiModel(description = "直播类型")
    public enum LiveTypeEnum {

    course("course", "课程");

    LiveTypeEnum(String value, String text) {
    this.value = value;
    this.text = text;
    }

    private String value;
    private String text;

    public String getText() {
    return text;
    }

    public void setText(String text) {
    this.text = text;
    }

    public String getValue() {
    return value;
    }

    public void setValue(String value) {
    this.value = value;
    }

    /**
    * 根据value获取text
    *
    * @param value
    * @return
    */
    public static String getTextByValue(String value) {
    LiveTypeEnum[] dictTypeEnums = LiveTypeEnum.values();
    for (LiveTypeEnum dictTypeEnum : dictTypeEnums) {
    if (dictTypeEnum.getValue().equals(value)) {
    return dictTypeEnum.getText();
    }

    }
    return "";
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    4,application.properties 参数配置:
    #阿里云直播配置 begin
    #推流域名
    aliyun.live.push.domain=www.xxx.xxx.com
    #推流鉴权url key
    aliyun.live.push.ident.key=xxx
    #拉流域名
    aliyun.live.pull.domain=www.xxx.xxx.com
    #拉流鉴权url key
    aliyun.live.pull.ident.key=xxx
    #直播测试appName
    aliyun.live.appName=ttest
    #直播测试streamName{直播类型}{类型id}
    aliyun.live.streamName={}{}
    #鉴权url的有效时间(秒),默认30分钟,1800秒
    aliyun.live.ident.url.validTime=1800
    #阿里云直播配置 end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    5,里面工具类的pom地址,不需要也可以自己写
    <!-- Hutool工具包 -->
    <dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>4.0.12</version>
    </dependency>
    1
    2
    3
    4
    5
    6
    工具类使用api官网:http://hutool.mydoc.io/undefined

    6,发起请求的结果:

  • 相关阅读:
    【洛谷P2921】[USACO08DEC]在农场万圣节Trick or Treat on the Farm
    【洛谷P3659】[USACO17FEB]Why Did the Cow Cross the Road I G
    【洛谷P3385】【模板】负环
    Typora+PicGo+Gitee实现图片上传功能
    Java substring() 方法
    Java lastIndexOf的用法
    Tomcat控制台乱码处理解决方法
    HTTP 协议中 URI 和 URL 有什么区别?
    java如何判断某一变量属于什么类型
    Idea发布web项目显示“找不到应用程序”的解决方法
  • 原文地址:https://www.cnblogs.com/ly570/p/10942283.html
Copyright © 2011-2022 走看看