java实现阿里云视频直播

准备工作

[官方地址](https://help.aliyun.com/document_detail/198676.html?spm=a2c4g.446769.0.0.1567af3cOvfx8d)
	具体要准备什么东西官方文档写的很清楚了,我就不写了

后端生成推流、播流地址

1.引入依赖

<!--阿里云直播-->
        <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>

2.配置相关参数

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{可以传个时间戳}
     */
    @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;
}

3.工具类,生成推流地址和拉流地址

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;
    }
}

创建一个接口成功推流和拉流地址

@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();
        }
    }

创建成功后我们就可以先使用obs进行直播,和vlc工具观看直播,确保直播功能是正常的

5.配置推流回调地址

获取推流地址后我们怎么才能知道用户开播,下播呢?当初我第一次做的时候也是查看了很多文档才搞明白这件事,其实很简单的。只需要我们在阿里云上配置一下回调地址就行了,是以http开头的。相信很多人不知道这个地址从哪来,因为如果配置的是我们本地的项目地址的话,公网肯定是访问不到的。那么怎么办呢?我的做法是先把自己项目部署到阿里云服务器,这样就可以通过公网访问我们项目的回调地址了。加入我项目中的地址是/live/pushcallback,阿里云公网地址是35.55.66.77,我们项目端口是8080,那么地址就是http://35.55.66.77:8080/live/pushcallback

java 做直播 使用java搭建直播平台_java 做直播


java 做直播 使用java搭建直播平台_开发语言_02


回调接口代码

/**
     * 推流地址回调接口 根据返回状态值进行业务处理
     */
    @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;
    }
}
这样,视频直播基本就完成了,给前端返回播流地址就行了,参考内容,
本文主要是原有内容推流回调这块做了一点点补充。