腾讯云直播-开启互动直播

项目背景:基于腾讯云直播开发项目,直播交友平台1+6模式

ps : 记录自己的日常 

一、申请腾讯视频权限(官方链接)

首先在流管理添加一个域名 类型为播放域名域名地址为 推流域名的域名前缀+你的域名生成的而已域名或者三级域名

然后点击你保存的播放域名查看详情

然后去自己的购买的网站域名中心进行解析域名解析的域名为你保存的域名地址

类型为CNAME,填写的是在腾讯播放域名的详情里的CNAME

为了信息数据安全我在流管理的播放流加入了HTTS的证书

二、在云直播的直播sdk列表中找到License,申请测试license添加ios/安卓的包名和随机的appname

然后拿着key 、lincenseURL交给ios和安卓开发人员

三、开通即时通讯IM 拿着 appskID 和秘钥 处理业务(注册)

 

package com.skyonez.core.util;

import java.io.IOException;

import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import com.skyonez.core.constant.Parameter;
import com.skyonez.core.entity.User;
import com.tencentyun.TLSSigAPIv2;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class TencentIMUtils {

	public static final long SDK_APP_ID =  你的sdkappid;

	public static final String KEY = "你的秘钥";

	/**
	 * 账号注册
	 * 
	 * @param user 用户对象
	 * @return 响应
	 */
	public static JSONObject create(User user) {
		// 请求地址
		String url = "https://console.tim.qq.com/v4/im_open_login_svc/account_import";
		// 封装请求参数
		JSONObject param = new JSONObject();
		param.put("Identifier", String.valueOf(user.getId()));
		param.put("Nick", user.getUsername());
		param.put("FaceUrl", Parameter.OSS_BUCKET + "/" + user.getHeadPortrait());
		param.put("Type", 0);
		return post(url, param);
	}

	/**
	 * 添加好友
	 * 
	 * @param user
	 * @return
	 */
	public static JSONObject addFriend(Integer id, Integer toId) {
		// 请求地址
		String url = "https://console.tim.qq.com/v4/sns/friend_add";
		// 封装请求参数
		JSONObject param = new JSONObject();
		param.put("From_Account", String.valueOf(id));
		JSONArray array = new JSONArray();
		JSONObject friend = new JSONObject();
		friend.put("To_Account", String.valueOf(toId));
		friend.put("AddSource", "AddSource_Type_Android");
		array.add(friend);
		param.put("AddFriendItem", array);
		param.put("AddType", "Add_Type_Single");
		param.put("ForceAddFlags", 1);
		return post(url, param);
	}

	/**
	 * 删除好友
	 * 
	 * @param user
	 * @return
	 */
	public static JSONObject deleteFriend(Integer id, Integer toId) {
		// 请求地址
		String url = "https://console.tim.qq.com/v4/sns/friend_delete";
		// 封装请求参数
		JSONObject param = new JSONObject();
		param.put("From_Account", String.valueOf(id));
		JSONArray array = new JSONArray();
		array.add(String.valueOf(toId));
		param.put("To_Account", array);
		param.put("DeleteType", "Delete_Type_Both");
		return post(url, param);
	}

	/**
	 * 通过用户id获取sig
	 * 
	 * @param id 用户id
	 * @return sig
	 */
	public static String genSig(Integer id) {
		TLSSigAPIv2 api = new TLSSigAPIv2(SDK_APP_ID, KEY);
		return api.genSig(String.valueOf(id), 180 * 86400).replaceAll("(\\r\\n|\\n|\\n\\r)", "");
	}

	/**
	 * 通用请求
	 * 
	 * @param url   请求地址
	 * @param param 参数
	 * @return 响应
	 */
	private static JSONObject post(String url, JSONObject param) {
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(SDK_APP_ID, KEY);
		// 获取签名
		String usersig = api.genSig("admin", 1800).replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		HttpPost httpPost = new HttpPost(url + "?sdkappid=" + SDK_APP_ID + "&identifier=admin&usersig=" + usersig
				+ "&random=" + StringUtils.randomUUID() + "&contenttype=json");
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 设置请求的参数
		StringEntity params = (new StringEntity(param.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			return JSONObject.fromObject(EntityUtils.toString(response.getEntity(), "utf-8"));
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 拉黑好友
	 * 
	 * @param user
	 * @return
	 */
	public static JSONObject addBlack(Integer id, Integer toId) {
		// 请求地址
		String url = "https://console.tim.qq.com/v4/sns/black_list_add";
		// 封装请求参数
		JSONObject param = new JSONObject();
		param.put("From_Account", String.valueOf(id));
		JSONArray array = new JSONArray();
		array.add( String.valueOf(toId) );
		param.put("To_Account", array);
		
		return post(url, param);
	}

	/**
	 * 取消拉黑好友
	 * 
	 * @param user
	 * @return
	 */
	public static JSONObject deleteBlack(Integer id, Integer toId) {
		// 请求地址
		String url = "https://console.tim.qq.com/v4/sns/black_list_delete";
		// 封装请求参数
		JSONObject param = new JSONObject();
		param.put("From_Account", String.valueOf(id));
		JSONArray array = new JSONArray();
		array.add( String.valueOf(toId) );
		param.put("To_Account", array);
		return post(url, param);
	}

}

 

四、生成推拉流地址

package com.skyonez.core.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * 腾讯推流、拉流工具
 * 
 * @author lnexin@aliyun.com
 */
public class TecentCloudUtils {


    // 这就是个日志,不需要的删掉就行了
    private static final Logger logger = LoggerFactory.getLogger(TecentCloudUtils.class);

    // 用于 生成推流防盗链的key
    public static final String key = "推拉流放到key" ;

 
    public static final String bizid = "你的推流地址上前缀*****.livepush.myqcloud.com 的*****";

    public static final String APPID = "点击你的头像查看你的信息里的APPid";
 
    // 用于主动查询和被动通知的key:API鉴定key
    public static final String API_KEY = "api鉴权key";

    // API回调地址
    public static final String API_ADDRESS = "http://fcgi.video.qcloud.com/common_access";

    /**
     * 推流地址
     */
    public static final String PUSH_URL = "rtmp://" + bizid + ".livepush.myqcloud.com/live/";

    /**
     * PC拉流地址
     */
//    public static final String PULL_RTMP_URL = "rtmp://" + bizid + ".名/live/"+ bizid + "_";
    public static final String PULL_RTMP_URL = "rtmp://" + bizid + ".域名/live/";
//    public static final String PULL_RTMP_URL = "rtmp://" + bizid + ".域名/live/";
    /**
     * app拉流地址
     */
    //  https://59744.liveplay.myqcloud.com/live/1003634281.flv
    public static final String PULL_URL = "https://"+ bizid +".play.unclexin.com/live/";
//    public static final String PULL_URL = "https://"+ bizid +".liveplay.myqcloud.com/live/";
  

    /**
     * 这是推流防盗链的生成 KEY+ streamId + txTime
     * 
     * @param key
     *            防盗链使用的key
     * @param streamId
     *            通常为直播码.示例:bizid+房间id
     * @param txTime
     *            到期时间
     * @return
     * @author lnexin@aliyun.com
     */
    public static String getSafeUrl(String key, String streamId, long txTime) {
        String input = new StringBuilder().
                append(key).
                append(streamId).
                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 final char[] DIGITS_LOWER =
            {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};


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

    /**
     * 推流地址生成
     */
    public static String getPushUrl(String roomId,Long txTime) {

        String safeUrl = getSafeUrl(key, roomId, txTime);

        String realPushUrl = PUSH_URL + roomId + "?"+ safeUrl;

        return realPushUrl;
    }

    /**
     * APP拉流地址获得
     */
    public static String getPullUrl(String owenrId,Long txTime) {
        String safeUrl = getSafeUrl(key, owenrId, txTime);
//        String appPullUrl = PULL_URL + owenrId + ".flv"+ "?"+ safeUrl;
        String appPullUrl = PULL_URL + owenrId + ".flv"+ "?"+ safeUrl+"&bizid"+bizid ;
//        String appPullUrl = PULL_URL + owenrId + ".flv";
        return appPullUrl;
    }

    /**
     * PC拉流地址获得
     */
    public static String getPullRtmpUrl(String owenrId,Long txTime) {
        String safeUrl = getSafeUrl(key, owenrId, txTime);
//        String pullRtmpUrl = PULL_RTMP_URL + owenrId;
//       String pullRtmpUrl = PULL_RTMP_URL + owenrId+ "?"+ safeUrl ;
       String pullRtmpUrl = PULL_RTMP_URL + owenrId+ "?"+ safeUrl+"&bizid"+bizid ;
        return pullRtmpUrl;
    }
    /**
     * APP拉流地址获得
     */
    public static String getHlsPullUrl(String owenrId,Long txTime) {
        String safeUrl = getSafeUrl(key, owenrId, txTime);
//        String appPullUrl = PULL_URL + owenrId + ".flv"+ "?"+ safeUrl;
        String appPullUrl = PULL_URL + owenrId + ".m3u8"+ "?"+ safeUrl+"&bizid"+bizid ;
//        String appPullUrl = PULL_URL + owenrId + ".flv";
        return appPullUrl;
    }
 
    
//
//    /**
//     * 获取关闭直播的url关闭直播 需要发送请求给腾讯服务器,然后返回结果
//     *
//     * @param id
//     *            需要关闭的房间ID
//     * @return 关闭直播的url
//     * @author lnexin@aliyun.com
//     * @date 2017年7月22日 下午2:54:14
//     */
//    public static String getCloseLiveUrl(String id) {
//        // 此请求的有效时间
//        Long current = System.currentTimeMillis() / 1000 + 10;
//        // 生成sign签名
//        String sign = MD5Encode.stringToMD5(new StringBuffer().append(API_KEY).append(current).toString());
//        // 生成需要关闭的直播码
//        String code = bizid + "_" + id;
//        // 生成关闭的参数列表
//        String params = new StringBuffer().append("&interface=Live_Channel_SetStatus").append("&Param.s.channel_id=").append(code).append("&Param.n.status=0").append("&t=").append(current).append("&sign=").append(sign).toString();
//
//        // 拼接关闭URL
//        String url = API_ADDRESS + "?appid=" + APPID + params;
//        return url;
//    }
//
 
 
    public static void main(String[] args) {
//    	https://59744.liveplay.myqcloud.com/live/1003634281.flv
//    	https://59744.liveplay.myqcloud.com/live/1003634281.fl
        // 腾讯云获取推流地址、拉流地址
        Long now = System.currentTimeMillis() + 60L * 60L * 24L * 30L * 1000L;// 要转成long类型,不然为负数
        // 当前毫秒数+需要加上的时间毫秒数 = 过期时间毫秒数
        Long txTime = now / 1000;// 推流码过期时间秒数
        String pushUrl = TecentCloudUtils.getPushUrl("1003634281",txTime);
        String pullUrl = TecentCloudUtils.getPullUrl("1003634281",txTime);
        String pullRtmpUrl = TecentCloudUtils.getPullRtmpUrl("1003634281",txTime);
        System.out.println(pushUrl);
        System.out.println(pullUrl);
        System.out.println(pullRtmpUrl);
	}
    
    /**
     * 这是推流防盗链的生成 KEY+ streamId + txTime
     * 
     * @param key
     *            防盗链使用的key
     * @param streamId
     *            通常为直播码.示例:bizid+房间id
     * @param txTime
     *            到期时间
     * @return
     * @author lnexin@aliyun.com
     */
    public static String md5( long txTime) {
        String input = new StringBuilder().
                append(key).
                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 ? "" :txSecret.toString() ;
    }
    
    
}

五、腾讯接口封装

package com.skyonez.core.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.skyonez.core.entity.Live;
import com.skyonez.core.pojo.Account;
import com.skyonez.core.pojo.Crowd;
import com.tencentyun.TLSSigAPIv2;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.*;

/**
 * @description: 腾讯im 接口
 * @author: liangyong
 * @time: 2019/8/24 0024 下午 15:30
 */

public class TencentApi {

	/**
	 * 单个帐号导入接口
	 *
	 * @param Identifier 用户id
	 * @param Nick       用户名
	 * @param FaceUrl    头像
	 * @param Type       默认 0 :普通用户 1:为机器人
	 */
	public Account insert(String Identifier, String Nick, String FaceUrl, Integer Type) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.ACCOUNT_IMPORT + "?sdkappid=" + AccessToken.SDK_APP_ID + "&identifier=admin&usersig="
				+ result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = new JSONObject();
		// 聊天室id
		postData.put("Identifier", Identifier);
		postData.put("Nick", Nick);
		postData.put("Type", Type);
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return account;
		} catch (IOException e) {
			e.printStackTrace();
			return account;
		}

	}

	/**
	 * 帐号删除接口
	 *
	 * @param ids 用户ids 集合
	 * @return
	 */
	public Account drop(List<String> ids) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		java.lang.String url = AccessToken.ACCOUNT_DELETE + "?sdkappid=" + AccessToken.SDK_APP_ID
				+ "&identifier=admin&usersig=" + result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = new JSONObject();
		List<Map<String, Object>> list = new ArrayList<>(2);
		Map<java.lang.String, String> map = new HashMap<>();
		for (int i = 0; i < ids.size(); i++) {
			map.put("UserID", ids.get(i));
		}
		// 聊天室id
		postData.put("DeleteItem", list);
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return account;
		} catch (IOException e) {
			e.printStackTrace();
			return account;
		}

	}

	/**
	 * 帐号删除接口
	 *
	 * @param message 消息
	 * @return
	 */
	public Account drop(Message message) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.ACCOUNT_DELETE + "?sdkappid=" + AccessToken.SDK_APP_ID + "&identifier=admin&usersig="
				+ result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = JSONObject.parseObject(message.toString());
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return account;
		} catch (IOException e) {
			e.printStackTrace();
			return account;
		}

	}

	/**
	 * 帐号删除接口
	 *
	 * @param message 消息
	 * @return
	 */
	public Account sendMessage(Message message) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.OPENIM_SENDMSG + "?sdkappid=" + AccessToken.SDK_APP_ID + "&identifier=admin&usersig="
				+ result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = JSONObject.parseObject(message.toString());
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return account;
		} catch (IOException e) {
			e.printStackTrace();
			return account;
		}

	}

	/**
	 * 帐号删除接口
	 *
	 * @param ToAccount 用户ids
	 * @return
	 */
	public Account queryState(JSONObject ToAccount) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.OPENIM_QUERYSTATE + "?sdkappid=" + AccessToken.SDK_APP_ID
				+ "&identifier=admin&usersig=" + result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = JSONObject.parseObject(ToAccount.toString());
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return account;
		} catch (IOException e) {
			e.printStackTrace();
			return account;
		}

	}

	/**
	 * 设置用户信息
	 *
	 * @param FromAccount
	 * @param list
	 * @return
	 */
	public Account portrait_set(String FromAccount, List<Map<String, Object>> list) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.PORTRAIT_SET + "?sdkappid=" + AccessToken.SDK_APP_ID + "&identifier=admin&usersig="
				+ result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = new JSONObject();
		postData.put("From_Account", FromAccount);
		postData.put("ProfileItem", list);
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return account;
		} catch (IOException e) {
			e.printStackTrace();
			return account;
		}

	}

	/**
	 * 获取
	 *
	 * @param FromAccount
	 * @param list
	 * @return existJsonObject
	 */
	public JSONObject portrait_get(String FromAccount, List<Map<String, Object>> list) {

		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.PORTRAIT_GET + "?sdkappid=" + AccessToken.SDK_APP_ID + "&identifier=admin&usersig="
				+ result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = new JSONObject();
		postData.put("From_Account", FromAccount);
		postData.put("ProfileItem", list);
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));

			return existJsonObject;
		} catch (ClientProtocolException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();

		}
		return null;
	}

	/**
	 * 创建群组
	 *
	 * @param crowd 群组实体类
	 * @return
	 */
	public Account createGroup(Crowd crowd, String liveNumber) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.CREATE_GROUP + "?sdkappid=" + AccessToken.SDK_APP_ID + "&identifier=admin&usersig="
				+ result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = new JSONObject();
		// 群主的 UserId(选填)
		postData.put("Owner_Account", crowd.getOwnerAccount());
		// 群组类型:Private/Public/ChatRoom/AVChatRoom/BChatRoom(必填)
		postData.put("Type", crowd.getType());
		// 群名称(必填)
		postData.put("Name", crowd.getName());
		// 群组自定义id
		postData.put("GroupId", "XDS" + liveNumber);
		// 群简介(选填)
		postData.put("Introduction", crowd.getIntroduction());
		// 群公告(选填)
		postData.put("Notification", crowd.getNotification());
