飞天班第24节:企业项目构建-阿里云视频点播

2020/04/19

1、了解并开通点播业务

阅读:阿里云视频点播技术能力盘点

​ 阿里云视频点播是集音视频采集、编辑、上传、自动化转码处理、媒体资源管理、分发加速、视频播放于一体的一站式音视频点播解决方案,为用户提供了Web管理控制台和软件开发工具包(API+SDK,包括视频上传、播放器等),用户可以通过它们使用、管理视频点播服务,也可以与自己的应用或服务集成,快速搭建安全、弹性、高可定制的视频点播功能。 流程:

好处:

  • SDK几行代码即可接入
  • 私有加密算法加密视频,告别视频安全困扰
  • 视频+AI加速内容处理效率
  • 窄带高清技术,最多节省30%流量

开通服务

1、找到视频点播

选择按量计费

了解资费说明 https://www.aliyun.com/price/product?spm=5176.12672711.overview.8.70f71fa3fxC5xA#/vod/detail

视频点播服务(后付费)计费项包含:视频加速(CDN)、媒资管理(存储等)、媒体处理(转码)、增值服务(智能审核、视频DNA)。 其中视频加速可选按[流量]付费或按[日峰值带宽 ]计费

2、视频上传后,web播放器(静态html代码)

3、转码说明

默认不转码,也可以自己添加转码设置(配置管理-》媒体处理配置)

点击模板,高级参数勾选HLS加密,视频就会加密,十分简单

4、域名绑定:

添加域名后,配置cname:https://help.aliyun.com/document_detail/86076.html?spm=5176.12672711.0.0.27ba1fa3AgJtT4

2、学会使用服务端API

找到API文档

准备工作,使用我们之前的oss子用户账号,开通账号用户组的阿里云点播权限:AliyunVodFullAccess

API,官网:https://help.aliyun.com/document_detail/44435.html?spm=a2c4g.11186623.6.708.6770448bTi8D8L

创建测试maven项目

导入依赖

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.1</version>
</dependency>
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
</dependency>

创建工具类AliyunVodApiUtils,复制官方调用示例代码

测试,原理步骤4步

加入签名,可以防止重放攻击,接口校验随机数在有效期内的唯一性,避免重复请求。

3、学会使用服务端的SDK

找到SDK文档

找到Java SDK

安装

Pom.xml

<!-- 添加阿里云的仓库 -->
<repositories>
  <repository>
    <id>sonatype-nexus-staging</id>
    <name>Sonatype Nexus Staging</name>
    <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    <releases>
      <enabled>true</enabled>
    </releases>
    <snapshots>
      <enabled>true</enabled>
    </snapshots>
  </repository>
</repositories>

添加SDK依赖

<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-core</artifactId>
  <version>4.3.3</version>
</dependency>
<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-vod</artifactId>
  <version>2.15.5</version>
</dependency>
<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.8.2</version>
</dependency>

创建工具类AliyunVodSDKUtils,复制官方使用 账号AccessKey 初始化的代码

public class AliyunVodSDKUtils {
	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;
	}
}

测试

获取播放凭证

@Test
public void getVideoPlayAuth() throws Exception {
  // 初始化客户端
  DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(access_key_id,access_key_secret);
  // 请求
  GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
  // 响应
  GetVideoPlayAuthResponse response = new GetVideoPlayAuthResponse();

  // 设置请求参数,视频ID
  request.setVideoId("2126ddd619254837a7fe909ff6242cd6");
  // 获取请求的响应
  response = client.getAcsResponse(request);
  // 播放凭证
  System.out.println(response.getPlayAuth());
  // 媒体信息
  System.out.println(response.getVideoMeta().getTitle());
}

获取播放地址

