本文介绍通过调用播单型导播台API实现直播场景。超快捷聚合多个点播视频,创建播单型导播台类型直播间,帮助各合作伙伴丰富其视频场景和内容形态,解决直播场次不固定、内容少、用户不稳定的问题。同时可实时或定时自动插入广告,促进商业变现。
方案概览
使用播单型导播台API实现直播场景大致分为4步,如下:
启用点播系统Bucket:开通视频点播服务后,不同的服务地域会默认分配一个独立的存储Bucket(类型为点播系统Bucket),通过启用该Bucket,无需其他配置即可进行上传和媒体资源管理。
上传音视频文件:将需要进行直播的视频文件(例如A、B、C三个视频文件)按照顺序依次上传至视频点播(VOD)控制台存储。
添加播流域名:观众端用于观看直播的地址。观众可以通过播放地址来观看直播内容。
调用API完成播单型导播台配置:通过调用播单型导播台API,对单个视频的播放次数和播单循环次数分别进行配置。例如文件A播放一遍,文件B播放两遍,文件C播放三遍。配置完成,查询整个节目单播放列表信息并开启播放。
前提条件
您已注册阿里云账号并完成账号实名认证。
依次开通视频点播服务、视频直播服务、云导播服务。具体操作,请参见开通视频点播、开通与购买视频直播、开通云导播服务。
说明目前导播台仅在上海(华东2)、北京(华北2)、亚太东南1(新加坡)、印度尼西亚(雅加达)中心开放,后续将会扩展至其他中心。
已准备好播流域名。为了快速体验,建议直播中心选择海外且加速区域采用海外及港澳台加速,此时域名无需备案。
已添加AliyunFCFullAccess、AliyunLiveFullAccess、AliyunVODFullAccess系统权限策略。具体操作,请参见创建RAM用户并授权。
1.启用点播系统Bucket
在视频点播控制台的配置管理 > 媒资管理配置 > 存储管理页面中,单击点播系统Bucket所在行的启用。
启用存储地址需要一段时间,请您耐心等待。当系统提示存储地址启用成功,且存储地址的状态为正常后,方可使用该存储地址。
2.上传音视频文件
在点播控制台的 页面,单击上传音/视频。
在上传音/视频页面,单击添加音/视频。
在添加音/视频弹框中,选择本地上传,将本地准备好的三个视频文件依次上传,单击开始上传。
成功后,可在音/视频页面查看并记录资源ID。然后单击操作列的更多 > 用于直播导播,播放内容可以实时在视频直播的导播台中关联显示。导播台功能说明,请参见功能区介绍。
3.添加播流域名
在视频直播控制台的推/播流域名管理 页面中,单击添加域名。
根据实际需求配置域名详情。单击下一步。配置参数的具体说明请参见添加加速域名。
记录生成的CNAME记录值,供下一步使用。
在云解析DNS控制台的域名解析页面,单击待设置的域名操作列的解析设置。
单击添加记录,完成CNAME配置,单击确认。更多详细信息,请参见配置域名的CNAME解析。
4.调用API完成播单型导播台配置
打开Intellij IDEA创建Maven项目,在pom.xml中新建 <dependencies></dependencies>标签,并添加如下依赖。
<dependencies> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-live</artifactId> <version>3.9.52</version> </dependency> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.6.3</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.76</version> </dependency> </dependencies>
在项目
src/main/java
目录下,右键单击java,创建Java类。例如命名为bodan。配置如下示例代码相关参数并运行。
package com.alibaba.aliyundebug.common; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.aliyun.live20161101.Client; import com.aliyuncs.AcsResponse; import com.aliyuncs.CommonRequest; import com.aliyuncs.CommonResponse; import com.aliyuncs.DefaultAcsClient; import com.aliyuncs.exceptions.ClientException; import com.aliyuncs.live.model.v20161101.*; import com.aliyuncs.profile.DefaultProfile; import com.aliyuncs.utils.StringUtils; import org.apache.commons.codec.digest.DigestUtils; import org.junit.jupiter.api.Test; import java.util.List; import java.util.Random; import java.util.UUID; public class Bodan { private final static String ACCESS_KEY_ID = "xxxx"; private final static String ACCESS_KEY_SECRET = "xxxx"; public static DefaultAcsClient initClient(String accessKeyId, String accessKeySecret) throws ClientException { String regionId = "cn-shanghai"; DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret); DefaultAcsClient client = new DefaultAcsClient(profile); return client; } private static CreateCasterResponse createCaster(DefaultAcsClient client) throws ClientException { CreateCasterRequest request = new CreateCasterRequest(); Random random = new Random(); int i = random.nextInt(100000); request.setCasterName("casterName" + i); UUID uuid = UUID.randomUUID(); String token = "thisIsaToken"; String clientToken = DigestUtils.sha256Hex(token + uuid); request.setClientToken(clientToken); // 节目单可以只用创建播单型即可。 request.setNormType(6); request.setChargeType("PostPaid"); CreateCasterResponse response = client.getAcsResponse(request); System.out.println("创建导播台成功,返回值: " + JSON.toJSONString(response)); return response; } private static void setCasterConfig(DefaultAcsClient client, String casterId) throws ClientException { SetCasterConfigRequest request = new SetCasterConfigRequest(); request.setCasterId(casterId); // 配置域名 request.setDomainName("example.aliyundoc.com"); JSONObject transcodeConfig = new JSONObject(); JSONArray liveTemplate = new JSONArray(); //配置导播台模板 liveTemplate.add("lld"); transcodeConfig.put("LiveTemplate", liveTemplate); //配置转码模板 transcodeConfig.put("CasterTemplate", "lp_sd"); request.setTranscodeConfig(transcodeConfig.toJSONString()); SetCasterConfigResponse response = client.getAcsResponse(request); System.out.println("添加导播台配置成功:requestId" + response.getRequestId() + " response:" + JSON.toJSONString(response)); } private static AcsResponse startCaster(DefaultAcsClient client, String casterId) throws ClientException { StartCasterRequest startCasterRequest = new StartCasterRequest(); startCasterRequest.setCasterId(casterId); StartCasterResponse acsResponse = client.getAcsResponse(startCasterRequest); System.out.println("开启导播台成功"); return acsResponse; } private static AcsResponse stopCaster(DefaultAcsClient client, String casterId) throws ClientException { StopCasterRequest stopCasterRequest = new StopCasterRequest(); stopCasterRequest.setCasterId(casterId); StopCasterResponse acsResponse = client.getAcsResponse(stopCasterRequest); System.out.println("停止导播台成功"); return acsResponse; } private static CommonResponse addShowIntoShowList(DefaultAcsClient client, String showName, String resourceId, String resourceUrl, String resourceType, Integer spot, Integer repeatTimes, String casterId, Long duration) throws ClientException { CommonRequest addShowIntoShowListRequest = new CommonRequest(); addShowIntoShowListRequest.setSysDomain("live.aliyuncs.com"); addShowIntoShowListRequest.setSysVersion("2016-11-01"); addShowIntoShowListRequest.setSysAction("AddShowIntoShowList"); if (casterId == null || resourceType == null) { return null; } if (resourceId == null && resourceUrl == null) { return null; } addShowIntoShowListRequest.putQueryParameter("CasterId", casterId); addShowIntoShowListRequest.putQueryParameter("ResourceType", resourceType); if (showName != null) { addShowIntoShowListRequest.putQueryParameter("ShowName", showName); } if (resourceUrl != null) { addShowIntoShowListRequest.putQueryParameter("ResourceUrl", resourceUrl); } if (resourceId != null) { addShowIntoShowListRequest.putQueryParameter("ResourceId", resourceId); } if (spot != null) { addShowIntoShowListRequest.putQueryParameter("Spot", spot.toString()); } if (repeatTimes != null) { addShowIntoShowListRequest.putQueryParameter("RepeatTimes", repeatTimes.toString()); } if (duration != null) { addShowIntoShowListRequest.putQueryParameter("Duration", duration.toString()); } CommonResponse addShowIntoShowListResponse = client.getCommonResponse(addShowIntoShowListRequest); return addShowIntoShowListResponse; } private static void removeShowFromShowList(DefaultAcsClient client, String casterId, String showId) throws ClientException { CommonRequest removeShowFromShowListFromShowList = new CommonRequest(); removeShowFromShowListFromShowList.setSysDomain("live.aliyuncs.com"); removeShowFromShowListFromShowList.setSysVersion("2016-11-01"); removeShowFromShowListFromShowList.setSysAction("RemoveShowFromShowList"); removeShowFromShowListFromShowList.putQueryParameter("ShowId", showId); removeShowFromShowListFromShowList.putQueryParameter("CasterId", casterId); CommonResponse removeShowFromShowListFromShowListResponse = client.getCommonResponse(removeShowFromShowListFromShowList); System.out.println("删除导播台节目,removeShowFromShowListFromShowListResponse:" + JSON.toJSONString(removeShowFromShowListFromShowListResponse)); } private static CommonResponse modfiyShowList(DefaultAcsClient client, String casterId, String showId, Integer repeatTimes, Integer spot, String highPriorityShowId, String highPriorityShowStartTime) throws ClientException { CommonRequest modfiyShowListRequest = new CommonRequest(); modfiyShowListRequest.setSysDomain("live.aliyuncs.com"); modfiyShowListRequest.setSysVersion("2016-11-01"); modfiyShowListRequest.setSysAction("ModifyShowList"); if (casterId != null) { modfiyShowListRequest.putQueryParameter("CasterId", casterId); } if (showId != null) { modfiyShowListRequest.putQueryParameter("ShowId", showId); } if (repeatTimes != null) { modfiyShowListRequest.putQueryParameter("RepeatTimes", repeatTimes.toString()); } if (spot != null) { modfiyShowListRequest.putQueryParameter("Spot", spot.toString()); } if (highPriorityShowId != null) { modfiyShowListRequest.putQueryParameter("HighPriorityShowId", highPriorityShowId.toString()); } if (highPriorityShowStartTime != null) { modfiyShowListRequest.putQueryParameter("HighPriorityShowStartTime", highPriorityShowStartTime.toString()); } CommonResponse modfiyShowListResponse = client.getCommonResponse(modfiyShowListRequest); System.out.println("修改showList成功,返回值:" + JSON.toJSONString(modfiyShowListResponse)); return modfiyShowListResponse; } private static CommonResponse describeShowList(DefaultAcsClient client, String casterId) throws ClientException { CommonRequest describeShowListRequest = new CommonRequest(); describeShowListRequest.setSysDomain("live.aliyuncs.com"); describeShowListRequest.setSysVersion("2016-11-01"); describeShowListRequest.setSysAction("DescribeShowList"); if (casterId != null) { describeShowListRequest.putQueryParameter("CasterId", casterId); } CommonResponse describeShowListRequestResponse = client.getCommonResponse(describeShowListRequest); System.out.println("查询showList成功,返回值:" + JSON.toJSONString(describeShowListRequestResponse)); return describeShowListRequestResponse; } private static void playChoosenShow(DefaultAcsClient client, String casterId, String showId) throws ClientException { CommonRequest playChoosenShow = new CommonRequest(); playChoosenShow.setSysDomain("live.aliyuncs.com"); playChoosenShow.setSysVersion("2016-11-01"); playChoosenShow.setSysAction("playChoosenShow"); playChoosenShow.putQueryParameter("CasterId", casterId); playChoosenShow.putQueryParameter("ShowId", showId); CommonResponse playChoosenShowResponse = client.getCommonResponse(playChoosenShow); System.out.println("手动切换showId: "+showId+" 成功"); } private static List<DescribeCasterStreamUrlResponse.CasterStream> describeCasterStreamUrl(DefaultAcsClient client, String casterId) throws ClientException { DescribeCasterStreamUrlRequest describeCasterStreamUrlRequest = new DescribeCasterStreamUrlRequest(); describeCasterStreamUrlRequest.setCasterId(casterId); DescribeCasterStreamUrlResponse acsResponse = client.getAcsResponse(describeCasterStreamUrlRequest); List<DescribeCasterStreamUrlResponse.CasterStream> casterStreams = acsResponse.getCasterStreams(); return casterStreams; } public static void main(String[] args) throws ClientException { DefaultAcsClient client = null; try { client = initClient(ACCESS_KEY_ID, ACCESS_KEY_SECRET); //创建导播台 CreateCasterResponse caster = createCaster(client); String casterId = caster.getCasterId(); //设置导播台 setCasterConfig(client, casterId); //添加三个点播文件,让第一个文件播一遍,第二个文件播两遍,第三个文件播三遍 String[] resourceIds = new String[]{"698d2b23581f476ea71107703e64****", "9c97e83e211a435b9f797e4e20ee****", "76c6addaa41c438985666a8a964f****"}; for (int i = 0; i < resourceIds.length; i++) { String showName = "ShowName#" + i; Integer repeatTimes = i; addShowIntoShowList(client, showName, resourceIds[i], null, "vod", null, repeatTimes, casterId, null); } modfiyShowList(client, casterId, null, 10, null, null, null); CommonResponse describeShowList = describeShowList(client, casterId); String data = describeShowList.getData(); JSONObject jsonObject = JSON.parseObject(data); JSONObject showList = jsonObject.getJSONObject("ShowList"); JSONArray shows = showList.getJSONArray("Shows"); //打印播放节目单 for (int i = 0; i < shows.size(); i++) { JSONObject show = (JSONObject) shows.get(i); String showId = show.getString("ShowId"); String resourceType = show.getString("ResourceType"); String resourceInfo = show.getString("ResourceInfo"); Integer repeatTimes = show.getInteger("RepeatTimes"); Long duration = show.getLong("Duration"); String showInfo = String.format("show%d: showId: %s \n resourceType: %s \n resourceInfo: %s \n RepeatTimes: %d \n Duration: %d", i + 1, showId, resourceType, resourceInfo, repeatTimes, duration); System.out.println(showInfo); } startCaster(client, casterId); Thread.sleep(500000); stopCaster(client, casterId); } catch (ClientException | InterruptedException e) { e.printStackTrace(); } } }
参数配置信息说明:
参数配置信息
说明
private final static String ACCESS_KEY_ID = "AccessKey ID"; private final static String ACCESS_KEY_SECRET = "AccessKey Secret";
您需要使用AccessKey完成身份验证。AccessKey包括AccessKey ID和AccessKey Secret。具体如下:
AccessKey ID:用于标识用户。
AccessKey Secret:用于验证用户的密钥。AccessKey Secret必须保密。
更多信息,请参见创建AccessKey。
request.setDomainName("example.aliyundoc.com");
播流域名。
String[] resourceIds = new String[]{"698d2b23581f476ea71107703e64****", "9c97e83e211a435b9f797e4e20ee****", "76c6addaa41c438985666a8a964f****"};
资源ID。请参见2.上传音视频文件获取。
查看运行结果。
在云导播台页面,可查看已创建的导播台,单击操作列的进入,即可看到三个点播文件按照顺序依次添加到节目单中,并按照相关配置进行播放。
后续操作
如果需要播放,您可以单击云导播台的播放地址并复制,通过VLC播放器、直播Demo或播放器SDK进行播放。具体操作,请参见直播播放。