Spring Boot集成阿里云视频点播服务的过程记录

阿里云视频点播

  • 效果预览
  • 视频点播
    • 视频点播概述
    • 功能
    • 优势
    • 流程
  • 环境准备
    • 开通视频点播
    • 创建RAM用户并授权
  • 上传SDK
    • 上传流程
    • 下载上传SDK
    • 安装上传SDK
    • 集成Java上传SDK
    • 异常说明
    • 音视频上传
  • 服务端SDK
    • 添加服务端SDK依赖
    • 初始化
    • 音视频播放
      • 获取视频播放地址
      • 获取视频播放凭证
  • 播放器SDK
    • 播放器SDK
    • 集成视频播放器
    • 完整示例
    • Vid+PlayAuth播放(推荐)
    • 视频加密
    • 播放加密视频
  • Spring Boot集成视频点播服务
    • 配置application.properties
    • ConstantVod常量类
    • AliyunVodUtils工具类
    • Controller
    • Service
    • 前端API
    • 前端Vue页面
    • 功能测试

效果预览

在对接阿里云视频点播服务时,踩了不少的坑。特此记录阿里云视频点播服务的相关使用。

同时使用Spring Boot集成阿里云视频点播服务,对接其上传SDK、服务端SDK、播放器SDK,最终完成如下Demo演示。

视频点播

视频点播概述

视频点播(ApsaraVideo VoD,简称VoD)是集视频采集、编辑、上传、媒体资源管理、自动化转码处理(窄带高清™)、视频审核分析、分发加速于一体的一站式音视频点播解决方案。

产品地址:https://www.aliyun.com/product/vod

功能

支持多种SDK,极大减少开发时间

1.短视频录制播放SDK

集音视频拍摄、特效编辑、本地转码、高速上传、自动化转码处理、 媒体资源管理、分发加速、播放于一体的完整短视频解决方案。

2.播放器SDK

Web端(HTML5)、移动端(Android\iOS\Flutter)和桌面端(Windows\macOS)的标准播放器SDK,并支持客户自定义开发。

3.上传SDK

提供服务端、Web端、移动端等多种版本SDK,全面适配各个主流平台和运行环境。

优势

强大的安全机制

1.视频加密

支持私有协议和HLS标准加密方案,加密转码解密播放全面保护视频安全

2.防盗链机制

设置防盗链的Refer黑白名单和IP黑白名单,防止恶意的访问

3.播放鉴权

在阿里云AK安全认证基础上的二次鉴权,对每个渠道的播放请求进行身份验证

应用场景:
视频网站、短视频、在线教育、广电传媒

流程

视频点播实现音视频上传、存储、处理和播放的整体流程如下:
Spring Boot集成阿里云视频点播服务的过程记录_第1张图片

用户获取上传授权。

VOD下发上传地址和凭证及VideoId。

用户上传视频并保存视频ID(VideoId)。

用户服务端获取播放授权。

用户客户端请求播放地址与凭证,VOD下发播放地址与带时效的播放凭证。

用户服务端将播放凭证下发给客户端完成视频播放。

环境准备

开通视频点播

Spring Boot集成阿里云视频点播服务的过程记录_第2张图片

创建RAM用户并授权

地址:https://ram.console.aliyun.com/users/new

访问方式区域勾选OpenAPI调用访问
Spring Boot集成阿里云视频点播服务的过程记录_第3张图片
自动生成该RAM用户的AccessKey(AccessKey ID + AccessKey Secret)
Spring Boot集成阿里云视频点播服务的过程记录_第4张图片
返回用户界面,为其添加权限
Spring Boot集成阿里云视频点播服务的过程记录_第5张图片
输入框中输入vod,将筛选出的权限策略都单击选择
Spring Boot集成阿里云视频点播服务的过程记录_第6张图片

上传SDK

上传SDK提供上传媒体文件到点播存储的开发工具包,是视频点播端到端服务的重要一环。通过上传SDK,可以快捷上传视频、音频、图片、字幕等各种媒体文件到点播存储。上传SDK同时提供服务端和移动客户端等多种版本SDK,全面适配各个主流平台和运行环境。

文档地址:https://help.aliyun.com/document_detail/52199.html

上传流程

服务端上传SDK封装了获取上传地址和凭证的逻辑和OSS上传逻辑,只需简单配置即可进行上传。
Spring Boot集成阿里云视频点播服务的过程记录_第7张图片

1.用户在上传应用服务集成点播服务端上传SDK并完成上传设置,如:AK信息、文件地址、存储地址、媒资管理、转码设置、上传控制等。

2.上传应用服务器使用点播服务端上传SDK调用上传地址和凭证相关接口获取上传地址、上传凭证及媒资信息。

3.点播服务在请求结果中返回上传地址(UploadAddress)、上传凭证(UploadAuth)和媒体ID等信息。

4.上传应用服务器通过点播服务端上传SDK封装好的OSS上传逻辑开始上传。

5.OSS服务返回上传结果

下载上传SDK

https://help.aliyun.com/document_detail/51992.htm
Spring Boot集成阿里云视频点播服务的过程记录_第8张图片

安装上传SDK

下载上传SDK后解压
在这里插入图片描述

lib:存放Java上传SDK所需要的jar包。

sample:存放Java上传SDK的示例代码。

命令行进入lib目录,执行如下安装命令

>mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-sdk-vod-upload -Dversion=1.4.11 -Dpackaging=jar -Dfile=aliyun-java-vod-upload-1.4.14.jar
C:\Users\Administrator\Downloads\Compressed\VODUploadDemo-java-1.4.14\VODUploadDemo-java-1.4.14\lib>mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-sdk-vod-upload -Dversion=1.4.11 -Dpackaging=jar -Dfile=aliyun-java-vod-upload-1.4.14.jar
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom ---
[INFO] Installing C:\Users\Administrator\Downloads\Compressed\VODUploadDemo-java-1.4.14\VODUploadDemo-java-1.4.14\lib\aliyun-java-vod-upload-1.4.14.jar to D:\Development\Maven\repository\com\aliyun\aliyun-sdk-vod-upload\1.4.11\aliyun-sdk-vod-upload-1.4.11.jar
[INFO] Installing C:\Users\Administrator\AppData\Local\Temp\mvninstall5580539659618723518.pom to D:\Development\Maven\repository\com\aliyun\aliyun-sdk-vod-upload\1.4.11\aliyun-sdk-vod-upload-1.4.11.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.714 s
[INFO] Finished at: 2022-09-18T18:56:24+08:00
[INFO] ------------------------------------------------------------------------

集成Java上传SDK

添加阿里云Java SDK、OSS SDK、视频点播服务端SDK、视频点播服务端上传SDK等依赖。

   <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
        <version>4.5.1</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun.oss</groupId>
        <artifactId>aliyun-sdk-oss</artifactId>
        <version>3.10.2</version>
    </dependency>
     <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-vod</artifactId>
        <version>2.15.11</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.28</version>
    </dependency>
    
    <!-- 引入安装的上传SDK依赖 -->
     <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-sdk-vod-upload</artifactId>
        <version>1.4.11</version>
     </dependency>

异常说明

在上传过程中遇到此异常,经查询发现是由于SDK版本差异造成的。

com.aliyuncs.vod.model.v20170321.CreateUploadVideoRequest.setIP(Ljava/lang/String;)V

直接使用官方示例给出的版本号即可。

Spring Boot集成阿里云视频点播服务的过程记录_第9张图片
原本使用服务端SDK文档描述中的版本依赖
Spring Boot集成阿里云视频点播服务的过程记录_第10张图片

音视频上传

音视频上传支持多种上传方式,这里使用上传本地文件方式,该方式使用分片上传,并支持断点续传。

    /**
     * 本地文件上传接口
     */
private static void testUploadVideo(String accessKeyId, String accessKeySecret, String title, String fileName) {
        UploadVideoRequest request = new UploadVideoRequest(accessKeyId, accessKeySecret, title, fileName);
        /* 可指定分片上传时每个分片的大小,默认为2M字节 */
        request.setPartSize(1 * 512 * 1024L);
        /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/
        request.setTaskNum(2);
    /* 是否开启断点续传, 默认断点续传功能关闭。当网络不稳定或者程序崩溃时,再次发起相同上传请求,可以继续未完成的上传任务,适用于超时3000秒仍不能上传完成的大文件。
    注意:断点续传开启后,会在上传过程中将上传位置写入本地磁盘文件,影响文件上传速度,请您根据实际情况选择是否开启*/
        //request.setEnableCheckpoint(false);
        /* OSS慢请求日志打印超时时间,是指每个分片上传时间超过该阈值时会打印debug日志,如果想屏蔽此日志,请调整该阈值。单位:毫秒,默认为300000毫秒*/
        //request.setSlowRequestsThreshold(300000L);
        /* 可指定每个分片慢请求时打印日志的时间阈值,默认为300s*/
        //request.setSlowRequestsThreshold(300000L);
        /* 是否显示水印(可选),指定模板组ID时,根据模板组配置确定是否显示水印*/
        //request.setIsShowWaterMark(true);
        /* 自定义消息回调设置(可选) */
        // request.setUserData("{\"Extend\":{\"test\":\"www\",\"localId\":\"xxxx\"},\"MessageCallback\":{\"CallbackURL\":\"http://demo.example.com\"}}");
        /* 视频分类ID(可选) */
        request.setCateId(1000440308L);
        /* 视频标签,多个用逗号分隔(可选) */
        //request.setTags("标签1,标签2");
        /* 视频描述(可选)*/
        //request.setDescription("视频描述");
        /* 封面图片(可选)*/
        //request.setCoverURL("http://cover.example.com/image_01.jpg");
        /* 模板组ID(可选)*/
        //request.setTemplateGroupId("8c4792cbc8694e7084fd5330e5****");
        /* 工作流ID(可选)*/
        //request.setWorkflowId("d4430d07361f0*be1339577859b0****");
        /* 存储区域(可选)*/
        //request.setStorageLocation("in-201703232118266-5sejd****.oss-cn-shanghai.aliyuncs.com");
        /* 开启默认上传进度回调 */
        //request.setPrintProgress(false);
        /* 设置自定义上传进度回调(必须继承 VoDProgressListener)*/
        /*默认关闭。如果开启了这个功能,上传过程中服务端会在日志中返回上传详情。如果不需要接收此消息,需关闭此功能*/
        //request.setProgressListener(new PutObjectProgressListener());
        /* 设置您实现的生成STS信息的接口实现类*/
        // request.setVoDRefreshSTSTokenListener(new RefreshSTSTokenImpl());
        /* 设置应用ID*/
        //request.setAppId("app-100****");
        /* 点播服务接入点 */
        //request.setApiRegionId("cn-shanghai");
        /* ECS部署区域*/
        // request.setEcsRegionId("cn-shanghai");
        UploadVideoImpl uploader = new UploadVideoImpl();
        UploadVideoResponse response = uploader.uploadVideo(request);
        System.out.print("RequestId=" + response.getRequestId() + "\n");  //请求视频点播服务的请求ID
        if (response.isSuccess()) {
            System.out.print("VideoId=" + response.getVideoId() + "\n");
        } else {
            /* 如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 */
            System.out.print("VideoId=" + response.getVideoId() + "\n");
            System.out.print("ErrorCode=" + response.getCode() + "\n");
            System.out.print("ErrorMessage=" + response.getMessage() + "\n");
        }
    }
    //账号AK信息请填写(必选)
    private static String accessKeyId = "XXX";
    //账号AK信息请填写(必选)
    private static String accessKeySecret = "XXX";

    public static void main(String[] args) {
        // 视频标题(必选)
        String title = "测试标题";
        // 本地文件上传和文件流上传时,文件名称为上传文件绝对路径,如:/User/sample/文件名称.mp4 (必选)
        // 任何上传方式文件名必须包含扩展名
        String fileName = "D:\\test.mp4";
        // 本地文件上传
        testUploadVideo(accessKeyId, accessKeySecret, title, fileName);
    }

