• springboot阿里云视频点播服务实现上传视频和删除功能


    一、开通视频点播云平台

    1、选择视频点播服务(收费)

    阿里云地址:https://www.aliyun.com/activity/618/2021?spm=5176.22772544.J_8058803260.d83.10632ea9TWsUsu&scm=20140722.3979.2.4317

    产品->视频服务->视频点播

    2、开通视频点播(选择按使用流量计费)

    我的已经开通了,没开通的开通一下

    3、选择按使用流量计费(选择使用流量计费,目前少于50G不收费,具体以实际为准)

     

    4、资费说明

    地址:https://www.aliyun.com/price/product?spm=a2c4g.11186623.2.12.7fbd59b9vmXVN6#/vod/detail

    5、整体流程

    1. 用户获取上传授权。
    2. VoD下发 上传地址和凭证 及 VideoId。
    3. 用户上传视频保存视频ID(VideoId)。
    4. 用户服务端获取播放凭证。
    5. VoD下发带时效的播放凭证。
    6. 用户服务端将播放凭证下发给客户端完成视频播放。

    二、视频点播服务的基本使用

    参考地址:https://help.aliyun.com/product/29932.html?spm=a2c4g.11186623.6.540.3c356a58OEmVZJ

    1、设置转码格式

    选择全局设置 > 转码设置,单击添加转码模板组。
    在视频转码模板组页面,根据业务需求选择封装格式和清晰度。
    或直接将已有的模板设置为默认即可

     

    2、分类管理

    选择全局设置 > 分类管理

    3、上传视频文件

    选择媒资库 > 音视频,单击上传音视频

    4、配置域名,之前视频播放必须配置域名,现在可以不配置,但是播放加密的视频,必须要域名。

    音视频上传完成后,必须配一个已备案的域名,并完成CNAME绑定

     

    5、视频上传只有用到基础信息中的ID值

    三、视频上传文档资料

    地址:https://www.aliyun.com/product/vod?spm=5176.19720258.J_8058803260.342.73832c4aJtohbh

    参考上边地址里的服务端API和服务端SDK,阿里云推荐使用服务端SDK调用API.SDK的底层是API,本文主要参考服务端ADK->JAVA SDK.

    API:阿里云提供固定的地址,只需要调用这个固定的地址,向地址传递参数,实现功能

    SDK:调用阿里云提供类或者接口的方法实现功能

    服务端:指的是java接口

    客户端:指的是浏览器,安卓,ios

    1、环境准备

    适用于JDK 6及以上版本。

    2、安装SDK

    本例中用到的版本以及jar包。(注意本文用到的jar包是VODUploadDemo-java-1.4.11jar,有些jar包未开源,在maven中央仓库没有未开源的jar包,所以pom文件里不能自动联网下载,可以通过maven命令手动安装本地maven仓库中

    可以参照这个地址:https://www.cnblogs.com/konglxblog/p/14881649.html

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>service</artifactId>
            <groupId>com.stu</groupId>
            <version>0.0.1-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>service-vod</artifactId>
        <dependencies>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-core</artifactId>
            </dependency>
            <dependency>
                <groupId>com.aliyun.oss</groupId>
                <artifactId>aliyun-sdk-oss</artifactId>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-vod</artifactId>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-sdk-vod-upload</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
            </dependency>
            <dependency>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
            </dependency>
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
            </dependency>
    
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
            </dependency>
        </dependencies>
    </project>

    版本号

        <properties>
            <java.version>1.8</java.version>
            <guli.version>0.0.1-SNAPSHOT</guli.version>
            <mybatis-plus.version>3.0.5</mybatis-plus.version>
            <velocity.version>2.0</velocity.version>
            <swagger.version>2.7.0</swagger.version>
            <aliyun.oss.version>2.8.3</aliyun.oss.version>
            <jodatime.version>2.10.1</jodatime.version>
            <poi.version>3.17</poi.version>
            <commons-fileupload.version>1.3.1</commons-fileupload.version>
            <commons-io.version>2.6</commons-io.version>
            <httpclient.version>4.5.1</httpclient.version>
            <jwt.version>0.7.0</jwt.version>
            <aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version>
            <aliyun-sdk-oss.version>3.1.0</aliyun-sdk-oss.version>
            <aliyun-java-sdk-vod.version>2.15.5</aliyun-java-sdk-vod.version>
            <aliyun-java-vod-upload.version>1.4.11</aliyun-java-vod-upload.version>
            <aliyun-sdk-vod-upload.version>1.4.11</aliyun-sdk-vod-upload.version>
            <fastjson.version>1.2.28</fastjson.version>
            <gson.version>2.8.2</gson.version>
            <json.version>20170516</json.version>
            <commons-dbutils.version>1.7</commons-dbutils.version>
            <canal.client.version>1.1.0</canal.client.version>
            <docker.image.prefix>zx</docker.image.prefix>
            <cloud-alibaba.version>0.2.2.RELEASE</cloud-alibaba.version>
        </properties>

    3、前提条件

    4、初始化(本文以填入账号AccessKey信息,进行初始化)

    点播服务的接入区域请参见接入区域和标识,例如:接入区域在上海,请使用cn-shanghai。(注意cn-shanghai是固定的。

    • 获取视频播放地址

    • 获取视频播放凭证

    • 视频功能主要根据视频的ID来实现功能,不根据视频地址实现,原因上传的视频可以加密,不加密的视频根据视频地址可以播放,但是加密地址的视频播放不了,所以根据ID实现功能,往数据库存储的是视频ID。
    • 获取视频播放地址和获取视频播放凭证都可以播放视频,但是用凭证既能播放加密视频也能播放不加密的视频。
    • 本文说的视频ID就是下图中的ID。

    5、根据视频ID获取视频地址,获取视频凭证,上传视频代码示例

    InitAcsClint初始化类(参照阿里云JAVA SDK ->初始化->填入账号AccessKey信息,进行初始化

    参考地址:https://help.aliyun.com/document_detail/61062.html?spm=a2c4g.11186623.6.1033.5c3f5186TnVPYE

    package com.stu.vod.test;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    
    public class InitAcsClint {
        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;
        }
    }

    TestVod测试类,根据视频ID获取视频地址,获取视频凭证,上传视频方法(参照阿里云JAVA SDK->获取视频播放地址和获取视频播放凭证,上传SDK->服务端上传->JAAV上传SDK)

    视频地址和视频凭证参考地址:https://help.aliyun.com/document_detail/61064.html?spm=a2c4g.11186623.2.20.322fd418dScXpy

    视频上传参考地址:https://help.aliyun.com/document_detail/53406.html?spm=a2c4g.11186623.6.1025.3562d418A5I6t0

    package com.stu.vod.test;
    
    import com.aliyun.vod.upload.impl.UploadVideoImpl;
    import com.aliyun.vod.upload.req.UploadVideoRequest;
    import com.aliyun.vod.upload.resp.UploadVideoResponse;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.vod.model.v20170321.GetPlayInfoRequest;
    import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
    import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthRequest;
    import com.aliyuncs.vod.model.v20170321.GetVideoPlayAuthResponse;
    
    import java.util.List;
    
    
    public class TestVod {
        public static void main(String[] args) throws Exception {
            testUploadVideo();
        }
    
        /**
         * 本地文件上传接口
         *
         */
        private static void testUploadVideo() {
            String accessKeyId ="LTAI5t9VceHAhYQWzbRYStXv";
            String accessKeySecret = "VQGvWWcpYKmJRiW9GRqdWDns17gc6i";
            //视频标题(必选)
            String title = "3 - How Does Project Submission Work - upload by sdk";
            //本地文件上传和文件流上传时,文件名称为上传文件绝对路径,如:/User/sample/文件名称.mp4 (必选)
            //文件名必须包含扩展名
            String fileName = "F:/aa.mp4";
            //本地文件上传
            UploadVideoRequest request = new UploadVideoRequest(accessKeyId, accessKeySecret, title, fileName);
            /* 可指定分片上传时每个分片的大小,默认为2M字节 */
            request.setPartSize(2 * 1024 * 1024L);
            /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/
            request.setTaskNum(1);
    
            UploadVideoImpl uploader = new UploadVideoImpl();
            UploadVideoResponse response = uploader.uploadVideo(request);
            System.out.print("RequestId=" + response.getRequestId() + "
    ");  //请求视频点播服务的请求ID
            if (response.isSuccess()) {
                System.out.print("VideoId=" + response.getVideoId() + "
    ");
            } else {
                /* 如果设置回调URL无效,不影响视频上传,可以返回VideoId同时会返回错误码。其他情况上传失败时,VideoId为空,此时需要根据返回错误码分析具体错误原因 */
                System.out.print("VideoId=" + response.getVideoId() + "
    ");
                System.out.print("ErrorCode=" + response.getCode() + "
    ");
                System.out.print("ErrorMessage=" + response.getMessage() + "
    ");
            }
        }
    
        public static void getPlayAuth() throws Exception {
            //1根据视频id获取视频播放地址
    
            //1.1创建初始化对象
            DefaultAcsClient client = InitAcsClint.initVodClient("LTAI5t9VceHAhYQWzbRYStXv","VQGvWWcpYKmJRiW9GRqdWDns17gc6i");
            //1.2创建获取视频地址response和request对象
            GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
            GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse();
    
            //1.3向request对象里面设置视频id
            request.setVideoId("0aff5247d80d4ff1bbddcfc6a5c8e6a1");
            //1.4调用初始化对象里的方法,取得凭证
            response = client.getAcsResponse(request);
            System.out.println(response.getPlayAuth());
    
        }
        public static void getPlayUrl() throws Exception {
            //1根据视频id获取视频播放地址
    
            //1.1创建初始化对象
            DefaultAcsClient client = InitAcsClint.initVodClient("LTAI5t9VceHAhYQWzbRYStXv","VQGvWWcpYKmJRiW9GRqdWDns17gc6i");
            //1.2创建获取视频地址response和request对象
            GetPlayInfoRequest request = new GetPlayInfoRequest();
            GetPlayInfoResponse response = new GetPlayInfoResponse();
    
            //1.3向request对象里面设置视频id
            request.setVideoId("0aff5247d80d4ff1bbddcfc6a5c8e6a1");
            //1.4调用初始化对象里的方法,传递request,获取数据
            response = client.getAcsResponse(request);
    
            List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
            //1.5播放地址
            for (GetPlayInfoResponse.PlayInfo playInfo : playInfoList) {
                System.out.print("PlayInfo.PlayURL = " + playInfo.getPlayURL() + "
    ");
            }
            //Base信息
            System.out.print("VideoBase.Title = " + response.getVideoBase().getTitle() + "
    ");
    
        }
    }

    6、JAVA上传SDK示例代码(比5里的更详细,可以理解为5的扩充)

    首先在地址:https://help.aliyun.com/document_detail/51992.htm?spm=a2c4g.11186623.2.6.1fea5186ltnfVA#title-mbq-hhb-gy2下载SDK。

    然后解压,找到上传demo类,例子中有多种上传方式,上边通过【本地文件上传接口】方式实现上传。

    四、视频上传,删除视频功能实现(通过【流式上传接口】实现视频上传)

    视频删除参考地址:https://help.aliyun.com/document_detail/61065.html?spm=a2c4g.11186623.6.831.654b3815cIxvma#title-pqt-085-dyf

    1、application.properties属性文件以及配置nginx反向代理(jar包以及依赖同上,如果没用到nginx可以不用配置)

    #服务端口
    server.port=8003
    #服务名
    spring.application.name=service-vod
    # 环境设置:dev、test、prod
    spring.profiles.active=dev
    
    #阿里云 vod
    #不同的服务器,地址不同
    aliyun.vod.file.keyid=LTAI5t9VceHAhYQWzbRYStXv
    aliyun.vod.file.keysecret=VQGvWWcpYKmJRiW9GRqdWDns17gc6i
    
    # 最大上传单个文件大小:默认1M
    spring.servlet.multipart.max-file-size=1024MB
    # 最大置总上传的数据大小 :默认10M
    spring.servlet.multipart.max-request-size=1024MB

    ConstantVodUtils属性文件值获取

    package com.stu.vod.utils;
    
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    //项目启动,spring接口,spring加载之后,执行接口一个方法
    @Component
    public class ConstantVodUtils implements InitializingBean {
    
        //通过@value注解读取属性文件里的值,赋值给keyId
        @Value("${aliyun.vod.file.keyid}")
        private String keyId;
        @Value("${aliyun.vod.file.keysecret}")
        private String keysecret;
    
        //定义一些静态常量
        public  static String KEY_ID;
        public  static String KEY_SECRET;
    
        //上边赋值完成后,会执行afterPropertiesSet方法,这是spring机制
        @Override
        public void afterPropertiesSet() throws Exception {
            KEY_ID = keyId;
            KEY_SECRET = keysecret;
    
        }
    }

    nginx反向代理(nginx.conf文件配置)

    将接口地址加入nginx配置

    location ~ /
    eduvod
    / { proxy_pass http://localhost:8003; }
    配置nginx上传文件大小,否则上传时会有 413 (Request Entity Too Large) 异常
    打开nginx主配置文件nginx.conf,找到http{},添加
    client_max_body_size 1024m;

    重启nginx

    nginx -s reload

    nginx.exe路径下cmd命令输入【nginx.exe】启动nginx,输入nginx.exe按回车,光标闪烁表示启动成功

    输入【nginx -s reload】重启nginx(有时候在Windows环境可能不好用)或者通过 nginx.exe -s stop关闭然后通过nginx.exe启动

     

    完整配置

    #user  nobody;
    worker_processes  1;
    
    #error_log  logs/error.log;
    #error_log  logs/error.log  notice;
    #error_log  logs/error.log  info;
    
    #pid        logs/nginx.pid;
    
    
    events {
        worker_connections  1024;
    }
    
    
    http {
        include       mime.types;
        default_type  application/octet-stream;
        client_max_body_size 1024m;
        #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        #                  '$status $body_bytes_sent "$http_referer" '
        #                  '"$http_user_agent" "$http_x_forwarded_for"';
    
        #access_log  logs/access.log  main;
    
        sendfile        on;
        #tcp_nopush     on;
    
        #keepalive_timeout  0;
        keepalive_timeout  65;
    
        #gzip  on;
    
        server {
            listen       81;
            server_name  localhost;
    
            #charset koi8-r;
    
            #access_log  logs/host.access.log  main;
    
            location / {
                root   html;
                index  index.html index.htm;
            }
    
            #error_page  404              /404.html;
    
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html;
            location = /50x.html {
                root   html;
            }
    
            # proxy the PHP scripts to Apache listening on 127.0.0.1:80
            #
            #location ~ .php$ {
            #    proxy_pass   http://127.0.0.1;
            #}
    
            # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
            #
            #location ~ .php$ {
            #    root           html;
            #    fastcgi_pass   127.0.0.1:9000;
            #    fastcgi_index  index.php;
            #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
            #    include        fastcgi_params;
            #}
    
            # deny access to .htaccess files, if Apache's document root
            # concurs with nginx's one
            #
            #location ~ /.ht {
            #    deny  all;
            #}
        }
    
    
        # another virtual host using mix of IP-, name-, and port-based configuration
        #
        #server {
        #    listen       8000;
        #    listen       somename:8080;
        #    server_name  somename  alias  another.alias;
    
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
    
    
        # HTTPS server
        #
        #server {
        #    listen       443 ssl;
        #    server_name  localhost;
    
        #    ssl_certificate      cert.pem;
        #    ssl_certificate_key  cert.key;
    
        #    ssl_session_cache    shared:SSL:1m;
        #    ssl_session_timeout  5m;
    
        #    ssl_ciphers  HIGH:!aNULL:!MD5;
        #    ssl_prefer_server_ciphers  on;
    
        #    location / {
        #        root   html;
        #        index  index.html index.htm;
        #    }
        #}
        server {
            listen       9001;
            server_name  localhost;
    
            location ~ /eduservice/ {           
                 proxy_pass http://localhost:8001;
            }
            location ~ /eduOss/ {           
                 proxy_pass http://localhost:8002;
            }
            location ~ /eduvod/ {           
                proxy_pass http://localhost:8003;
            }
        }
    
    
    }

    2、controller文件

    package com.stu.vod.controller;
    
    import com.stu.commonutils.ResultData;
    import com.stu.vod.service.VodService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    
    @RestController
    @RequestMapping("/eduvod/video")
    @CrossOrigin
    public class VodController {
    
        @Autowired
        private VodService vodService;
    
        //上传视频到阿里云
        @PostMapping("uploadAlyVideo")
        public ResultData uploadAlyVideo(MultipartFile file){
            //返回视频id
            String videoId = vodService.uploadAlyVideo(file);
            return ResultData.success().data("videoId",videoId);
        }
        //根据id删除阿里云视频
        @DeleteMapping("removeVideo/{id}")
        public ResultData removeVideo(@PathVariable String id){
            //返回视频id
            String videoId = vodService.removeVideo(id);
            return ResultData.success();
        }
    
    }

    3、service接口

    package com.stu.vod.service;
    
    import org.springframework.web.multipart.MultipartFile;
    
    public interface VodService {
        String uploadAlyVideo(MultipartFile file);
    
        String removeVideo(String id);
    
    }

    4、service接口实现类

    package com.stu.vod.service.impl;
    
    import com.aliyun.vod.upload.impl.UploadVideoImpl;
    import com.aliyun.vod.upload.req.UploadStreamRequest;
    import com.aliyun.vod.upload.resp.UploadStreamResponse;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.vod.model.v20170321.DeleteVideoRequest;
    import com.stu.servicebase.exceptionHandler.GuliException;
    import com.stu.vod.service.VodService;
    import com.stu.vod.utils.ConstantVodUtils;
    import com.stu.vod.utils.InitVodClient;
    import org.springframework.stereotype.Service;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.InputStream;
    @Service
    public class VodServiceImpl implements VodService {
    
       //通过【流式上传接口】实现 @Override
    public String uploadAlyVideo(MultipartFile file) { try { //accessKeyId, accessKeySecret //fileName:上传文件原始名称 // 01.03.09.mp4 String fileName = file.getOriginalFilename(); //title:上传之后显示名称 String title = fileName.substring(0, fileName.lastIndexOf(".")); //inputStream:上传文件输入流 InputStream inputStream = file.getInputStream(); UploadStreamRequest request = new UploadStreamRequest(ConstantVodUtils.KEY_ID,ConstantVodUtils.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 String removeVideo(String id) { try { //1初始化对象 DefaultAcsClient client = InitVodClient.initVodClient(ConstantVodUtils.KEY_ID, ConstantVodUtils.KEY_SECRET); //2创建删除视频request对象 DeleteVideoRequest request = new DeleteVideoRequest(); //3向request设置视频id request.setVideoIds(id); //4调用初始化对象的方法删除视频 client.getAcsResponse(request); return id; } catch (Exception e) { e.printStackTrace(); throw new GuliException(20001,"删除视频失败"); } } }
  • 相关阅读:
    3个百度网盘下载实用小技巧
    decodeURIComponent 解码函数
    background属性怎么添加2个或多个背景图
    本地运行vue项目webpack提示 Compiled successfully
    var和let区别简述
    picture元素的使用
    博客园自定义鼠标icon
    background-size:100% 100% 和 background-size:cover的区别简述
    ScreenToGif——gif动图工具使用说明
    离职个人社保补缴——程序员也应该知道的社保基础知识科普
  • 原文地址:https://www.cnblogs.com/konglxblog/p/14901688.html
Copyright © 2020-2023  润新知