//        // 群头像 URL(选填)
//        postData.put("FaceUrl",list);
//        // 最大群成员数量(选填)
//        postData.put("MaxMemberCount",list);
//        // 申请加群处理方式(选填)申请加群处理方式。包含 FreeAccess(自由加入),NeedPermission(需要验证),DisableApply(禁止加群),不填默认为 NeedPermission(需要验证)
		postData.put("ApplyJoinOption", "FreeAccess");
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 解散
	 *
	 * @param crowd 群组实体类
	 * @return
	 */
	public Account DESTORY_GROUP(String liveNumber) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.DESTORY_GROUP + "?sdkappid=" + AccessToken.SDK_APP_ID + "&identifier=admin&usersig="
				+ result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = new JSONObject();
		// 群组自定义id
		postData.put("GroupId", "XDS" + liveNumber);
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public Account createGroup(Message message) {
		Account account = new Account();
		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.SEND_GROUP_MSG + "?sdkappid=" + AccessToken.SDK_APP_ID + "&identifier=admin&usersig="
				+ result + "&random=" + RandomUtil.getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = new JSONObject();
		JSONObject jsonObject2 = new JSONObject();
		jsonObject2.put("Text", "123456789");
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("MsgType", "TIMTextElem");
		jsonObject.put("MsgContent", jsonObject2);
		JSONArray jsonArray = new JSONArray();
		jsonArray.add(jsonObject);
		postData.put("GroupId", "");
		// 群组类型:Private/Public/ChatRoom/AVChatRoom/BChatRoom(必填)
		postData.put("From_Account", "10031");
		// 群名称(必填)
		postData.put("Random", "123456879");
		postData.put("MsgBody", jsonArray);
		// 打印参数
		System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			account = existJsonObject.toJavaObject(Account.class);
			System.out.println(account.toString());
			return account;
		} catch (ClientProtocolException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();

		}
		return null;
	}

	/**
	 * 混流
	 *
	 * @return
	 */
	public JSONObject common(JSONObject jsonObject) {
		Long now = System.currentTimeMillis() + 60L * 60L * 24L * 30L * 1000L;// 要转成long类型,不然为负数
		// 当前毫秒数+需要加上的时间毫秒数 = 过期时间毫秒数
		Long txTime = now / 1000;// 推流码过期时间秒数
		// 正式
		String key = AccessToken.API_KEY + txTime;
		String result = MD5Utils.MD5(key);
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.COMMON_ACCESS + "?appid=" + AccessToken.APP_ID + "&interface=Mix_StreamV2&t=" + txTime
				+ "&sign=" + result;

		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 封装请求参数
		JSONObject postData = new JSONObject();
		postData.put("timestamp", txTime);
		// 群组类型:Private/Public/ChatRoom/AVChatRoom/BChatRoom(必填)
		postData.put("eventId", txTime);
		// 群名称(必填)
		postData.put("interface", jsonObject);
		// 打印参数
//        System.out.println(new StringEntity(postData.toString(), Consts.UTF_8));
		// 设置请求的参数
		StringEntity params = (new StringEntity(postData.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
//            System.out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			return existJsonObject;

		} catch (ClientProtocolException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();

		}
		return null;
	}

	/**
	 * 
	 * @Title: dropStream
	 * @Description: 移除混流
	 * @param liveNumber
	 * @return JSONObject
	 * @author liangyong
	 * @date 2019年10月16日下午3:55:35
	 */
	public JSONObject dropStream(String liveNumber) {
		JSONObject jsonObject = new JSONObject();
		JSONObject para = new JSONObject();
		para.put("app_id", AccessToken.APP_ID);
		para.put("interface", "mix_streamv2.cancel_mix_stream");
		para.put("mix_stream_session_id", liveNumber);
		para.put("output_stream_id", liveNumber);
		jsonObject.put("interfaceName", "Mix_StreamV2");
		jsonObject.put("para", para);
		common(jsonObject);
		return jsonObject;
	}

	/**
	 * 画布
	 * 
	 * @param idsList
	 * @param live
	 * @return
	 */
	public JSONObject anchorStart(List<Object> idsList, Live live, Integer max) {
		// para 参数
		JSONObject para = new JSONObject();
		// 固定值mix_streamv2.start_mix_stream_advanced
		para.put("interface", "mix_streamv2.start_mix_stream_advanced");
		para.put("app_id", AccessToken.APP_ID);
		para.put("mix_stream_template_id", 0);
		// list
		JSONArray list = new JSONArray();

		for (int i = 0; i < idsList.size(); i++) {
			// input_stream_list

//			Map<String, Object> map = new HashMap<>();
			JSONObject input_stream_list = new JSONObject();
			if (i == 0) {
				para.put("mix_stream_session_id", live.getLiveNumber());
				para.put("output_stream_id", live.getLiveNumber());
				para.put("output_stream_type", 1);
				// 画布
				// layout_params
				JSONObject layoutParams = new JSONObject();
				// 1)背景流(即大主播画面或画布)的 image_layer 填1。
				// 2)纯音频混流,该参数也需填。
				layoutParams.put("image_layer", 1);
				// 目前支持:
				// 不填默认为0。
				// 0表示输入源为音视频。
				// 2表示输入源为图片。
				// 3表示输入源为画布。
				// 4表示输入源为音频。
				// 5表示输入源为纯视频。
//				layoutParams.put("input_type", 2);
				layoutParams.put("input_type", 3);
				// 不填默认为输入流的宽度。
				// 使用百分比时,期望输出为(百分比 * 背景宽)
				layoutParams.put("image_width", 540);
				// 不填默认为输入流的高度。
				// 使用百分比时,期望输出为(百分比 * 背景高)
				layoutParams.put("image_height", 540);
				// 使用画布(input_type = 3)时填写,常用的颜色有:
				// 红色:0xcc0033。
				// 黄色:0xcc9900。
				// 绿色:0xcccc33。
				// 蓝色:0x99CCFF。
				// 黑色:0x000000。
				// 白色:0xFFFFFF。
				// 灰色:0x999999。
				// 自己设置:23232f
				layoutParams.put("color", "23232f");
//				layoutParams.put("picture_id", 118417);
				// 参数1
				input_stream_list.put("input_stream_id", "canvas1");
				// 参数二
				input_stream_list.put("layout_params", layoutParams);
				list.add(input_stream_list);
			}
			// 画布图层1
			// layout_params
			JSONObject layoutParams1 = new JSONObject();
			JSONObject crop_params = new JSONObject();
			// 1)背景流(即大主播画面或画布)的 image_layer 填1。
			// 2)纯音频混流,该参数也需填。
			layoutParams1.put("image_layer", i + 2);
			// 判断主播共多少个来做画布的布局
			// 1 v 1
			if (max == 1) {

				if (i == 0) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
//                    map = lists.get(i);
//                    map.get("width");
//                    map.get("width");
					layoutParams1.put("image_height", (540 / 2.0) * (250.0 / 188) - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 540);
					crop_params.put("crop_height", 540);
					crop_params.put("crop_x", 0);
					crop_params.put("crop_y", 0);
				} else if (i == 1) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", (540 / 2.0) * (250.0 / 188.0) - 0.1);
					// // x 轴
					layoutParams1.put("location_x", 0.5);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280 * (250.0 / 188));
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				}
				// 三人间
			} else if (max == 2) {

				if (i == 0) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
//                    map = lists.get(i);
//                    map.get("width");
//                    map.get("width");
					layoutParams1.put("image_height", 540 / 2.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0.25);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 540);
					crop_params.put("crop_height", 540);
					crop_params.put("crop_x", 0);
					crop_params.put("crop_y", 0);
				} else if (i == 1) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 2.0 - 0.1);
					// // x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 0.5);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 2) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 2.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0.5);
					// y 轴
					layoutParams1.put("location_y", 0.5);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				}
				// 四人间
			} else if (max == 3) {
				if (i == 0) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
//                        map = lists.get(i);
//                        map.get("width");
//                        map.get("width");
					layoutParams1.put("image_height", 540 / 2.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 540);
					crop_params.put("crop_height", 540);
					crop_params.put("crop_x", 0);
					crop_params.put("crop_y", 0);
				} else if (i == 1) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 2.0 - 0.1);
					// // x 轴
					layoutParams1.put("location_x", 0.5);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 2) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 2.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 0.5);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 3) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 2.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 2.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0.5);
					// y 轴
					layoutParams1.put("location_y", 0.5);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				}

				// 五人间
			} else if (max == 4) {
				if (i == 0) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
//                        map = lists.get(i);
//                        map.get("width");
//                        map.get("width");
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0 / 2.0);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 540);
					crop_params.put("crop_height", 540);
					crop_params.put("crop_x", 0);
					crop_params.put("crop_y", 0);
				} else if (i == 1) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// // x 轴
					layoutParams1.put("location_x", 1 / 3.0 / 2.0 + 1 / 3.0);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 2) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 3) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 4) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0 * 2.0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				}
				// 六人间
			} else if (max == 5) {
				if (i == 0) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
//                        map = lists.get(i);
//                        map.get("width");
//                        map.get("width");
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 540);
					crop_params.put("crop_height", 540);
					crop_params.put("crop_x", 0);
					crop_params.put("crop_y", 0);
				} else if (i == 1) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// // x 轴
					layoutParams1.put("location_x", 1 / 3.0);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 2) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0 * 2);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 3) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 4) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 5) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0 * 2.0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				}
				// 七人间
			} else if (max == 6) {
				if (i == 0) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)

					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 0);
					crop_params.put("crop_width", 540);
					crop_params.put("crop_height", 540);
					crop_params.put("crop_x", 0);
					crop_params.put("crop_y", 0);
				} else if (i == 1) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// // x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 2) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 3) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0 * 2.0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 4) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0 * 2);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 5) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0 * 2.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				} else if (i == 6) {
					// 不填默认为输入流的宽度。
					// 使用百分比时,期望输出为(百分比 * 背景宽)
					layoutParams1.put("image_width", 540 / 3.0 - 0.1);
					// 不填默认为输入流的高度。
					// 使用百分比时,期望输出为(百分比 * 背景高)
					layoutParams1.put("image_height", 540 / 3.0 - 0.1);
					// x 轴
					layoutParams1.put("location_x", 1 / 3.0 * 2.0);
					// y 轴
					layoutParams1.put("location_y", 1 / 3.0 * 2.0);
					crop_params.put("crop_width", 280);
					crop_params.put("crop_height", 280);
					crop_params.put("crop_x", 1);
					crop_params.put("crop_y", 100);
				}
			}
			// input_stream_list
			JSONObject input_stream_list1 = new JSONObject();