上传成功后,到视频点播控制台查看,地址:https://vod.console.aliyun.com/

Spring Boot集成阿里云视频点播服务的过程记录_第11张图片

服务端SDK

基于服务端SDK编写代码来调用点播API。视频点播服务端SDK提供两种初始化方式,这里使用AccessKey初始化。

文档地址:https://help.aliyun.com/document_detail/57716.html

添加服务端SDK依赖

<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-core</artifactId>
  <version>4.6.0</version>
</dependency>
<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-vod</artifactId>
  <version>2.16.5</version>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.83</version>
</dependency>
<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-kms</artifactId>
  <version>2.10.1</version>
</dependency>

初始化

Java SDK可通过AccessKey或STS Security Token初始化,这里使用AccessKey初始化。

调用服务端接口需要使用AccessKey完成身份验证,AccessKey包括AccessKey ID和AccessKey Secret,也就是上面环境准备中的创建RAM用户并授权步骤

AccessKey ID:用于标识用户

AccessKey Secret:用于验证用户的密钥。AccessKey Secret必须保密
public class AliyunVodUtils {

    private static String accessKeyId = "";

    private static String accessKeySecret = "";

    public static DefaultAcsClient initVodClient() {
        String regionId = "cn-shanghai";  // 点播服务接入区域
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }
}

音视频播放

获取视频播放地址

调用GetPlayInfo接口,完成获取视频播放地址功能。

    /**
     * 获取视频播放地址
     */
    @Test
    public void testGetPlayInfo() {
        //初始化客户端、请求对象和相应对象
        DefaultAcsClient client = AliyunVodUtils.initVodClient();
        GetPlayInfoRequest request = new GetPlayInfoRequest();
        GetPlayInfoResponse response = new GetPlayInfoResponse();

        try {
            request.setVideoId("446063fe379e45c7a582b36380c04c24");
            response = client.getAcsResponse(request);
            List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();

            // 播放地址
            for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
                System.out.print("PlayInfo.PlayURL = " + playInfo.getPlayURL() + "\n");
            }
            //Base信息
            System.out.print("VideoBase.Title = " + response.getVideoBase().getTitle() + "\n");
        } catch (Exception e) {
            System.out.print("ErrorMessage = " + e.getLocalizedMessage());
        }
        System.out.print("RequestId = " + response.getRequestId() + "\n");
    }

相应结果如下,得到的地址可以直接访问

PlayInfo.PlayURL = https://outin-5ebb3a9bea2511ebbc8400163e00b174.oss-cn-shanghai.aliyuncs.com/sv/1cb4e5fe-1835105eb00/1cb4e5fe-1835105eb00.mp4?Expires=1663599729&OSSAccessKeyId=LTAI4FfD63zoqnm6ckiBFfXZ&Signature=KNX7Ayydteovt6HvJPwJFl%2FDocU%3D
VideoBase.Title = test
RequestId = 5B70A878-CCEB-573F-9837-7B40EE13D588

获取视频播放凭证

调用GetVideoPlayAuth接口,完成获取视频播放凭证功能。

    /**
     * 获取视频播放凭证
     */
    @Test
    public void testGetVideoPlayAuth() {
        //初始化客户端、请求对象和相应对象
        DefaultAcsClient client = AliyunVodUtils.initVodClient();
        GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
        GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse();

        try {
            request.setVideoId("446063fe379e45c7a582b36380c04c24");
            response = client.getAcsResponse(request);

            // 播放凭证
            System.out.print("PlayAuth = " + response.getPlayAuth() + "\n");
            // VideoMeta信息
            System.out.print("VideoMeta.Title = " + response.getVideoMeta().getTitle() + "\n");
        } catch (Exception e) {
            System.out.print("ErrorMessage = " + e.getLocalizedMessage());
        }
        System.out.print("RequestId = " + response.getRequestId() + "\n");
    }

响应结果如下

