使用阿里云播放器实现全屏秒播

基于阿里云播放器SDK的预加载能力和点播设置视频封面等策略的搭配使用,可实现视频毫秒级的起播速度,能有效解决短视频场景中的视频起播慢,切换视频卡顿等问题,为用户呈现无感起播和流畅丝滑的播放体验。本文介绍如何使用阿里云播放器SDK实现全屏秒播。

方案原理

播放视频时,在起播阶段因加载视频需要一定的时间,因此播放可能会出现一段黑屏的时间。一方面,可以通过开启阿里云播放器的预加载功能以及通过预热视频资源来提升视频的起播速度。另一方面,由于图片的加载速度比视频加载速度快的更多,此时如果设置了视频封面图,则起播阶段视频还未加载出来时,可以由封面图占据播放页面直到视频加载出来开始播放,从而避免视频黑屏的视觉效果;而通过将视频的首帧截图设置为视频封面,使用户感觉不到视频封面的存在,以达到视频秒开极快的视觉效果。

通过此方案,在WiFi环境下可以实现使用阿里云播放器播放视频达到平均300毫秒左右的起播速度。

使用限制

  • 目前仅支持通过阿里云Android播放器SDK和iOS播放器SDK实现全屏秒播。

  • 目前仅支持MP4、MP3、FLV、HLS(单码率视频流)等单个媒体文件实现预加载功能。

  • 预加载仅支持使用UrlSource方式播放视频,暂不支持VidAuth、VidSts方式播放视频。

前提条件

步骤一:开启阿里云播放器SDK的预加载功能

阿里云播放器SDK的预加载功能,通过提前将视频数据加载到本地,来提升视频的起播速度。

使用限制

  • 目前支持MP4、MP3、FLV、HLS(单码率视频流)等单个媒体文件的加载。

  • 仅支持UrlSource播放方式播放视频的预加载,暂不支持VidAuth、VidSts方式播放视频的预加载。