@Test
public  void getPlayInfo() throws Exception {
  // 初始化客户端
  DefaultAcsClient client = AliyunVodSDKUtils.initVodClient(access_key_id,access_key_secret);
  // 请求
  GetPlayInfoRequest request = new GetPlayInfoRequest();
  // 响应
  GetPlayInfoResponse response = null;

  // 设置请求参数,视频ID
  request.setVideoId("2126ddd619254837a7fe909ff6242cd6");
  // 获取请求的响应
  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");
}

4、视频安全(HLS加密)

hls标准加密

转码模版组,勾选hls加密

要使用加密,必须绑定域名备案

5、视频上传

SDK安装

文档:https://help.aliyun.com/document_detail/53406.html?spm=a2c4g.11186623.2.20.57ff7bdc2K8gXK

点击视频上传SDK下载

找到服务端SDK下载,下载Java上传1.4.2及示例代码

解压后的lib目录就是所需要的jar包。

安装官方文档所说,除了aliyun-java-vod-upload-1.4.12.jar 其他依赖都可以通过maven安装依赖,因为它还没有开源,需要手动引入依赖到自己的项目中。

添加依赖的两种方式:

  • 直接添加到项目

    项目/resources文件夹下建立lib目录,add as library,jar包放在lib目录下。

  • 添加到本地maven仓库

    mvn install:install-file -DgroupId=com.aliyun -DartifactId=aliyun-java-vod-upload -Dversion=1.4.12 -Dpackaging=jar -Dfile=/Users/xjw/Downloads/VODUploadDemo-java-1.4.12/lib/aliyun-java-vod-upload-1.4.12.jar 
    

添加依赖

<dependency>
  <groupId>com.aliyun.oss</groupId>
  <artifactId>aliyun-sdk-oss</artifactId>
  <version>3.1.0</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.aliyun</groupId>
  <artifactId>aliyun-java-vod-upload</artifactId>
  <version>1.4.12</version>
  </dependency>

后端使用java上传视频

复制官方的示例代码,参数可自行调整开启

运行成功,获得视频ID

前端使用js上传视频

官方文档:https://help.aliyun.com/document_detail/52204.html

6、视频播放

官方文档:https://help.aliyun.com/document_detail/125548.html

在线配置

开通视频功能集成到项目中步骤:

1、开通阿里云点播服务

2、编写后端上传视频工具类,返回视频id

3、前端视频vue,自己写或者爬取好看的视频播放页面,将视频放上去播放即可

前端播放功能配置:弹幕、音量等,官方文档:https://help.aliyun.com/document_detail/125574.html

7、视频微服务搭建

后端上传API

创建微服务模块edu-vod

初始化加载accesskey

// 初始化加载
@Component
public class ConstantPropertiesUtils implements InitializingBean {
    @Value("${aliyun.vod.file.accessKeyId}")
    private String keyId;
    @Value("${aliyun.vod.file.accessKeySecret}")
    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;
    }
}

业务层接口VideoService

public interface VideoService {
	String uploadVideo(MultipartFile file);
}

接口实现类VideoServiceImpl

@Service
public class VideoServiceImpl implements VideoService {
	@Override
	public String uploadVideo(MultipartFile file) {
		// 获取文件名称
		String filename = file.getOriginalFilename();
		String title = filename.substring(0,filename.lastIndexOf("."));
		InputStream inputStream = null;


		// 封装上传
		try {
			inputStream = file.getInputStream();
		} catch (IOException e) {
			throw new JudeException(ResultCodeEnum.VIDEO_UPLOAD_TOMCAT_ERROR);
		}

		// 流上传到阿里云
		UploadStreamRequest request = new UploadStreamRequest(ConstantPropertiesUtils.ACCESS_KEY_ID,
				ConstantPropertiesUtils.ACCESS_KEY_SECRET, title,filename,inputStream);
		UploadVideoImpl uploader = new UploadVideoImpl();
		UploadStreamResponse response = uploader.uploadStream(request);
		String vdieoId = response.getVideoId();

		if(!response.isSuccess() && StringUtils.isEmpty(vdieoId)){
			throw new JudeException(ResultCodeEnum.VIDEO_UPLOAD_ALIYUN_ERROR);
		}
		return vdieoId;
	}
}