PlayAuth = eyJTZWN1cml0eVRva2VuIjoiQ0FJU2h3TjFxNkZ0NUIyeWZTaklyNWYzR29qZjI1c1QwNmJhY0VuMmxHUXNRZmNmbS9UemtUejJJSDVFZW5OcUF1d2F2Lzh5bEd0VDZQZ1psck1xRjhjZEhCQ1ZNSk1zdjhzS29WLzZKcExGc3QySjZyOEpqc1Zpc1o1SjFrYXBzdlhKYXNEVkVmbDJFNVhFTWlJUi8wMGU2TC8rY2lyWXBUWEhWYlNDbFo5Z2FQa09Rd0M4ZGtBb0xkeEtKd3hrMnQxNFVtWFdPYVNDUHdMU2htUEJMVXhtdldnR2wyUnp1NHV5M3ZPZDVoZlpwMXI4eE80YXhlTDBQb1AyVjgxbExacGxlc3FwM0k0U2M3YmFnaFpVNGdscjhxbHg3c3BCNVN5Vmt0eVdHVWhKL3phTElvaXQ3TnBqZmlCMGVvUUFQb3BGcC9YNmp2QWF3UExVbTliWXhncGhCOFIrWGo3RFpZYXV4N0d6ZW9XVE84MCthS3p3TmxuVXo5bUxMZU9WaVE0L1ptOEJQdzQ0RUxoSWFGMElVRUJ5RUd5RWNQSDZwd3FTUFZqK0U1TG9pdjltamNCSHFIeno1c2VQS2xTMVJMR1U3RDBWSUpkVWJUbHphVTVJaHphNkx2TlhLRkVjS0FnNVdlMlBNYXgzYlFGRHI1M3ZzVGJiWHpaYjBtcHR1UG56ZDEwMVJuWGh4eUdWR29BQnNiSTJXUGRIdk5zaExaMWd3WUVVYzEwQkkrWkxKa1BWVElEUmord3VXM1dta3lRYS9rR2Z5NlE3Vk1oSkpTRFdFSEhubEtTLzZLUG1VM3dQNFZEbmNLT29VQ3N5VEdUQUhSb0RsOWJ4NkpDTjExanZGRTFMTGhqYW9KVFhoTkJRQjRYVFBYa1lWNmgvSkE2L05pY2w4U2pVS29uUTZXMHV1UStWS2xRMmhudz0iLCJBdXRoSW5mbyI6IntcIkNJXCI6XCJZRDNGblAzMDVIQjdkdDUzVlJlenFvTUJKNUh0cG5CSGJ3am9OSUh3MmVhTFlSU21oelBmdkVQdklBb2JjRjBpT1FlQjFaREdRblBGQVpjUSt2S1dXcE9JL1k1aDNhSXJ1STBBbkVzWnlQND1cIixcIkNhbGxlclwiOlwiV2VlTW9vQTYzQUhTSFlwa2VPNlZneUF5VkNxSVkyTklyUGhiSVhCYWhjMD1cIixcIkV4cGlyZVRpbWVcIjpcIjIwMjItMDktMTlUMTQ6MDY6MThaXCIsXCJNZWRpYUlkXCI6XCI0NDYwNjNmZTM3OWU0NWM3YTU4MmIzNjM4MGMwNGMyNFwiLFwiU2lnbmF0dXJlXCI6XCJzSGFUU3lxZlJydCsrTFFkQ1duQnRLeldidDg9XCJ9IiwiVmlkZW9NZXRhIjp7IlN0YXR1cyI6Ik5vcm1hbCIsIlZpZGVvSWQiOiI0NDYwNjNmZTM3OWU0NWM3YTU4MmIzNjM4MGMwNGMyNCIsIlRpdGxlIjoidGVzdCIsIkNvdmVyVVJMIjoiaHR0cDovL291dGluLTVlYmIzYTliZWEyNTExZWJiYzg0MDAxNjNlMDBiMTc0Lm9zcy1jbi1zaGFuZ2hhaS5hbGl5dW5jcy5jb20vNDQ2MDYzZmUzNzllNDVjN2E1ODJiMzYzODBjMDRjMjQvc25hcHNob3RzLzNjYTQ4MTQ1Y2YzNzRlYjRhNzRkNTVkZWEzZjNhNjRmLTAwMDAxLmpwZz9FeHBpcmVzPTE2NjM1OTk4NzgmT1NTQWNjZXNzS2V5SWQ9TFRBSTRGZkQ2M3pvcW5tNmNraUJGZlhaJlNpZ25hdHVyZT15cEV6Q3FnTVhWZEVWOU1pcUpXWGFkdDZPcnMlM0QiLCJEdXJhdGlvbiI6MzYuODF9LCJBY2Nlc3NLZXlJZCI6IlNUUy5OVEJRMms2RDJkZDFyb0dwZHlNeDN0MVhzIiwiQWNjZXNzS2V5U2VjcmV0IjoiREhUOGlnalJSRXA2R3B0Mmp4bTE4VlB6V0NjOUY5OGVRMk13akRBekZwMTYiLCJSZWdpb24iOiJjbi1zaGFuZ2hhaSIsIkN1c3RvbWVySWQiOjE0MDAxNDk1MDQ5NzU4NDN9
VideoMeta.Title = test
RequestId = D8FC312A-E80C-5C9F-B7F1-D79182A6928E

播放器SDK

