刚刚了解了OSS存储,现在需要了解视频点播服务,什么是视频点播服务?为什么需要视频点播服务?OSS存储不是可以直接存储视频吗?

其实我也不很清楚,只是大体上知道视频点播服务是专门云端存储视频的,相比于OSS来说,更加聚焦于视频,更加适合云端操作视频。

视频点播服务和OSS大体相同,都是阿里云提供的一种服务,所以视频点播服务应该是和OSS的使用相同,逻辑上不会相差太多。

后面翻看官方文档发现:视频点播基于阿里云OSS,为您提供资源存储服务,无需单独开通OSS即可使用。同时还能省去迁移数据的麻烦,将OSS中已创建的OSS Bucket添加到视频点播中。视频点播的存储本质上是基于阿里云OSS实现的,分为点播系统Bucket与OSS自有Bucket这两种存储。开通点播服务后,需要启用点播系统Bucket,以支持视频、音频、图片、字幕等各种媒体文件的存储和处理,并可作为CDN加速的源站。但如果您已有大量媒体文件存在于OSS Bucket,且不方便迁移到点播的系统Bucket,可以将自有的OSS Bucket添加到视频点播服务中,以实现对存储在OSS Bucket中的媒体文件进行转码、截图、播放等操作。具体参考:存储管理 (aliyun.com)

上面的意思是,如果我们已经有大量的音频数据存储到了OSS中,那么点播服务可以帮助我们一键迁移到点播系统Bucket中,如果我们的视频还没有上传,我们最好是放在点播系统Bucket中。

一:前期准备

1.1:开通视频点播

1.2:观看官方网站新手视频指引(非开发人员操作步骤)

1.开启存储管理,就是在开通点播服务之后,我们需要创建一个存储空间bucket来专门存储上传的文件。

2.设置转码模板,转码模板是对视频的转码处理,不是很理解什么意思。

3.设置工作流,通过创建工作流,在上传和媒体处理的过程中可以使用作用流对视频进行流程化的处理,貌似暂时用不到。

4. 上传音视频,就是把我们本地的视频拉去视频点播上面。

5.处理视频,使用转码模板组或者工作流对食品进行处理

6.获取播放地址,就是让其他人能够访问到我们上传的视频。

7.配置加速域名,提升其他人的观看体验

二:开发人员具体开发流程

2.1 了解一些基本概念

接入区域:点播服务在全球多个地域提供就近接入

存储区域:每个接入区域有对应的存储区域,点播服务不可以跨区域调用

接入地域标识:对应的就是后面的API和各语言SDK中的RegionId参数,不同的RegionId代表不同接入地域。

接入地址(访问域名):对应自行构造HTTP(HTTPS)请求访问点播API场景下的请求URL中的服务地址。(不太理解具体含义)

访问控制(RAM):阿里云提供的用户身份管理与资源访问控制服务什么是访问控制 (aliyun.com)

 2.2 账号和授权

我们在能够使用阿里云主账号直接登陆后台的时候,我们直接就拥有了最高级的权限

 对于非开发人员来时,扫码登录就是授权,是在一种可视化界面完成的。但是对于开发人员来说,是要通过一行行的代码来进行登录的,所以我们就需要对开发人员特定的授权。

对于开发人员来说,几乎每一步的点播服务操作,都需要对发起请求的用户进行身份验证,就是通过AccessKey来判断,AccessKey就是账号+密码,缩写AK,AK有三种:主账号AK(最高权限)、RAM用户AK(部分权限)、STS临时AK(在一定时间后会过期,无法通过身份验证)。

至于选用哪种,参考官网:概述 (aliyun.com)

2.3 存储管理

我们上传的视频就是上传到存储空间bucket里面,存储管理是重要的一环。

使用流程如下(和上面的新手教程视频部门有重叠)

2.3.1 创建存储地址

2.3.2 (可选)添加加速域名

2.3.3 上传媒体资源到存储地址中

2.3.4 使用点播服务提供的转码,加密等功能

2.4 媒体上传

媒体上传是在存储空间bucket建立好之后进行的,是最最核心一步,上传方式有两类,一类是工具上传,一类是开发上传。我们作为开发,肯定是主要介绍难度较大的开发上传。开发上传又分为两类,SDK和API。

具体的上传方式有四种,我们无法选择上传SDK方式,因为我们使用的是Golang语言,暂时不被官方支持,但是官方建议我们使用“基于OSS原生SDK”上传。

 

基于OSS原生SDK上传的具体流程

  1. 初始化点播客户端(通过RAM用户AK方式或者STS临时AK)
  2. 获取上传地址和上传凭证(通过服务端SDK调用上传地址和凭证相关接口,也可使用HTTP/HTTPS,但是出错率较搞)
  3. 返回上传地址(UploadAddress,经过Base64加密)和上传凭证(UploadAuth)以及媒体ID等信息。可以根据返回结果解析参数作为初始化OSS原生SDK的入参
  4. 解析上传地址和上传凭证,并用解析后的上传地址和上传凭证初始化OSS客户端
  5. 开始上传(SDK调用OSS上传相关接口将媒体文件上传至指定的存储地址)
  6. 返回上传结果

前提条件

 官方文档上面的第二步我们还没有完成,现在去完成一下。

完成上传相关的系统配置

 三:上传本地文件到bucket实战操作