web层接口的定义

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

	@PostMapping("upload")
	public R uploadVideo(
			@ApiParam(name = "file",value = "文件",required = true)
			@RequestParam MultipartFile file){
		String videoId = videoService.uploadVideo(file);
		return R.ok().message("视频上传成功").data("videoId",videoId);
	}
}

swagger2测试

配置nginx

location路由和允许上传的文件大小,否则会报413Request Entity Too large 异常

location ~ /vod/{
  proxy_pass http://localhost:8160;
}
http {
  ...
  client_max_body_size 1024m;
  ...
}

删除视频

点进com.aliyun.AcsRequest的源码,发现它是一个抽象类,查看它的实现类

找到DeleteVideoRequest类,通过这个请求删除阿里云上的视频

@Override
public void removeVideo(String videoId) {
  DefaultAcsClient client = null;
  try {
    client = AliyunVodSDKUtils.initVodClient(ConstantPropertiesUtils.ACCESS_KEY_ID,ConstantPropertiesUtils.ACCESS_KEY_SECRET);
    // 删除请求
    DeleteVideoRequest request = new DeleteVideoRequest();
    request.setVideoIds(videoId);
    DeleteVideoResponse response = client.getAcsResponse(request);
  } catch (ClientException e) {
    throw new JudeException(ResultCodeEnum.VIDEO_DELETE_ALIYUM_ERROR);
  }
}

整合前端上传

前端模版

<el-form-item label="上传视频">
        <el-upload
          drag
          :file-list="fileList"
          :on-success="handleVodUploadSuccess"
          :on-error="handleVodUploadError"
          :on-exceed="handleVodExceed"
          :on-remove="handleVodRemove"
          :before-remove="handleVodBeforeRemove"
          :on-progress="handleVodUploadProgress"
          :limit="1"
          :action="uploadUrl"
          >
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          <div slot="tip" class="el-upload__tip">支持3GP、ASF、AVI、DAT、DV、FLV、F4V、GIF、M2T、M4V、MJ2、MJPEG、MKV、MOV、MP4、MPE、MPG、MPEG、MTS、OGG、QT、RM、RMVB、SWF、TS、VOB、WMV、WEBM 等视频格式上传</div>
        </el-upload>
</el-form-item>

Vod.js

import request from '@/utils/request'

const api_name = '/admin/vod/video'
 
export default {
  removeById(id) {
    return request({
      url: `${api_name}/${id}`,
      method: 'delete'
    })
  }
}

Method:

import vod from '@/api/edu/vod'
...
export default {
  ...
  method: {
    ...
   	handleVodUploadSuccess(response,file,fileList) {
      this.fileUoloadBtnText = '上传到服务器'
      this.loading = false
      if (response.success === true) {
        this.video.videoSourceId = response.data.videoId
        this.video.videoOriginalName = file.name
      } else {
        this.$alert(response.message)
      }
    },
    handleVodUploadError() {
      this.loading = false
    },
    handleVodUploadProgress(){
      this.fileUoloadBtnText = '正在上传'
      this.loading = true
    },
    handleVodExceed(){
      this.$message({
          type: 'error',
          message: '文件数超出限制,请删除已有视频再上传'
        })
    },
    handleVodRemove(file) {
      //console.log(file)
      vod.removeById(this.video.videoSourceId).then(response => {
        this.video.videoSourceId = ''
        this.video.videoOriginalName = ''
        this.$message({
          type: 'success',
          message: response.message
        })
      })
    },
    handleVodBeforeRemove(file) {
      return this.$confirm(`确定移除${file.name}?`)
    } 
  }
}

测试:

后端上传视频的方式,无法看到视频在服务端tomcat到阿里云的文件上传进度,考虑使用javascript上传,文件由客户端直接上传到阿里云,不经过后端。

Post Directory