文档地址:https://help.aliyun.com/document_detail/124933.html

阿里云播放器SDK(ApsaraVideo Player SDK,简称播放器SDK)是阿里云自研的全端音视频播放工具,为音视频播放提供稳定、流畅、丰富的服务。配合视频点播服务,播放器SDK能够为客户提供云端协同的优异播放体验,以及多场景的解决方案,满足客户的业务需求。播放器SDK具有集成便捷、全端覆盖、播放性能优秀等特点,助力业务快速腾飞。

若上面获取的视频地址是经过加密处理的,是不能直接播放,需要配合阿里云播放器进行播放。

播放器SDK

播放器SDK地址:https://help.aliyun.com/document_detail/51992.htm
Spring Boot集成阿里云视频点播服务的过程记录_第12张图片
这里使用Web播放器,直接访问https://player.alicdn.com/aliplayer/index.html进行效果预览与在线配置
Spring Boot集成阿里云视频点播服务的过程记录_第13张图片

集成视频播放器

Web播放器不依赖于任何的前端js库,只需要在页面中引用js文件,就可以进行初始化。

引入css文件与js文件

<head>
  <link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.12.1/skins/default/aliplayer-min.css" />  //(可选)如果您的使用场景需要用到H5模式的播放器,则需引用此css文件。
  <script charset="utf-8" type="text/javascript" src="https://g.alicdn.com/de/prismplayer/2.12.1/aliplayer-min.js"></script>  //(必须)引入js文件。
</head>

提供挂载元素

 <div id="J_prismPlayer"></div>

初始化视频播放器

Web播放器SDK支持5种点播播放方式,包括:URL播放、Vid+PlayAuth播放(推荐)、STS播放、MPS播放、加密播放。

Web播放器SDK支持2种直播播放方式,URL播放和加密播放。
var player = new Aliplayer({
        id: 'J_prismPlayer',
        source: '<your play URL>',//播放地址,可以是第三方点播地址,或阿里云点播服务中的播放地址。
      },function(player){
        console.log('The player is created.')
     });

完整示例

使用URL播放方式播放点播视频,需要将播放器的source属性设置为播放地址。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 阿里云视频播放器样式 -->
    <link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.12.1/skins/default/aliplayer-min.css"/>
    <!-- 阿里云视频播放器脚本 -->
    <script charset="utf-8" type="text/javascript" src="https://g.alicdn.com/de/prismplayer/2.12.1/aliplayer-min.js"></script>
</head>
<body>
<!-- 定义播放器dom -->
<div style="width:700px;height:400px;margin: auto" id="J_prismPlayer"></div>

<script>
    var player = new Aliplayer({
        id: 'J_prismPlayer',
        //播放地址,可以是第三方点播地址,或阿里云点播服务中的播放地址。
        source: 'https://outin-5ebb3a9bea2511ebbc8400163e00b174.oss-cn-shanghai.aliyuncs.com/sv/1cb4e5fe-1835105eb00/1cb4e5fe-1835105eb00.mp4?Expires=1663602152&OSSAccessKeyId=LTAI4FfD63zoqnm6ckiBFfXZ&Signature=9%2Fl2NhGaT4paUCIMh4Z1zPGFJvM%3D',
    },function(player){
        console.log('The player is created.')
    });
</script>
</body>
</html>

结果如下
Spring Boot集成阿里云视频点播服务的过程记录_第14张图片

Vid+PlayAuth播放(推荐)

Vid+PlayAuth播放是阿里云播放器推荐的播放方式,提供音视频ID与对应视频播放授权码即可播放,更安全。

var player = new Aliplayer({
           id: 'J_prismPlayer',
           width: '100%',
           vid : '<your video ID>',//必选参数。音视频ID。示例:1e067a2831b641db90d570b6480f****。
           playauth : '<your PlayAuth>',//必选参数。音视频播放凭证。
         },function(player){
           console.log('The player is created.')
        });

视频加密

媒体管理配置中添加一个转码模板组,在高级参数开启视频加密
Spring Boot集成阿里云视频点播服务的过程记录_第15张图片
将未加密视频进行加密,然后就可以在视频对应的管理中看到加密视频
Spring Boot集成阿里云视频点播服务的过程记录_第16张图片

播放加密视频

使用Vid+PlayAuth播放方式,使用视频ID加上述获取视频播放凭证的到的凭证进行播放,结果产生异常如下:
Spring Boot集成阿里云视频点播服务的过程记录_第17张图片
Spring Boot集成阿里云视频点播服务的过程记录_第18张图片
网上资料很少,说将存储管理中的私有权限改成公共权限,但个人认为既然通过授权码播放视频,那设置公共读完全没必要,但折腾很久,忍不住尝试了下,结果呵呵,不是这个原因。

Spring Boot集成阿里云视频点播服务的过程记录_第19张图片
最终有效解决方案
删除已上传视频,使用上述音视频上传接口重新上传视频,不过需要指定模板组ID,上传文件后自动进行视频处理。

  /* 模板组ID(可选)*/
request.setTemplateGroupId("17bf1c9688cb1d52c23e56dcfd2cb6fa");

然后再设置视频ID,设置获取的视频播放凭证进行播放。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 阿里云视频播放器样式 -->
    <link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.12.1/skins/default/aliplayer-min.css"/>
    <!-- 阿里云视频播放器脚本 -->
    <script charset="utf-8" type="text/javascript" src="https://g.alicdn.com/de/prismplayer/2.12.1/aliplayer-min.js"></script>
