阿里云视频点播

  |   0 评论   |   0 浏览

阿里云视频点播

一、阿里云视频点播技术能力盘点

参考文章:

https://blog.csdn.net/qq_33857573/article/details/79564255

视频点播(ApsaraVideo for VoD)是集音视频采集、编辑、上传、自动化转码处理、媒体资源管理、分发加速于一体的一站式音视频点播解决方案。

img

1、应用场景

  • 音视频网站:无论是初创视频服务企业,还是已拥有海量视频资源,可定制化的点播服务帮助客户快速搭建拥有极致观看体验、安全可靠的视频点播应用。
  • 短视频:集音视频拍摄、特效编辑、本地转码、高速上传、自动化云端转码、媒体资源管理、分发加速、播放于一体的完整短视频解决方案。目前已帮助1000+APP快速实现手机短视频功能。
  • 直播转点播:将直播流同步录制为点播视频,用于回看。并支持媒资管理、媒体处理(转码及内容审核/智能首图等AI处理)、内容制作(云剪辑)、CDN分发加速等一系列操作。
  • 在线教育:为在线教育客户提供简单易用、安全可靠的视频点播服务。可通过控制台/API等多种方式上传教学视频,强大的转码能力保证视频可以快速发布,覆盖全网的加速节点保证学生观看的流畅度。防盗链、视频加密等版权保护方案保护教学内容不被窃取。
  • 视频生产制作:提供在线可视化剪辑平台及丰富的OpenAPI,帮助客户高效处理、制作视频内容。除基础的剪切拼接、混音、遮标、特效、合成等一系列功能外,依托云剪辑及点播一体化服务还可实现标准化、智能化剪辑生产,大大降低视频制作的槛,缩短制作时间,提升内容生产效率。
  • 内容审核:应用于短视频平台、传媒行业审核等场景,帮助客户从从语音、文字、视觉等多维度精准识别视频、封面、标题或评论的违禁内容进行AI智能审核与人工审核。

2、功能介绍

产品功能

二、开通阿里云视频点播

进入阿里云控制台输入:视频点播

https://vod.console.aliyun.com/#/guide

image-20220116131010045

1.流量计费:不用不花钱(推荐)
2.按带宽峰值计费:按使用流量带宽值从1M-100M均可以设置,带宽峰值无论是设置1M还是100M费用都是一样的,都是根据实际使用流量来支付费用,那么带宽峰值如何设置呢?新手站长网建议还是根据应用数据大小、并发数使用场景来设置合适的带宽峰值,如果带宽值设置过大,以免突发高流量导致较高费用产生

image-20220116131348736

1、资费说明

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

2、整体流程

使用视频点播实现音视频上传、存储、处理和播放的整体流程如下:

img

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

image-20220116131631841

image-20220116131650702

三、使用服务端SDK

image-20220116212144666

在本地Maven仓库中安装jar包:

下载地址:https://help.aliyun.com/document_detail/51992.html

image-20220116212611420

下载视频上传SDK,解压,命令行进入lib目录,执行以下代码

注意 : 这里aliyun-sdk-vod-upload和aliyun-sdk-oss的版本对应关系

mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-sdk-vod-upload -Dversion=1.4.14 -Dpackaging=jar -Dfile=aliyun-java-vod-upload-1.4.14.jar

然后在pom中引入jar包

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-sdk-vod-upload</artifactId>
    <version>1.4.14</version>
</dependency>

引入依赖

<dependencies>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
        <version>4.3.3</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun.oss</groupId>
        <artifactId>aliyun-sdk-oss</artifactId>
        <version>3.9.0</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-sdk-vod-upload</artifactId>
        <version>1.4.14</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-vod</artifactId>
        <version>2.15.2</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.28</version>
    </dependency>
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20170516</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>

yml配置

server:
  port: 8003

spring:
  application:
    name: service-vod
  profiles:
    active: dev
  servlet:
    multipart: #默认大小1M
      max-file-size: 1024MB
      max-request-size: 1024MB


aliyun:
  vod:
    file:
      keyId: 你的id
      keySecret: 你的secret

工具类

@Data
@Component
@ConfigurationProperties("aliyun.vod.file")
public class ConstantPropertiesUtil implements InitializingBean {

	private String keyId;

	private String keySecret;

	public static String ACCESS_KEY_ID;
	public static String ACCESS_KEY_SECRET;

	@Override
	public void afterPropertiesSet() throws Exception {
		ACCESS_KEY_ID = keyId;
		ACCESS_KEY_SECRET = keySecret;
	}
}

初始化

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;

public class InitObject {
    public final static String KEY_ID = "你的keyId";
    public final static String KEY_SECRET = "你的keySecret";
    //填入AccessKey信息
    public static DefaultAcsClient initVodClient() throws ClientException {
        // 点播服务接入地域,不能修改
        String regionId = "cn-shanghai";
        DefaultProfile profile = DefaultProfile.getProfile(regionId, KEY_ID, KEY_SECRET);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        return client;
    }
}

删除视频、获取视频播放凭证、获取视频地址、视频上传

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.exceptions.ClientException;
import com.aliyuncs.vod.model.v20170321.*;
import org.junit.Test;

import java.util.List;

