腾讯云直播工具

直播工具类(生成流地址、云直播签名、云直播IM签名、云直播IM解散群组)

1.导入jar包

<!--直播IM获取签名-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>kisso</artifactId>
    <version>3.7.0</version>
</dependency>

2.工具类,仅供参考

package com.es.biz.common.utils;


import com.alibaba.fastjson.JSONObject;
import com.es.biz.modules.userlive.entity.LiveAddressEntity;
import net.sf.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.zip.Deflater;

/**
 * 直播工具类
 */
public class LiveUtils {
    private static Logger log = LoggerFactory.getLogger(LiveUtils.class);

    //--------------------------------------------------生成流地址(开始)--------------------------------

    private static final char[] DIGITS_LOWER =
            {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    private static final String pushKey = "xxxxxxxxx"; //域名管理中点击推流域名-->推流配置-->鉴权配置-->主KEY
    private static final String playKey = "xxxxxxxxx"; //域名管理中点击推流域名-->推流配置-->鉴权配置-->主KEY
    private static final String pushDomain = "xxxxxxxxx.com"; //云直播控制台配置的推流域名
    private static final String playDomain = "xxxxxxxxx.com";//云直播控制台配置的播放域名


    /**
     * 推流地址
     * @param appName
     * @param streamName
     * @return
     */
    public static LiveAddressEntity getAddressUrl(String appName, String streamName) {
        long txTime = getTxTime();
        String safeUrl = getSafeUrl(pushKey, streamName, txTime);

        LiveAddressEntity liveAddress = new LiveAddressEntity();
        liveAddress.setPushRtmpUrl("rtmp://" + pushDomain + "/" + appName + "/" + streamName + "?" + safeUrl);
        return liveAddress;
    }

    /**
     * 播放地址
     * @param appName
     * @param streamName
     * @return
     */
    public static LiveAddressEntity getPlayAddressUrl(String appName, String streamName) {
        long txTime = getTxTime();
        String safeUrl = getSafeUrl(playKey, streamName, txTime);

        LiveAddressEntity liveAddress = new LiveAddressEntity();
        liveAddress.setPlayRtmpUrl("rtmp://" + playDomain + "/" + appName + "/" + streamName + "?" + safeUrl);
        liveAddress.setFlvUrl("http://" + playDomain + "/" + appName + "/" + streamName + ".flv?" + safeUrl);
        liveAddress.setHlsUrl("http://" + playDomain + "/" + appName + "/" + streamName + ".m3u8?" + safeUrl);
        liveAddress.setUdpUrl("webrtc://" + playDomain + "/" + appName + "/" + streamName + "?" + safeUrl);
        return liveAddress;
    }

    /**
     * 过期时间戳
     * @return
     */
    private static long getTxTime() {
        LocalDateTime localDateTime = LocalDateTime.now();
        long nowTime = localDateTime.toEpochSecond(ZoneOffset.of("+8"));
        return nowTime + 60 * 60 * 24;
    }

    /*
     * KEY+ streamName + txTime
     */
    private static String getSafeUrl(String key, String streamName, long txTime) {
        String input = new StringBuilder().
                append(key).
                append(streamName).
                append(Long.toHexString(txTime).toUpperCase()).toString();

        String txSecret = null;
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            txSecret = byteArrayToHexString(
                    messageDigest.digest(input.getBytes("UTF-8")));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        return txSecret == null ? "" :
                new StringBuilder().
                        append("txSecret=").
                        append(txSecret).
                        append("&").
                        append("txTime=").
                        append(Long.toHexString(txTime).toUpperCase()).
                        toString();
    }

    private static String byteArrayToHexString(byte[] data) {
        char[] out = new char[data.length << 1];

        for (int i = 0, j = 0; i < data.length; i++) {
            out[j++] = DIGITS_LOWER[(0xF0 & data[i]) >>> 4];
            out[j++] = DIGITS_LOWER[0x0F & data[i]];
        }
        return new String(out);
    }

    //--------------------------------------------------生成流地址(结束)----------------------------------------


    //--------------------------------------------------云直播签名(开始)----------------------------------------

    private final static Charset UTF8 = StandardCharsets.UTF_8;
    private final static String SECRET_ID = "xxxxxxxxx";
    private final static String SECRET_KEY = "xxxxxxxxx";
    private final static String CT_JSON = "application/json; charset=utf-8";

    public static byte[] hmac256(byte[] key, String msg) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
        mac.init(secretKeySpec);
        return mac.doFinal(msg.getBytes(UTF8));
    }