//            // 参数1
			input_stream_list1.put("input_stream_id", idsList.get(i));
			// 参数二
			input_stream_list1.put("layout_params", layoutParams1);
			input_stream_list1.put("crop_params", crop_params);
			list.add(input_stream_list1);

		}
		// 封装画布布局
		para.put("input_stream_list", list);
		JSONObject jsonObject = new JSONObject();
		// 固定值Mix_StreamV2
		jsonObject.put("interfaceName", "Mix_StreamV2");
		jsonObject.put("para", para);
		TencentApi api = new TencentApi();
		JSONObject result = api.common(jsonObject);

		return result;
	}

	public Boolean sendGroupMsg(JSONObject message) {

		// 验证获取签名
		TLSSigAPIv2 api = new TLSSigAPIv2(AccessToken.SDK_APP_ID, AccessToken.KEY);
		// 得到签名
		String sing = api.genSig("admin", 180 * 86400);
		String result = sing.replaceAll("(\\r\\n|\\n|\\n\\r)", "");
		// 获取DefaultHttpClient请求
		HttpClient client = HttpClientBuilder.create().build();
		String url = AccessToken.SEND_GROUP_SYSTEM_NOTIFICATION + "?sdkappid=" + AccessToken.SDK_APP_ID
				+ "&identifier=admin&usersig=" + result + "&random=" + getSixNumber() + "&contenttype=json";
		HttpPost httpPost = new HttpPost(url);
		// 设置请求的header
		httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
		// 打印参数
		// 设置请求的参数
		StringEntity params = (new StringEntity(message.toString(), Consts.UTF_8));
		// 将参数传入httpBody中
		httpPost.setEntity(params);
		// 执行请求
		HttpResponse response;
		try {
			response = client.execute(httpPost);
			JSONObject existJsonObject = JSON.parseObject(EntityUtils.toString(response.getEntity(), "utf-8"));
			Integer errorCode = (Integer) existJsonObject.get("ErrorCode");
			if (errorCode == 0) {
				return true;
			} else {
				return false;
			}

		} catch (ClientProtocolException e) {
			e.printStackTrace();

		} catch (IOException e) {
			e.printStackTrace();

		}
		return null;
	}

	 
}

备注:

  1.根据自己的业务进行修改,当用户注册时进行IM绑定注册,让自己的会员跟腾讯的IM体系进行关联

  2. 根据自己的业务开启直播时,在什么流程下创建直播间群聊,群聊一定要是AVChatRoom,而且这个单独购买服务,否则有创建上线。

 3.为了降低延迟最后采用rtmp 超低延迟解决方案。需要购买实时音视频套餐包!

 

新手无怪,有问题评论区留言即可,会尽快回复!

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值