上面有完整的实例,成功的标志就是打开视频点播控制台后,能够看到上传的视频。 

项目上面,一般是需要给前端返回一个所有人都可以访问的URL地址。所以我们除了上传到云端,还要把URL给存储到数据库,然后返回给前端。

包括第一步的完整代码如下:

package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
	"github.com/aliyun/alibaba-cloud-sdk-go/services/vod"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"os"
)

func InitVodClient(accessKeyId string, accessKeySecret string) (client *vod.Client, err error) {
	// 点播服务接入区域
	regionId := "cn-shanghai"
	// 创建授权对象
	credential := &credentials.AccessKeyCredential{
		accessKeyId,
		accessKeySecret,
	}
	// 自定义config
	config := sdk.NewConfig()
	config.AutoRetry = true     // 失败是否自动重试
	config.MaxRetryTime = 3     // 最大重试次数
	config.Timeout = 3000000000 // 连接超时,单位:纳秒;默认为3秒
	// 创建vodClient实例
	return vod.NewClientWithOptions(regionId, config, credential)
}

func MyCreateUploadVideo(client *vod.Client) (response *vod.CreateUploadVideoResponse, err error) {
	request := vod.CreateCreateUploadVideoRequest()
	request.Title = "Sample Video Title"
	request.Description = "Sample Description"
	request.FileName = "/opt/video/sample/video_file.mp4"
	//request.CateId = "-1"
	//Cover URL示例:http://example.alicdn.com/tps/TB1qnJ1PVXXXXXCXXXXXXXXXXXX-700-****.png
	request.CoverURL = "<your CoverURL>"
	request.Tags = "tag1,tag2"
	request.AcceptFormat = "JSON"
	return client.CreateUploadVideo(request)
}

func InitOssClient(uploadAuthDTO UploadAuthDTO, uploadAddressDTO UploadAddressDTO) (*oss.Client, error) {
	client, err := oss.New(uploadAddressDTO.Endpoint,
		uploadAuthDTO.AccessKeyId,
		uploadAuthDTO.AccessKeySecret,
		oss.SecurityToken(uploadAuthDTO.SecurityToken),
		oss.Timeout(86400*7, 86400*7))
	return client, err
}

func UploadLocalFile(client *oss.Client, uploadAddressDTO UploadAddressDTO, localFile string) {
	// 获取存储空间。
	bucket, err := client.Bucket(uploadAddressDTO.Bucket)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	// 上传本地文件。
	err = bucket.PutObjectFromFile(uploadAddressDTO.FileName, localFile)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
}

type UploadAuthDTO struct {
	AccessKeyId     string
	AccessKeySecret string
	SecurityToken   string
}
type UploadAddressDTO struct {
	Endpoint string
	Bucket   string
	FileName string
}
func MyGetPlayInfo(client *vod.Client, videoId string) (response *vod.GetPlayInfoResponse, err error) {
	request := vod.CreateGetPlayInfoRequest()
	request.VideoId = videoId
	request.AcceptFormat = "JSON"

	return client.GetPlayInfo(request)
}
func main() {
	var accessKeyId string = "xxx"           // 您的AccessKeyId
	var accessKeySecret string = "xxx" // 您的AccessKeySecret
	var localFile string = "D:\\1.mp4"     // 需要上传到VOD的本地视频文件的完整路径
	// 初始化VOD客户端并获取上传地址和凭证
	var vodClient, initVodClientErr = InitVodClient(accessKeyId, accessKeySecret)
	if initVodClientErr != nil {
		fmt.Println("Error:", initVodClientErr)
		return
	}
	// 获取上传地址和凭证
	var response, createUploadVideoErr = MyCreateUploadVideo(vodClient)
	if createUploadVideoErr != nil {
		fmt.Println("Error:", createUploadVideoErr)
		return
	}
	// 执行成功会返回VideoId、UploadAddress和UploadAuth
	var videoId = response.VideoId
	var uploadAuthDTO UploadAuthDTO
	var uploadAddressDTO UploadAddressDTO
	var uploadAuthDecode, _ = base64.StdEncoding.DecodeString(response.UploadAuth)
	var uploadAddressDecode, _ = base64.StdEncoding.DecodeString(response.UploadAddress)
	json.Unmarshal(uploadAuthDecode, &uploadAuthDTO)
	json.Unmarshal(uploadAddressDecode, &uploadAddressDTO)
	// 使用UploadAuth和UploadAddress初始化OSS客户端
	var ossClient, _ = InitOssClient(uploadAuthDTO, uploadAddressDTO)
	// 上传文件,注意是同步上传会阻塞等待,耗时与文件大小和网络上行带宽有关
	UploadLocalFile(ossClient, uploadAddressDTO, localFile)
	//MultipartUploadFile(ossClient, uploadAddressDTO, localFile)
	fmt.Println("Succeed, VideoId:", videoId)
	response1, err := MyGetPlayInfo(vodClient, videoId)
	if err != nil {
		panic(err)
	}
	fmt.Println(response.GetHttpContentString())
	playList := response1.PlayInfoList.PlayInfo
	for _, playInfo := range playList {
		fmt.Printf("%s: %s\n", playInfo.Definition, playInfo.PlayURL)
	}
}
                

至此,我们已经通过Golang把音视频文件上传到了Bucket云端。