</head>
<body>
<!-- 定义播放器dom -->
<div class="prism-player" style="width:700px;height:400px;margin: auto" id="J_prismPlayer"></div>

<script>
    var player = new Aliplayer({
        id: 'J_prismPlayer',
        autoplay: false, // 自动播放
        encryptType: '1', //当播放私有加密流时需要设置本参数值为1。其它情况无需设置。
        //播放地址,可以是第三方点播地址,或阿里云点播服务中的播放地址。
        vid : 'b3568a51aca847f791dab47ccb8e7bbe',//必选参数。音视频ID。示例:1e067a2831b641db90d570b6480f****。
        playauth  : 'eyJTZWN1cml0eVRva2VuIjoiQ0FJU2h3TjFxNkZ0NUIyeWZTaklyNWI1TVkzVHZMeExnWnVGYjFYZjNWRmhlZnQraEtEQzFUejJJSDVFZW5OcUF1d2F2Lzh5bEd0VDZQZ1psck1xRjhjZEhCQ1ZNSk1zdjhzS29WLzZKcExGc3QySjZyOEpqc1ZOcXFSNDFVYXBzdlhKYXNEVkVmbDJFNVhFTWlJUi8wMGU2TC8rY2lyWXBUWEhWYlNDbFo5Z2FQa09Rd0M4ZGtBb0xkeEtKd3hrMnQxNFVtWFdPYVNDUHdMU2htUEJMVXhtdldnR2wyUnp1NHV5M3ZPZDVoZlpwMXI4eE80YXhlTDBQb1AyVjgxbExacGxlc3FwM0k0U2M3YmFnaFpVNGdscjhxbHg3c3BCNVN5Vmt0eVdHVWhKL3phTElvaXQ3TnBqZmlCMGVvUUFQb3BGcC9YNmp2QWF3UExVbTliWXhncGhCOFIrWGo3RFpZYXV4N0d6ZW9XVE84MCthS3p3TmxuVXo5bUxMZU9WaVE0L1ptOEJQdzQ0RUxoSWFGMElVRUJ5RUd5RWNQSDZwd3FTUFZqK0U1TG9pdjltamNCSHFIeno1c2VQS2xTMVJMR1U3RDBWSUpkVWJUbHphVTVJaHphNkx2TlhLRkVjS0FnNVdlMlBNYXgzYlFGRHI1M3ZzVGJiWHpaYjBtcHR1UG56ZDEwMVJuWGh4eUdWR29BQkFrS0cxZTMybTU2M0NKUzJmaUJ0RU1jdDVPQzN2VHlSQTVEMHphaXA2ZDN5d2J0U0dweFl1VHZLcDE3STREU2RPSy81bUZOQmVZZTZoenhMNzIvbXdjanNmUVZWTHo3Zk9lVDR4enpLY0JkM3NWUXB4VjUvS1p2ZDVHdlBzWFNQc0pobUc0N056L2dhdlAxUTQzMWk3ckxYOHNmRVM5Z0lHcUJoOVFXdDVwMD0iLCJBdXRoSW5mbyI6IntcIkNJXCI6XCJxbjdqTUJzSDNJR05SdVNUUFhuNzhpMEFmcnlxMnJpd3VMQmFnTS8ydnVFLzQyL250dWdDT0UxUU5EdnNPVnRXTDJ4dFAxU0JUYTdrcmFYSjI0UVkwL0o1VlVYSjBrd1pVb3JYNWNiUHR2az1cIixcIkNhbGxlclwiOlwicER6c1pmaFJ3TGpNL0xzWXU4d3pCQXcrdEs0NVBzRTBkOXBJUzVmazBkaz1cIixcIkV4cGlyZVRpbWVcIjpcIjIwMjItMDktMjFUMTQ6MDc6MjlaXCIsXCJNZWRpYUlkXCI6XCJiMzU2OGE1MWFjYTg0N2Y3OTFkYWI0N2NjYjhlN2JiZVwiLFwiU2lnbmF0dXJlXCI6XCJRUkg0cFpGZThqSmtuWnYzVU83Yi83UldUZ0E9XCJ9IiwiVmlkZW9NZXRhIjp7IlN0YXR1cyI6Ik5vcm1hbCIsIlZpZGVvSWQiOiJiMzU2OGE1MWFjYTg0N2Y3OTFkYWI0N2NjYjhlN2JiZSIsIlRpdGxlIjoi5rWL6K+V5qCH6aKYIiwiQ292ZXJVUkwiOiJodHRwOi8vb3V0aW4tNWViYjNhOWJlYTI1MTFlYmJjODQwMDE2M2UwMGIxNzQub3NzLWNuLXNoYW5naGFpLmFsaXl1bmNzLmNvbS9iMzU2OGE1MWFjYTg0N2Y3OTFkYWI0N2NjYjhlN2JiZS9zbmFwc2hvdHMvMzk0NmZlZjZmZjRlNDU1MWFlM2YyYjJiMWFkMWNhYTgtMDAwMDEuanBnP0V4cGlyZXM9MTY2Mzc2OTg0OSZPU1NBY2Nlc3NLZXlJZD1MVEFJNEZmRDYzem9xbm02Y2tpQkZmWFomU2lnbmF0dXJlPURUaVM1JTJGakxyeDFyJTJCdVpjUW1JWnh3VlRDSkElM0QiLCJEdXJhdGlvbiI6MzYuODF9LCJBY2Nlc3NLZXlJZCI6IlNUUy5OVUx6N2dRY2o2WW5tc245UTR1dFJrZWk3IiwiQWNjZXNzS2V5U2VjcmV0IjoiRTJEWldvQlhjODg2Q3ZxRWlmRUpvRWhGa1BLOXl2aDlyN05uNlJVeDZ3SnciLCJSZWdpb24iOiJjbi1zaGFuZ2hhaSIsIkN1c3RvbWVySWQiOjE0MDAxNDk1MDQ5NzU4NDN9',//必选参数。音视频播放凭证。
        // source: 'https://outin-5ebb3a9bea2511ebbc8400163e00b174.oss-cn-shanghai.aliyuncs.com/446063fe379e45c7a582b36380c04c24/dc105c86cb133303ad4eb6907672369f-ld-encrypt-stream.m3u8?Expires=1663604096&OSSAccessKeyId=LTAI4FfD63zoqnm6ckiBFfXZ&Signature=re%2BKCtXTgpfTYifg%2Fdum7GZ2m4o%3D'
    },function(player){
        console.log('The player is created.')
    });
