文档

播单型导播台最佳实践

播单型导播台用于快速聚合多个视频节目,创建播单型导播台类型直播间,丰富直播场景和内容形态。本文介绍播单型导播台API的调用场景和代码示例。

场景概述

播单型导播台API的调用场景:

  1. 将三个点播文件A、B、C按照顺序依次添加到节目单中。

  2. 添加完成,对单个节目的播放次数和整体节目单的播放次数分别进行配置。例如文件A播一遍,文件B播两遍,文件C播三遍。

  3. 配置完成,查询整个节目单播放列表信息并开启播放。

前提条件

  • 您已注册阿里云账号并完成账号实名认证。

  • 依次开通视频点播服务、视频直播服务、云导播服务。具体操作,请参见开通视频点播开通与购买视频直播开通云导播服务

  • 已准备好播流域名。为了快速体验,建议直播中心选择海外且加速区域采用海外及港澳台加速,此时域名无需备案。

  • 目前导播台仅在上海(华东2)、北京(华北2)、亚太东南1(新加坡)、印度尼西亚(雅加达)中心开放,后续将会扩展至其他中心。

  • 已添加AliyunFCFullAccessAliyunLiveFullAccessAliyunVODFullAccess系统权限策略。具体操作,请参见创建RAM用户并授权

步骤一:启用点播系统Bucket

开通视频点播服务后,不同的服务地域会默认分配一个独立的存储Bucket(类型为点播系统Bucket),通过启用该Bucket,无需其他配置即可进行上传和媒体资源管理。

  1. 登录视频点播控制台

  2. 在左侧导航栏选择配置管理 > 媒资管理配置 > 存储管理,进入到存储管理页面。

  3. 单击页面左上方的服务地域,切换到目标服务地域下。

    存储管理3

  4. 单击点播系统Bucket所在行的启用

    启用存储地址需要一段时间,请您耐心等待。当系统提示存储地址启用成功,且存储地址的状态为正常后,方可使用该存储地址。

步骤二:上传音视频文件

  1. 在点播控制台左侧导航栏的媒资库区域,单击音/视频

  2. 单击上传音/视频

  3. 单击添加音/视频

  4. 添加音/视频弹框中,选择本地上传,将本地准备好的三个视频文件依次上传,单击开始上传

  5. 成功后,可在音/视频页面查看并记录资源ID。

    image

  6. 音/视频页面,单击操作列的更多 > 用于直播导播,播放内容可以实时在视频直播的导播台中关联显示。导播台功能说明,请参见功能区介绍

      说明

      仅当媒体资源为视频时,才能设置用于直播导播

      每个视频只能使用一次用于直播导播,使用之后用于直播导播会置灰无法使用。

步骤三:添加播流域名

  1. 登录视频直播控制台

  2. 在左侧导航栏单击域名管理,进入域名管理页面。

  3. 单击添加域名

  4. 根据实际需求配置域名详情。

    重要

    当您首次将一个新域名添加至阿里云视频直播时,需要您完成验证域名的归属权,请参见验证域名归属权

    配置域名

    展开查看参数

    参数

    参数分类

    说明

    业务类型

    • 播流域名

    • 推流域名

    指域名的加速类型,推流域名与播流域名分别对应推流加速与播流加速。初次配置后不可更改。

    说明
    • 添加推流域名时,业务类型请选择推流域名;添加播流域名时请选择播流域名

    • 您无法将同一域名既添加为推流域名,又添加为播流域名。

    加速域名

    输入您需要加速的域名。注意事项如下:

    • 加速域名一般使用子域名,例如: demo.aliyundoc.com

    • 直播服务暂不支持添加泛域名,例如: *.aliyundoc.com

    • 加速域名不允许重复添加,如果出现域名已添加的提示,请检查您的域名是否已经添加到其他云产品中,例如视频点播、全站加速、SCDN和视频监控。

    • 开通视频直播服务后,每个账户最多可添加20个域名,如果您域名的总带宽日均峰值大于50 Mbps,且业务无风险,可以提交工单申请增加域名个数。关于如何提交工单,请参见联系我们

    • 加速内容必须合法且符合业务规范,详情请参见域名准入标准

    说明

    子域名必须在同一个账号下。您在添加域名时,直播服务会进行检查,如果子域名被添加到不同账号,系统会报错。

    加速区域

    中国内地

    • 当主播在中国内地时,推流域名应选择中国内地

    • 当观众在中国内地时,播流域名应选择中国内地

    域名需要在工信部备案,推荐您进入阿里云ICP代备案管理系统进行备案。

    全球加速

    • 当主播在中国内地、中国香港、中国澳门、中国台湾以及其他国家和地区时,推流域名应选择全球加速

    • 当观众在中国内地、中国香港、中国澳门、中国台湾以及其他国家和地区时,播流域名应选择全球加速

    域名需要在工信部备案,推荐您进入阿里云ICP代备案管理系统进行备案。

    海外及港澳台加速

    • 当主播在海外及中国香港、中国澳门、中国台湾时,推流域名应选择海外及港澳台加速

    • 当观众在海外及中国香港、中国澳门、中国台湾时,播流域名应选择海外及港澳台加速

    • 如果选择海外及港澳台加速且直播中心在海外,则域名无需在工信部备案。

    • 如果选择海外及港澳台加速且直播中心在中国境内,则域名需要在工信部备案。推荐您进入阿里云ICP代备案管理系统进行备案。

    说明

    关于如何选择CDN加速区域,请参见如何选择域名的CDN加速区域?

    直播中心

    直播中心用来提供云上直播流的媒体处理服务,如截图、录制、转码、云导播等。

    需要关联的直播推流域名与播流域名的直播中心所在地域要保持一致,初次配置后不可更改。

    关于如何选择直播中心,请参见如何选择直播中心?

完成添加播流域名的操作后,需要对添加的域名进行CNAME解析,请参见配置域名的CNAME解析

步骤四:调用API完成播单型导播台配置

  1. 打开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>
  2. 在项目src/main/java目录下,右键单击java,创建Java类。例如命名为bodan。

  3. 配置如下示例代码相关参数并运行。

    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。请参见步骤二:上传音视频文件获取。

  4. 查看运行结果。

    image

  5. 云导播台页面,可查看已创建的导播台,单击操作列的进入,即可看到三个点播文件按照顺序依次添加到节目单中,并按照相关配置进行播放。

    image

    image

后续操作

如果需要播放,您可以单击云导播台的播放地址并复制,通过VLC播放器、直播Demo或播放器SDK进行播放。具体操作,请参见直播播放

image