使用aws-sdk将视频及封面保存到对象存储中| 青训营笔记

753 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第 1 篇笔记。

前言

在看到项目文档之前,就已经考虑好了将视频保存在对象存储中而不是本地的方案。实际落地也没有遇到很多困难,且当对aws-sdk的一次简单了解吧。

什么是对象存储?

顾名思义,就是基于对象的存储。 和传统的关系型数据库不同的是,对象存储通常用于保存大量的非结构化数据,用简单的话来说,我们日常生活中生成的照片、视频、音频、文档等都属于非结构化数据。这些类型的文件都适合保存在对象存储中。

为什么使用aws-sdk?

在对象存储的行业中,aws-s3为事实标准,这意味着几乎所有的云厂商的对象存储都支持aws-s3的接口协议。无论哪个厂商的对象存储都可以直接使用aws-sdk进行操作,开发者不需要额外去学习新的文档,既有的代码在迁移到其他厂商以后依然可以直接使用。

创建Bucket

这里以腾讯云cos进行举例。

存储桶列表 - 对象存储 - 控制台 (tencent.com)

txyun.png 点击创建存储桶。

QQ截图20220601195722.png

QQ截图20220601195810.png

按照以下配置创建,需要注意的是由于我们的视频需要通过demo抖音客户端打开,因此访问权限选择公有读私有写。 创建完成即可使用了。对象存储的常规操作这里不做介绍。这里记下bucket名称和访问域名即可。

接下来在访问密钥 - 控制台 (tencent.com)中获取aws-sdk需要使用的accesskey和secretkey,在腾讯云中,SecretId就是accesskey。

QQ截图20220601201641.png

使用aws-sdk将视频上传到bucket中

首先安装aws-sdk相关的package。

$ go get github.com/aws/aws-sdk-go-v2/aws
$ go get github.com/aws/aws-sdk-go-v2/config
$ go get github.com/aws/aws-sdk-go-v2/service/dynamodb

根据以上的信息,我们创建一个s3客户端。

package s3

import (
	"context"

	"github.com/aws/aws-sdk-go-v2/aws"
	awscfg "github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/credentials"
	"github.com/aws/aws-sdk-go-v2/service/s3"
)

const (
	endpoint   = "https://cos.ap-guangzhou.myqcloud.com"
	accesskey  = "your access key" 
	secretkey  = "your secret key"
	bucketName = "your bucket"
	region     = "ap-guangzhou"
)

func NewS3Client() *s3.Client {
	customResolver := aws.EndpointResolverWithOptionsFunc(func(service, region string, options ...interface{}) (aws.Endpoint, error) {
		return aws.Endpoint{
			URL:           endpoint,
			SigningRegion: region,
		}, nil
	}) // 将endpoint设置为自己的endpoint
	cfg, err := awscfg.LoadDefaultConfig(context.TODO(), awscfg.WithEndpointResolverWithOptions(customResolver))
	if err != nil {
		panic(err)
	}
	cfg.Region = region
	cfg.Credentials = aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(accesskey, secretkey, "")) 
        // 设定accesskey和secretkey
	client := s3.NewFromConfig(cfg)
        // 创建s3客户端
	return client
}

这个返回的s3.client就是我们执行上传操作的对象了。我们以后的操作都会使用这个对象下的方法。

上传视频我们使用PutObject方法,我们需要构造这个方法下所需的结构体。

func main() {
	filepath := "./test.mp4"
	file, err := os.Open("./test.mp4") //打开文件
	if err != nil {
		panic(err)
	}
	s3c := NewS3Client()
	_, err = s3c.PutObject(context.TODO(), &s3.PutObjectInput{
		Bucket:      aws.String(bucketName),
                //该field的类型为*string,可以用aws自带的aws.string进行转换
		Key:         aws.String(filepath),
		Body:        file,
		ContentType: aws.String("video/mp4"),
	}) //上传文件
	if err != nil {
		fmt.Printf("upload video to s3 failed: %s", err.Error())
		return
	}
	fmt.Printf("upload video to s3 success: %s", filepath)
}

我们最终是要将上传的视频的url保存到数据库中的,在上传前后我们都可以用PreSign来直接获取对应对象的url。


func getobjecturl() {
	s3c := NewS3Client()
	ps3 := s3.NewPresignClient(s3c)
	pr, err := ps3.PresignGetObject(context.TODO(), &s3.GetObjectInput{
		Bucket: aws.String(bucketName),
		Key:    aws.String("test.mp4"),
	})
	if err != nil {
		fmt.Printf("get presign url failed: %s", err.Error())
		return
	}
	playurl := strings.Replace(pr.URL, "http://", "https://", 1)
	fmt.Printf("get presign url success: %s", playurl)
}

通过以上的实现,你就能做到将视频保存到对象存储中了。

参考资料