Android播放器配置

  1. 开启本地缓存功能。

    /app/src/main/java/com/aliyun/alivcsolution/MutiApplication.java文件中,通过AliPlayerGlobalSettings.enableLocalCache开启。

    public class MutiApplication extends Application {
    
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            MultiDex.install(this);
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            //开启本地缓存,本地缓存文件路径,为绝对路径,下述示例为/tmp,下述示例中10240对应的参数在5.4.7.1及以后版本已废弃,暂无作用
            AliPlayerGlobalSettings.enableLocalCache(true,10240,"/tmp");
    
          
        }
    
    }
  2. 创建预加载单例,并在初始化时设置预加载的回调函数。

    /AliyunListPlayer/src/main/java/com/aliyun/player/aliyunlistplayer/AliyunListPlayerActivity.java文件中创建。

    public class AliyunListPlayerActivity extends AppCompatActivity {
    
        private AliyunListPlayerView mListPlayerView;
        private NetWatchdog mNetWatchDog;
        private String mUserToken;
        private boolean mIsLoadMore = false;
        private int mLastVideoId = -1;
        private ImageView mBackImageView;
        
        //创建预加载单例
        private MediaLoader medialoader=MediaLoader.getInstance();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_aliyun_list_player);
            mUserToken = getIntent().getStringExtra("list_player_user_token");
    
            initView();
            initSts(true);
            initListener();
    
    
            //设置加载状态回调
            medialoader.setOnLoadStatusListener(new MediaLoader.OnLoadStatusListener() {
                @Override
                public void onError(String url, int code, String msg) {
                    //加载出错
                }
    
                @Override
                public void onCompleted(String s) {
                    //加载完成
                }
    
                @Override
                public void onCanceled(String s) {
                    //加载取消
                }
            });
        }
        ...
  3. 在请求数据响应时,调用load函数实现预加载数据存储到指定磁盘路径中。

    private void getDatas(int id){
            GetVideoInfomation getVideoInfomation = new GetVideoInfomation();
            getVideoInfomation.getListPlayerVideoInfos(this, "1", mUserToken, id, new GetVideoInfomation.OnGetListPlayerVideoInfosListener() {
                private SparseArray<String> mSparseArray;
                @Override
                public void onGetSuccess(Request request, String result) {
                    //demo列表播放器实现中,仅根据video id请求视频数据
                    //但是预加载只能通过url实现,不能通过video id预加载视频数据
                    //这里只是做一个说明,在拿到url后,如何通过medialoader实现预加载
                    String url="";//假设这里拿到了视频url
                    medialoader.load(url,10000);//预加载数据存储到指定磁盘路径中,加载时长为10000毫秒
    
                    Gson gson = new Gson();
                    AliyunVideoListBean aliyunVideoListBean = gson.fromJson(result, AliyunVideoListBean.class);
                    
                    ...

iOS播放器配置

  1. 在初始化时,开启本地缓存功能并设置预加载的回调函数。

    - (AliPlayer *)aliPlayer{
        if (!_aliPlayer && UIApplicationStateActive == [[UIApplication sharedApplication] applicationState]) {
            _aliPlayer = [[AliPlayer alloc] init];
            _aliPlayer.scalingMode =  AVP_SCALINGMODE_SCALEASPECTFIT;
            _aliPlayer.rate = 1;
            _aliPlayer.delegate = self;
            _aliPlayer.playerView = self.playerView;
    
            //开启本地缓存,本地缓存文件路径沙盒路径,maxBufferMemoryKB对应的10240对应的参数在5.4.7.1及以后版本已废弃,暂无作用
            NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
            [AliPlayerGlobalSettings enableLocalCache:YES maxBufferMemoryKB:10*1024 localCacheDir:[docDir stringByAppendingPathComponent:@"alivcCache"]];
            [AliPlayerGlobalSettings setCacheFileClearConfig:30*60*24 maxCapacityMB:20480 freeStorageMB:0];
            //设置url回调方法,这里避免预加载时的url和播放时的url由于参数的变化导致不一致造成预加载失效
            [AliPlayerGlobalSettings setCacheUrlHashCallback:hashCallback];
            
            //设置回调代理
            [[AliMediaLoader shareInstance] setAliMediaLoaderStatusDelegate:self];
    
        }
        return _aliPlayer;
    }
    
    //设置url回调方法
    NSString* hashCallback(NSString* url){
        NSString *md5Str = [NSString aliyun_MD5:url];
        return md5Str;
    }
    
    //预加载的回调方法
    #pragma mark -- AliMediaLoaderStatusDelegate
    /**
     @brief 错误回调
     @param url 加载url
     @param code 错误码
     @param msg 错误描述
     */
    - (void)onError:(NSString *)url code:(int64_t)code msg:(NSString *)msg {
        
    }
    
    /**
     @brief 完成回调
     @param url 加载url
     */
    - (void)onCompleted:(NSString *)url {
        
    }
    
    /**
     @brief 取消回调
     @param url 加载url
     */
    - (void)onCanceled:(NSString *)url {
        
    }

  2. 设置数据源时,调用load函数实现预加载数据存储到指定磁盘路径。

    NSString *urlString = @"<url地址>";
    AVPUrlSource *urlSource = [[AVPUrlSource alloc] urlWithString:urlString];
    [_aliPlayer setUrlSource:urlSource];
    [[AliMediaLoader shareInstance] load:urlString duration:10000];//预加载数据存储到指定磁盘路径中,加载时长示例为10000毫秒

步骤二:设置视频首帧截图为视频封面

通过将视频首帧截图设置为视频封面,以达到视频秒开极快的视觉效果。

说明

当使用阿里云播放器播放视频时,在列表播放的场景下,您可以结合视频封面设置如下播放逻辑来达到秒开的视觉效果并节省流量。

  • 当用户快速滑动切换视频时,仅仅只请求视频封面图。

  • 当用户切换下一个视频滑动到一半时,展示预先下载的视频封面图。

控制台方式配置

  1. 创建截取视频首帧的截图模板。

    1. 登录视频点播控制台

    2. 在左侧导航栏选择配置管理 > 媒体处理配置 > 截图模板,进入到截图模板页面。

    3. 单击添加截图模板,配置截取视频首帧截图的模板参数。

      模板名称请自定义设置,截图方式选择普通截图起始时间点设置为00:00:00,截图数量设置为1,其余参数请按需配置,有关截图模板的参数解释,详情请参见截图模板首帧截图1.png

    4. 单击保存,完成截图模板的创建。

  2. 发起截取视频首帧的截图任务。

    说明
    • 通过控制台方式发起截图任务时,只能通过工作流的方式发起,因此,您需要先创建一个包含视频首帧截图任务的工作流(即在工作流中添加视频截图节点,并设置截图模板为上一步创建的首帧截图模板)。工作流的创建方法,请参见工作流管理

    • 建议您发起截图任务之前,配置视频点播的事件通知,通过设置视频截图完成的事件通知,以便在截图任务完成后,能获取到截图任务的状态及截取的图片地址等信息。事件通知的配置方法,请参见回调设置

    • 场景一:上传视频时截图

      1. 在视频点播控制台,从左侧导航栏选择媒资库 > 音/视频

      2. 单击上传音/视频,单击添加音/视频

      3. 按需设置上传方式、存储地址并添加上传的视频后,选择用工作流处理,并选择预先创建的包含首帧截图任务的工作流。

      4. 单击开始上传

    • 场景二:上传视频后截图

      1. 在视频点播控制台,从左侧导航栏选择媒资库 > 音/视频

      2. 在音/视频列表页面,单击目标视频所在行的媒体处理

      3. 处理类型选择用工作流处理工作流选择预先创建的包含首帧截图任务的工作流。

      4. 单击确定

    • 获取截图结果

      • 如果您已经配置了视频点播的视频截图完成的事件通知,您可以从回调事件中获取到截图任务的状态及截取的图片地址等信息。

      • 如果您未配置事件通知,您可以使用轮询的方式调用ListSnapshots - 查询截图数据接口来查询截图任务的状态及截取的图片地址等信息。

  3. 修改视频封面为视频首帧截图。

    说明

    通过控制台方式修改视频封面,只支持在视频上传完成后对视频封面进行更新。您需要先将步骤2中截图任务截取到的视频首帧截图保存到本地以便修改封面时上传。

    1. 在视频点播控制台,从左侧导航栏选择媒资库 > 音/视频

    2. 在音/视频列表页面,单击目标视频所在行的管理

    3. 基础信息页签,单击编辑视频信息

    4. 单击上传封面,选择预先保存到本地的视频首帧截图,单击打开

    5. 单击保存,完成视频封面设置。

      设置完成后,您可以在音/视频列表页面查看视频封面是否更新成功。

OpenAPI方式配置

说明

本文以使用Java语言的阿里云 SDK方式调用视频点播的OpenAPI为例进行举例说明。

操作步骤

  1. 创建截取视频首帧的截图模板。

    调用AddVodTemplate - 添加截图或动图模板接口,创建截取视频首帧的截图模板。调用示例如下:

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.vod.model.v20170321.AddVodTemplateRequest;
    import com.aliyuncs.vod.model.v20170321.AddVodTemplateResponse;
    
    
    /**
     * 说明:
     * 1. 本Demo为创建首帧截图模板示例,截图输出为 1 张图片。
     * 2. 推荐使用视频点播控制台创建截图模板,更加方便快捷。
     */
    public class AddSnapshotTemplate {
    
        // 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
        // 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
        // 本示例通过从环境变量中读取AccessKey,来实现API访问的身份验证。运行代码示例前,请配置环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        public static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        public static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
    
        public static void main(String[] args) {
    
            try{
                DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
                AddVodTemplateResponse response = addSnapshotTemplate(vodClient);
                System.out.println("RequestId is:" + response.getRequestId());
                System.out.println("TemplateId is:" + response.getVodTemplateId());
            }catch (Exception e){
    
            }
        }
    
        public static AddVodTemplateResponse addSnapshotTemplate(DefaultAcsClient vodClient) throws ClientException {
            AddVodTemplateRequest request = new AddVodTemplateRequest();
            request.setName("首帧截图模板");
            request.setTemplateType("Snapshot");
            request.setTemplateConfig("{\"SnapshotType\":\"NormalSnapshot\",\"SnapshotConfig\":{\"FrameType\":\"normal\",\"Count\":1,\"Interval\":1,\"SpecifiedOffsetTime\":0}}");
    
            return vodClient.getAcsResponse(request);
        }
    
        public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
            // 点播服务接入区域
            String regionId = "cn-shanghai";  
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
    
            return client;
        }
    }
    
  2. 发起截取视频首帧的截图任务。

    调用SubmitSnapshotJob - 提交媒体截图作业接口,发起截图任务。调用示例如下:

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.vod.model.v20170321.*;
    
    /**
     * 说明:
     * 1. 本Demo为创建首帧截图模板后,提交首帧截图任务。
     * 2. 对于新上传的视频,建议该步骤放在【音视频分析完成】事件成功之后,对于存量且状态正常的视频,可自行设计。
     * 3. 截图为异步任务,需要等到【视频截图完成】事件成功之后(推荐),可获取截图地址。
     * 4. 根据回调事件中的SnapshotRegular,可推测出截图输出地址。详情请参见【视频截图完成】文档中的截图地址生成规则说明。
     * 5. 若您暂无回调服务,也可以通过ListSnapshots接口主动查询,该接口默认只返回最新一次的截图结果。详情请参见ListSnapshots接口文档。
     */
    public class SubmitSnapshotJob {
    
        // 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
        // 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
        // 本示例通过从环境变量中读取AccessKey,来实现API访问的身份验证。运行代码示例前,请配置环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        public static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        public static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
    
        public static void main(String[] args) {
    
            try{
                DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
                SubmitSnapshotJobResponse response = submitSnapshotJob(vodClient);
                System.out.println("RequestId is:" + response.getRequestId());
                System.out.println("JobId is:" + response.getSnapshotJob().getJobId());
            }catch (Exception e){
    
            }
        }
    
        public static SubmitSnapshotJobResponse submitSnapshotJob(DefaultAcsClient vodClient) throws ClientException {
            SubmitSnapshotJobRequest request = new SubmitSnapshotJobRequest();
            request.setVideoId("a42b**********633b79f0102");
            request.setSnapshotTemplateId("1f27a7**********eba2756");
            //自定义透传参数,回调时可用,非必须,用于区分封面首帧截图
            request.setUserData("{\"Extend\":{\"SnapshotType\":\"FirstFrame\",\"VideoId\":\"a42bf540********33b79f0102\"}}");
            return vodClient.getAcsResponse(request);
        }
    
        public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
            // 点播服务接入区域
            String regionId = "cn-shanghai";  
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
    
            return client;
        }
    
        //ListSnapshots 查询截图
        public static ListSnapshotsResponse listSnapshots(DefaultAcsClient vodClient) throws ClientException {
            ListSnapshotsRequest request = new ListSnapshotsRequest();
            request.setVideoId("a42bf540b1b371ed804a6633b79****");
            request.setSnapshotType("NormalSnapshot");
    
            ListSnapshotsResponse response = vodClient.getAcsResponse(request);
            System.out.println("RequestId is:" + response.getRequestId());
            System.out.println("SnapshotUrl is:" + response.getMediaSnapshot().getSnapshots().get(0).getUrl());
            return vodClient.getAcsResponse(request);
        }
    
    }
    
  3. 修改视频封面为视频首帧截图。

    此处以视频上传完成后,修改单个视频封面的场景为例进行说明,其他场景的实现,请参见上传视频时设置封面视频上传后更新封面

    通过调用UpdateVideoInfo - 修改单个音视频信息接口,传入CoverURL参数指定视频封面。调用示例如下:

    package com.alibaba.bltest.transcode;
    
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.vod.model.v20170321.UpdateVideoInfoRequest;
    import com.aliyuncs.vod.model.v20170321.UpdateVideoInfoResponse;
    
    /**
     * 说明:
     * 1. 本Demo为修改单个视频封面,如需修改其他视频参数,请参见UpdateVideoInfo的接口文档。
     * 2. 对于修改封面的场景,请确保您使用的图片地址是有效的。
     */
    public class UpdateVideoInfo {
    
        // 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
        // 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
        // 本示例通过从环境变量中读取AccessKey,来实现API访问的身份验证。运行代码示例前,请配置环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        public static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        public static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
    
        public static void main(String[] args) {
    
            try{
                DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
                UpdateVideoInfoResponse response = updateVideoInfo(vodClient);
                System.out.println("RequestId is:" + response.getRequestId());
            }catch (Exception e){
    
            }
        }
    
        public static UpdateVideoInfoResponse updateVideoInfo(DefaultAcsClient vodClient) throws ClientException {
            UpdateVideoInfoRequest request = new UpdateVideoInfoRequest();
            request.setVideoId("a42b***********33b79f0102");
            //设置首帧封面时,CoverURL为首帧截图任务成功后输出的图片地址
            request.setCoverURL("http://demo.aliyuncdn.com/a42bf5******40b1b37/snapshots/normal/41B7AF54-18672BB301D-1748-0984-309-112420****.jpg");
    
            return vodClient.getAcsResponse(request);
        }
    
        public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
            // 点播服务接入区域
            String regionId = "cn-shanghai";  
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            return client;
        }
    }
    

完整实例

package com.alibaba.bltest.transcode;


import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.*;
import org.apache.commons.lang3.StringUtils;

/**
 * 说明:
 * 1. 本Demo为完整截图+修改封面逻辑设计,部分代码需要根据自己业务逻辑自行修改。
 * 2. 本Demo非直接可用,部分逻辑需要自行补充。
 * 3. 本Demo仅供实现参考,不代表唯一实现方式。
 */
public class SnapshotAndUpdateCover {

    // 阿里云账号AccessKey拥有所有API的访问权限,建议您使用RAM用户进行API访问或日常运维。
    // 强烈建议不要把AccessKey ID和AccessKey Secret保存到工程代码里,否则可能导致AccessKey泄露,威胁您账号下所有资源的安全。
    // 本示例通过从环境变量中读取AccessKey,来实现API访问的身份验证。运行代码示例前,请配置环境变量ALIBABA_CLOUD_ACCESS_KEY_ID和ALIBABA_CLOUD_ACCESS_KEY_SECRET。
    public static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
    public static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");

    public static void main(String[] args) {


        try{
            DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
            //视频ID
            String videoId = "a42bf540b1b37*******b79f0102";

            //场景一:有回调服务 或 MNS
            //若是为新上传的视频设置封面,则需要先获取到音视频分析成功事件
            //若是为存量视频设置封面,则可以直接从此步骤开始提交截图任务
            submitSnapshotJob(vodClient,videoId);

            //获取到视频截图成功事件,判断截图类型,取得需要的图片URL
            JSONObject callBackMessage = new JSONObject();  //此处替换为回调服务收到的message
            String snapshotType = callBackMessage.getJSONObject("UserData").getJSONObject("Extend").getString("SnapshotType");
            if("FirstFrame".equals(snapshotType)){

                //这里的截图路径逻辑需要根据您自行定义的截图路径逻辑来替换
                String coverUrl = callBackMessage.getJSONArray("SnapshotInfos").getJSONObject(0).getString("SnapshotRegular").replace("{SnapshotCount}","00001");
                //修改视频封面
                updateVideoInfo(vodClient,videoId,coverUrl);
            }

            //场景二:无回调服务 或 MNS
            //若是为新上传的视频设置封面,则视频上传后,轮询视频状态
            String videoStatus = "";
            while(!"Normal".equals(videoStatus)){
                videoStatus = getVideoInfo(vodClient,videoId);
                Thread.sleep(1000);
            }

            //若是为存量视频设置封面,则可以直接从此步骤开始提交截图任务
            submitSnapshotJob(vodClient,videoId);

            //轮询截图结果
            String coverUrl = "";
            while(StringUtils.isBlank(coverUrl)){
                coverUrl = listSnapshots(vodClient,videoId);
                Thread.sleep(1000);
            }

            //修改视频封面
            updateVideoInfo(vodClient,videoId,coverUrl);
        }catch (Exception e){

        }
    }

    /**
     * 提交截图任务
     */
    public static SubmitSnapshotJobResponse submitSnapshotJob(DefaultAcsClient vodClient, String vid) throws ClientException {
        SubmitSnapshotJobRequest request = new SubmitSnapshotJobRequest();
        request.setVideoId(vid);
        request.setSnapshotTemplateId("1f27a7f*********70eba2756");
        //自定义透传参数,回调时可用,非必须,用于区分封面首帧截图
        request.setUserData("{\"Extend\":{\"SnapshotType\":\"FirstFrame\",\"VideoId\":\"a42bf540********33b79f0102\"}}");

        return vodClient.getAcsResponse(request);
    }

    /**
     * 修改视频封面
     */
    public static UpdateVideoInfoResponse updateVideoInfo(DefaultAcsClient vodClient, String vid, String coverUrl) throws ClientException {
        UpdateVideoInfoRequest request = new UpdateVideoInfoRequest();
        request.setVideoId(vid);
        //设置首帧封面时,CoverURL为首帧截图任务成功后输出的图片地址
        request.setCoverURL(coverUrl);

        return vodClient.getAcsResponse(request);
    }

    /**
     * 初始化sdk实例
     */
    public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
        // 点播服务接入区域
        String regionId = "cn-shanghai";  
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);

        return client;
    }

    /**
     * 查询截图
     */
    public static String listSnapshots(DefaultAcsClient vodClient, String vid) throws ClientException {
        ListSnapshotsRequest request = new ListSnapshotsRequest();
        request.setVideoId(vid);
        request.setSnapshotType("NormalSnapshot");

        ListSnapshotsResponse response = vodClient.getAcsResponse(request);
        String coverUrl = "";
        System.out.println("RequestId is:" + response.getRequestId());
        try{
            coverUrl = response.getMediaSnapshot().getSnapshots().get(0).getUrl();
            System.out.println("SnapshotUrl is:" + response.getMediaSnapshot().getSnapshots().get(0).getUrl());
        }catch (NullPointerException e){

        }
        return coverUrl;
    }

    /**
     * 查询单个视频
     */
    public static String getVideoInfo(DefaultAcsClient vodClient, String vid) throws ClientException {
        GetVideoInfoRequest request = new GetVideoInfoRequest();
        request.setVideoId(vid);

        GetVideoInfoResponse response = vodClient.getAcsResponse(request);
        System.out.println("RequestId is:" + response.getRequestId());
        String videoStatus = "";
        try{
            videoStatus = response.getVideo().getStatus();
            System.out.println("Video Status is:" + response.getVideo().getStatus());
        }catch (NullPointerException e){

        }

        return videoStatus;
    }
}

步骤三:(可选)预热视频资源

通过视频点播的预热功能,将视频资源提前缓存到CDN节点上,用户请求播放视频时,可以直接从CDN节点获取到最新的资源,无需再回源站获取,从而提升用户请求播放的响应速度,有利于播放器预加载的实现。

说明

由于刷新预热有一定的回源流量成本,可根据视频热度进行预热,将视频主动预热在阿里云各个节点上。

控制台方式配置

  1. 登录视频点播控制台

  2. 在左侧导航栏选择配置管理 > 分发加速配置 > 刷新预热,进入到刷新预热页面。

  3. 刷新缓存页签,配置预热信息。

    • 操作类型:选择预热

    • 刷新类型:固定为URL

    • URL:输入待预热的视频资源的URL。输入的URL必须带有http://https://。同一个账号每天最多预热500个URL,每次最多只能提交100条。

  4. 单击提交,完成预热配置。

OpenAPI方式配置

  1. 调用PreloadVodObjectCaches - 预热缓存接口实现预热视频资源。

步骤四:使用阿里云播放器播放视频

使用阿里云播放器通过UrlSource方式播放视频。