</script>
</body>
</html>

Spring Boot集成阿里云视频点播服务的过程记录_第20张图片

Spring Boot集成视频点播服务

配置application.properties

# 阿里云vod
aliyun.vod.accessKeyId=
aliyun.vod.accessKeySecret=

# 最大上传单个文件大小:默认1M
spring.servlet.multipart.max-file-size=1024MB
# 最大置总上传的数据大小 :默认10M
spring.servlet.multipart.max-request-size=1024MB

ConstantVod常量类

@Component
//@PropertySource("classpath:application.properties")
public class ConstantVod implements InitializingBean {

    @Value("${aliyun.vod.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.vod.accessKeySecret}")
    private String accessKeySecret;

    public static String ACCESS_KEY_SECRET;
    public static String ACCESS_KEY_ID;

    @Override
    public void afterPropertiesSet() {
        ACCESS_KEY_ID = accessKeyId;
        ACCESS_KEY_SECRET = accessKeySecret;
    }
}

AliyunVodUtils工具类

public class AliyunVodUtils {

    /**
     * 初始化
     */
    public static DefaultAcsClient initVodClient() {
        String regionId = "cn-shanghai";  // 点播服务接入区域
        DefaultProfile profile = DefaultProfile.getProfile(regionId, ConstantVod.ACCESS_KEY_ID, ConstantVod.ACCESS_KEY_SECRET);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }
}

Controller

@RestController
@RequestMapping("/video")
public class VodController {

    @Autowired
    private VodService vodService;

    /**
     * 上传视频到阿里云
     */
    @PostMapping("uploadVideo")
    public String uploadVideo(MultipartFile file) {
        // 返回上传视频id
        String videoId = vodService.uploadVideo(file);
        return videoId;
    }

    /**
     * 根据视频id删除视频
     */
    @DeleteMapping("removeOneVideo/{id}")
    public String removeOneVideo(@PathVariable String id) {
        vodService.removeOneVideo(id);
        return "OK";
    }

    /**
     * 删除多个视频
     */
    @DeleteMapping("removeMoreVideo")
    public String removeMoreVideo(@RequestParam("videoIdList") List<String> videoIdList) {
        vodService.removeMoreVideo(videoIdList);
        return "OK";
    }

    /**
     * 根据视频id获取视频凭证
     */
    @GetMapping("getPlayAuth/{id}")
    public String getPlayAuth(@PathVariable String id) {
        String playAuth = vodService.getPlayAuth(id);
        return playAuth;
    }
}

Service

public interface VodService {
    /**
     * 上传视频到阿里云
     */
    String uploadVideo(MultipartFile file);

    /**
     * 根据视频id删除视频
     */
    void removeOneVideo(String id);

    /**
     * 删除多个阿里云视频
     */
    void removeMoreVideo(List videoIdList);

    /**
     * 获取播放授权
     */
    String getPlayAuth(String id);
}
@Service
public class VodServiceImpl implements VodService {