public class UploadDemo {
    /**
     * 获取视频播放凭证
     * @throws ClientException
     */
    @Test
    public void testGetVideoPlayAuth() throws ClientException {

        //初始化客户端、请求对象和相应对象
        DefaultAcsClient client = InitObject.initVodClient();
        GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
        GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse();

        try {

            //设置请求参数
            request.setVideoId("ddb674ec06af442582acd159117908f6");
            //获取请求响应
            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");
    }

    /**
     * 获取视频播放地址
     * @throws ClientException
     */
    @Test
    public void testGetPlayInfo() throws ClientException {

        //初始化客户端、请求对象和相应对象
        DefaultAcsClient client = InitObject.initVodClient();
        GetPlayInfoRequest request = new GetPlayInfoRequest();
        GetPlayInfoResponse response = new GetPlayInfoResponse();

        try {

            //设置请求参数
            //注意:这里只能获取非加密视频的播放地址
            request.setVideoId("ddb674ec06af442582acd159117908f6");
            //获取请求响应
            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");
    }


    /**
     * 视频上传
     */
    @Test
    public void testUploadVideo(){

        //1.音视频上传-本地文件上传
        //视频标题(必选)
        String title = "视频标题测试";
        //本地文件上传和文件流上传时,文件名称为上传文件绝对路径,如:/User/sample/文件名称.mp4 (必选)
        //文件名必须包含扩展名
        String fileName = "E:/Download/在线教育--谷粒学苑/1-阿里云上传测试视频/我的测试.mp4";
        //本地文件上传
        UploadVideoRequest request = new UploadVideoRequest(InitObject.KEY_ID, InitObject.KEY_SECRET, title, fileName);
        /* 可指定分片上传时每个分片的大小,默认为1M字节 */
        request.setPartSize(1 * 1024 * 1024L);
        /* 可指定分片上传时的并发线程数,默认为1,(注:该配置会占用服务器CPU资源,需根据服务器情况指定)*/
        request.setTaskNum(1);
    /* 是否开启断点续传, 默认断点续传功能关闭。当网络不稳定或者程序崩溃时,再次发起相同上传请求,可以继续未完成的上传任务,适用于超时3000秒仍不能上传完成的大文件。
        注意: 断点续传开启后,会在上传过程中将上传位置写入本地磁盘文件,影响文件上传速度,请您根据实际情况选择是否开启*/
        request.setEnableCheckpoint(false);

        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");
        }
    }

    /**
     * 视频删除
     */
    @Test
    public void removeVideo(String videoId) throws ClientException {

            DefaultAcsClient client = InitObject.initVodClient();

            DeleteVideoRequest request = new DeleteVideoRequest();

            request.setVideoIds("ddb674ec06af442582acd159117908f6");

            DeleteVideoResponse response = client.getAcsResponse(request);

            System.out.println(("RequestId:"+ response.getRequestId() + "\n"));

    }


}

四、项目中运用阿里云点播视频

下面这段截图是项目中上传视频的一个功能点

image-20220116212827004

这里项目中将视频点播作为一个公共的服务,因此需要关注于文件的管理

视频上传返回视频id,没有返回url。在实际开发中视频往往都需要进行加密处理,因此这里记录视频的url是没有意义的。

记录视频id,可以根据id取获取凭证然后获取视频地址实现点播功能。

controller层

@Api(tags="阿里云视频点播微服务")
@CrossOrigin //跨域
@RestController
@RequestMapping("/vod/video")
public class VideoController {
    @Autowired
    private VideoService videoService;

    @ApiOperation("上传视频")
    @PostMapping("upload")
    public R uploadVideo(
            @ApiParam(name = "file", value = "文件", required = true)
            @RequestParam("file") MultipartFile file) throws Exception {

        String videoId = videoService.uploadVideo(file);
        return R.ok().message("视频上传成功").data("videoId", videoId);
    }

    @ApiOperation("删除视频")
    @DeleteMapping("{videoId}")
    public R removeVideo(@ApiParam(name = "videoId", value = "云端视频id", required = true)
                         @PathVariable String videoId){

        videoService.removeVideo(videoId);
        return R.ok().message("视频删除成功");
    }
}

service层

@Override
    public String uploadVideo(MultipartFile file) {
        try {
            InputStream inputStream = file.getInputStream();
            //文件名称
            String originalFilename = file.getOriginalFilename();
            //文件名作为标题
            String title = originalFilename.substring(0, originalFilename.lastIndexOf("."));
            String accessKeySecret = ConstantPropertiesUtil.ACCESS_KEY_SECRET;
            String accessKeyId = ConstantPropertiesUtil.ACCESS_KEY_ID;
            UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, originalFilename, inputStream);
            UploadVideoImpl uploader = new UploadVideoImpl();
            UploadStreamResponse response = uploader.uploadStream(request);
            String videoId = response.getVideoId();
            if (!response.isSuccess()) {
                String errorMessage = "阿里云上传错误:" + "code:" + response.getCode() + ", message:" + response.getMessage();
                log.warn(errorMessage);
                if (StringUtils.isEmpty(videoId)) {
                    throw new GuliException(ResultCode.ERROR, errorMessage);
                }
            }
            return videoId;
        } catch (IOException e) {
            throw new GuliException(ResultCode.ERROR, "guli vod 服务上传失败");
        }
    }

    @Override
    public void removeVideo(String videoId) {
        try{
            DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(
                    ConstantPropertiesUtil.ACCESS_KEY_ID,
                    ConstantPropertiesUtil.ACCESS_KEY_SECRET);

            DeleteVideoRequest request = new DeleteVideoRequest();

            request.setVideoIds(videoId);

            DeleteVideoResponse response = client.getAcsResponse(request);

            log.info("RequestId:{}", response.getRequestId() + "\n");

        }catch (ClientException e){
            throw new GuliException(20001, "视频删除失败");
        }
    }

标题:阿里云视频点播
作者:llp
地址:https://llinp.cn/articles/2022/01/16/1642340331598.html