    public static String sha256Hex(String s) throws Exception {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] d = md.digest(s.getBytes(UTF8));
        return DatatypeConverter.printHexBinary(d).toLowerCase();
    }

    /**
     * 获取云直播签名
     * @return
     * @throws Exception
     */
    public static String getUserSign() throws Exception {
        String service = "cvm";
        String host = "cvm.tencentcloudapi.com";
//        String region = "ap-guangzhou";
//        String action = "DescribeInstances";
//        String version = "2017-03-12";
        String algorithm = "TC3-HMAC-SHA256";
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 注意时区,否则容易出错
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        String date = sdf.format(new Date(Long.valueOf(timestamp + "000")));

        // ************* 步骤 1:拼接规范请求串 *************
        String httpRequestMethod = "POST";
        String canonicalUri = "/";
        String canonicalQueryString = "";
        String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n";
        String signedHeaders = "content-type;host";

        String payload = "{\"Limit\": 1, \"Filters\": [{\"Values\": [\"\\u672a\\u547d\\u540d\"], \"Name\": \"instance-name\"}]}";
        String hashedRequestPayload = sha256Hex(payload);
        String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
                + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
        System.out.println(canonicalRequest);

        // ************* 步骤 2:拼接待签名字符串 *************
        String credentialScope = date + "/" + service + "/" + "tc3_request";
        String hashedCanonicalRequest = sha256Hex(canonicalRequest);
        String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
        System.out.println(stringToSign);

        // ************* 步骤 3:计算签名 *************
        byte[] secretDate = hmac256(("TC3" + SECRET_KEY).getBytes(UTF8), date);
        byte[] secretService = hmac256(secretDate, service);
        byte[] secretSigning = hmac256(secretService, "tc3_request");
        String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
        System.out.println(signature);

        // ************* 步骤 4:拼接 Authorization *************
        String authorization = algorithm + " " + "Credential=" + SECRET_ID + "/" + credentialScope + ", "
                + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
        System.out.println(authorization);

        TreeMap<String, String> headers = new TreeMap<String, String>();
        headers.put("Authorization", authorization);
        headers.put("Content-Type", CT_JSON);
        headers.put("Host", host);
//        headers.put("X-TC-Action", action);
        headers.put("X-TC-Timestamp", timestamp);
//        headers.put("X-TC-Version", version);
//        headers.put("X-TC-Region", region);

        StringBuilder sb = new StringBuilder();
        sb.append("curl -X POST https://").append(host)
                .append(" -H \"Authorization: ").append(authorization).append("\"")
                .append(" -H \"Content-Type: application/json; charset=utf-8\"")
                .append(" -H \"Host: ").append(host).append("\"")
//                .append(" -H \"X-TC-Action: ").append(action).append("\"")
                .append(" -H \"X-TC-Timestamp: ").append(timestamp).append("\"");
//                .append(" -H \"X-TC-Version: ").append(version).append("\"")
//                .append(" -H \"X-TC-Region: ").append(region).append("\"")
//                .append(" -d '").append(payload).append("'");
        System.out.println(sb.toString());
        return sb.toString();
    }

    //--------------------------------------------------云直播签名(结束)--------------------------------

    //--------------------------------------------------云直播IM签名(开始)-----------------------------

    private final static Long sdkappid = xxxxxxxxxL;//腾讯云appid
    private final static String key = "xxxxxxxxx";//腾讯云私钥
    private final static long expire = 3600 * 24 * 180 ;// 签名有效时长 180天

    private static String hmacsha256(String identifier, long currTime, String base64Userbuf) {
        String contentToBeSigned = "TLS.identifier:" + identifier + "\n" + "TLS.sdkappid:" + sdkappid + "\n"
                + "TLS.time:" + currTime + "\n" + "TLS.expire:" + expire + "\n";
        if (null != base64Userbuf) {
            contentToBeSigned += "TLS.userbuf:" + base64Userbuf + "\n";
        }
        try {
            byte[] byteKey = key.getBytes("UTF-8");
            Mac hmac = Mac.getInstance("HmacSHA256");
            SecretKeySpec keySpec = new SecretKeySpec(byteKey, "HmacSHA256");
            hmac.init(keySpec);
            byte[] byteSig = hmac.doFinal(contentToBeSigned.getBytes("UTF-8"));
            return (new BASE64Encoder().encode(byteSig)).replaceAll("\\s*", "");
        } catch (UnsupportedEncodingException e) {
            return "";
        } catch (NoSuchAlgorithmException e) {
            return "";
        } catch (InvalidKeyException e) {
            return "";
        }
    }

    private static String genSig(String identifier, byte[] userbuf) {

        long currTime = System.currentTimeMillis() / 1000;

        JSONObject sigDoc = new JSONObject();
        sigDoc.put("TLS.ver", "2.0");
        sigDoc.put("TLS.identifier", identifier);
        sigDoc.put("TLS.sdkappid", sdkappid);
        sigDoc.put("TLS.expire", expire);
        sigDoc.put("TLS.time", currTime);

        String base64UserBuf = null;
        if (null != userbuf) {
            base64UserBuf = new BASE64Encoder().encode(userbuf);
            sigDoc.put("TLS.userbuf", base64UserBuf);
        }
        String sig = hmacsha256(identifier, currTime, base64UserBuf);
        if (sig.length() == 0) {
            return "";
        }
        sigDoc.put("TLS.sig", sig);
        Deflater compressor = new Deflater();
        compressor.setInput(sigDoc.toString().getBytes(Charset.forName("UTF-8")));
        compressor.finish();
        byte[] compressedBytes = new byte[2048];
        int compressedBytesLength = compressor.deflate(compressedBytes);
        compressor.end();
        return (new String(Base64Url.base64EncodeUrl(Arrays.copyOfRange(compressedBytes, 0, compressedBytesLength)))).replaceAll("\\s*", "");
    }

    public static String genSig(String identifier) {
        return genSig(identifier, null);
    }

    public static String genSigWithUserBuf(String identifier, byte[] userbuf) {
        return genSig(identifier, userbuf);
    }

    //--------------------------------------------------云直播IM签名(结束)----------------------------

    //--------------------------------------------------云直播IM解散群组(开始)----------------------

    private final static String destroyGroupUrl = "https://console.tim.qq.com/v4/group_open_http_svc/destroy_group?sdkappid=SDKAPPID&identifier=IDENTIFIER&usersig=USERSIG&random=RANDOM&contenttype=json";

    private final static String identifier = "admin";

    public static void main(String[] args) {
        destroyGroup("9459064");
    }
    /**
     * 解散群组
     * @param groupId IM群组id
     */
    public static String destroyGroup(String groupId){
        String userSig = genSig(identifier);

        //获取32位随机数字
        StringBuilder stringBuilder = new StringBuilder();
        String ran = String.valueOf(new Random().nextInt(899999999) + 10000000);
        String rand = String.valueOf(new Random().nextInt(899999999) + 10000000);
        String rando = String.valueOf(new Random().nextInt(899999999) + 10000000);
        String random = String.valueOf(new Random().nextInt(899999999) + 10000000);
        stringBuilder.append(ran).append(rand).append(rando).append(random);


        String requestUrl = destroyGroupUrl.replace("SDKAPPID", sdkappid.toString()).replace("IDENTIFIER", identifier)
                .replace("USERSIG", userSig).replace("RANDOM", stringBuilder);

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("GroupId", groupId);
        String s = "";
        try {
            s = HttpClientUtil.postParameters(requestUrl, jsonObject.toJSONString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(s);
        return s;
    }

    //--------------------------------------------------云直播IM解散群组(结束)--------------------------
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值