    @Override
    public String uploadVideo(MultipartFile file) {

        try {
            //上传文件原始名称
            String fileName = file.getOriginalFilename();
            // 上传之后显示名称
            String title = fileName.substring(0, fileName.lastIndexOf("."));
            // 上传文件输入流
            InputStream inputStream = file.getInputStream();
            UploadStreamRequest request = new UploadStreamRequest(ConstantVod.ACCESS_KEY_ID, ConstantVod.ACCESS_KEY_SECRET, title, fileName, inputStream);

            UploadVideoImpl uploader = new UploadVideoImpl();
            UploadStreamResponse response = uploader.uploadStream(request);

            String videoId = null;
            if (response.isSuccess()) {
                videoId = response.getVideoId();
            } else {
                //如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因
                videoId = response.getVideoId();
            }
            return videoId;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    @Override
    public void removeOneVideo(String id) {
        try {
            //初始化对象
            DefaultAcsClient client = AliyunVodUtils.initVodClient();
            //创建删除视频request对象
            DeleteVideoRequest request = new DeleteVideoRequest();
            //向request设置视频id
            request.setVideoIds(id);
            //调用初始化对象的方法实现删除
            client.getAcsResponse(request);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("删除视频失败");
        }
    }

    @Override
    public void removeMoreVideo(List videoIdList) {
        try {
            //初始化对象
            DefaultAcsClient client = AliyunVodUtils.initVodClient();
            //创建删除视频request对象
            DeleteVideoRequest request = new DeleteVideoRequest();
            //videoIdList值转换成 1,2,3
            String videoIds = StringUtils.join(videoIdList.toArray(), ",");
            //向request设置视频id
            request.setVideoIds(videoIds);
            //调用初始化对象的方法实现删除
            client.getAcsResponse(request);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("删除视频失败");
        }
    }

    @Override
    public String getPlayAuth(String id) {
        try {
            //创建初始化对象
            DefaultAcsClient client = AliyunVodUtils.initVodClient();
            //创建获取凭证request和response对象
            GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
            //向request设置视频id
            request.setVideoId(id);
            //调用方法得到凭证
            GetVideoPlayAuthResponse response = client.getAcsResponse(request);
            String playAuth = response.getPlayAuth();
            return playAuth;
        } catch (Exception e) {
            throw new RuntimeException("获取凭证失败");
        }
    }
}

前端API

import request from '@/utils/request'

export default {

  removeOneVideo(id) {
    return request({
      url: '/video/removeOneVideo/' + id,
      method: 'delete'
    })
  },

  getPlayAuth(id) {
    return request({
      url: '/video/getPlayAuth/' + id,
      method: 'get',
    })
  },
}

前端Vue页面

<template>
  <div>
    <div style="text-align:center;margin-top: 10%">
      <el-row span="12">
        <el-upload
          class="upload-demo"
          ref="upload"
          action="http://localhost:8888/video/uploadVideo"
          :on-remove="handleRemove"
          :on-success="onSuccess"
          :file-list="fileList"
          :auto-upload="false"
        >
          <el-button slot="trigger" size="small" :disabled="disabled" type="primary">选取文件el-button>
          <el-button style="margin-left: 10px;" :disabled="disabled" size="small" type="success" @click="submitUpload">
            上传到服务器
          el-button>
          <el-button  size="small" :disabled="disabled" type="primary" @click="getPlayAuth">获取播放凭证
          el-button>
        el-upload>
      el-row>
    div>

    <div>
      
      <div style="width:30%;height:300px;margin:auto;" id="J_prismPlayer">div>
      <remote-css>remote-css>
      <remote-js>remote-js>
    div>
  div>
template>
<script>
import video from '@/api/video'

export default {
  name: 'Index',
  components: {
    'remote-css': {
      render(createElement) {
        return createElement('link', {
          attrs: { rel: 'stylesheet', href: "https://g.alicdn.com/de/prismplayer/2.12.1/skins/default/aliplayer-min.css"}
        })
      },
    },
    'remote-js': {
      render(createElement) {
        return createElement('script', {
          attrs: { type: 'text/javascript', src: "https://g.alicdn.com/de/prismplayer/2.12.1/aliplayer-min.js" }
        })
      },
    }
  },
  data() {
    return {
      videoSourceId: '',
      playauth:'',
      fileList: [],
      disabled: false
    }
  },

  methods: {
    /**
     * 上传
     */
    submitUpload() {
      this.disabled = true
      this.$refs.upload.submit()
    },
    onSuccess(res, file, fileList) {
      this.videoSourceId = res
      this.$message({
        type: 'success',
        message: '上传成功'
      })
      this.disabled = false
    },
    /**
     * 删除
     * @param file
     * @param fileList
     */
    handleRemove(file, fileList) {
      video.removeOneVideo(this.videoSourceId)
        .then(res => {
          this.$message({
            type: 'success',
            message: '删除视频成功'
          })
          this.fileList = []
          this.videoSourceId = ''
        })
    },
    /**
     * 获取播放凭证
     */
    getPlayAuth(){
      video.getPlayAuth(this.videoSourceId)
        .then(res => {
          console.log(res)
          this.$message({
            type: 'success',
            message: '获取播放凭证成功'
          })
          this.playauth=res;
          this.init();
        })
    },
    init(){
      new Aliplayer({
        id: 'J_prismPlayer',
        vid: this.videoSourceId, // 视频id
        playauth: this.playauth, // 播放凭证
        encryptType: '1', // 如果播放加密视频,则需设置encryptType=1,非加密视频无需设置此项
        width: '100%',
        height: '1000px',
        // 以下可选设置
        cover: '', // 封面
        qualitySort: 'asc', // 清晰度排序
        mediaType: 'video', // 返回音频还是视频
        autoplay: true, // 自动播放
        isLive: false, // 直播
        rePlay: false, // 循环播放
        preload: true,
        controlBarVisibility: 'hover', // 控制条的显示方式:鼠标悬停
        useH5Prism: true // 播放器类型:html5
      }, function(player) {
        console.log('播放器创建成功')
      })
    }
  }
}
script>
<style scoped>

style>

功能测试

1.上传一个视频文件,查看阿里云视频点播控制台,同时进行删除,然后在查看控制台。

2.再次上传一个视频文件,进行获取播放凭证进行播放

Spring Boot集成阿里云视频点播服务的过程记录_第21张图片

你可能感兴趣的:(其他,spring,boot,阿里云,视频点播,音视频,视频编解码)