129 lines
3.4 KiB
Go
129 lines
3.4 KiB
Go
// Package common
|
||
// @Link https://github.com/bufanyun/hotgo
|
||
// @Copyright Copyright (c) 2023 HotGo CLI
|
||
// @Author Ms <133814250@qq.com>
|
||
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
|
||
package common
|
||
|
||
import (
|
||
"context"
|
||
"hotgo/api/admin/common"
|
||
"hotgo/internal/library/storager"
|
||
"hotgo/internal/service"
|
||
"hotgo/utility/validate"
|
||
"os"
|
||
"os/exec"
|
||
"path/filepath"
|
||
|
||
"github.com/gogf/gf/v2/errors/gerror"
|
||
"github.com/gogf/gf/v2/frame/g"
|
||
"github.com/google/uuid"
|
||
)
|
||
|
||
var Upload = new(cUpload)
|
||
|
||
type cUpload struct{}
|
||
|
||
// UploadFile 上传文件
|
||
func (c *cUpload) UploadFile(ctx context.Context, _ *common.UploadFileReq) (res common.UploadFileRes, err error) {
|
||
r := g.RequestFromCtx(ctx)
|
||
uploadType := r.Header.Get("uploadType")
|
||
if uploadType != "default" && !validate.InSlice(storager.KindSlice, uploadType) {
|
||
err = gerror.New("上传类型是无效的")
|
||
return
|
||
}
|
||
|
||
file := r.GetUploadFile("file")
|
||
if file == nil {
|
||
err = gerror.New("没有找到上传的文件")
|
||
return
|
||
}
|
||
return service.CommonUpload().UploadFile(ctx, uploadType, file)
|
||
}
|
||
|
||
// UploadVideo 上传视频
|
||
func (c *cUpload) UploadVideo(ctx context.Context, _ *common.UploadVideoReq) (res common.UploadVideoRes, err error) {
|
||
r := g.RequestFromCtx(ctx)
|
||
uploadType := r.Header.Get("uploadType")
|
||
if uploadType != "default" && !validate.InSlice(storager.KindSlice, uploadType) {
|
||
err = gerror.New("上传类型是无效的")
|
||
return
|
||
}
|
||
|
||
file := r.GetUploadFile("file")
|
||
if file == nil {
|
||
err = gerror.New("没有找到上传的文件")
|
||
return
|
||
}
|
||
|
||
// 1. 保存上传视频到本地临时目录
|
||
tmpDir := "./tmp/video"
|
||
_, _ = file.Save(tmpDir)
|
||
tmpFile := tmpDir + "/" + file.Filename
|
||
|
||
// 2. 用ffmpeg切片为m3u8和ts文件
|
||
|
||
m3u8UUID := uuid.New().String()
|
||
|
||
hlsDir := "./tmp/hls/" + m3u8UUID
|
||
_ = os.MkdirAll(hlsDir, 0755)
|
||
|
||
defer func() {
|
||
os.RemoveAll(hlsDir)
|
||
}()
|
||
|
||
m3u8File := m3u8UUID + ".m3u8"
|
||
m3u8Path := hlsDir + "/" + m3u8File
|
||
ffmpegCmd := exec.Command("ffmpeg", "-i", tmpFile, "-c:v", "libx264", "-hls_time", "10", "-hls_playlist_type", "vod", m3u8Path)
|
||
err = ffmpegCmd.Run()
|
||
if err != nil {
|
||
err = gerror.Wrap(err, "ffmpeg切片失败")
|
||
return
|
||
}
|
||
|
||
// 3. 遍历切片目录,上传所有m3u8和ts文件到minio
|
||
minioDrive := new(storager.MinioDrive)
|
||
var m3u8MinioPath string
|
||
files, _ := filepath.Glob(hlsDir + "/*")
|
||
for _, f := range files {
|
||
fileInfo, errStat := os.Stat(f)
|
||
if errStat == nil && !fileInfo.IsDir() {
|
||
minioPath, err2 := minioDrive.UploadFromPath(ctx, f, filepath.Base(f))
|
||
if err2 != nil {
|
||
err = err2
|
||
return
|
||
}
|
||
if filepath.Ext(f) == ".m3u8" {
|
||
m3u8MinioPath = minioPath
|
||
}
|
||
}
|
||
}
|
||
|
||
// 4. 返回m3u8文件的minio路径
|
||
return common.UploadVideoRes{
|
||
Path: m3u8MinioPath,
|
||
}, nil
|
||
}
|
||
|
||
// CheckMultipart 检查文件分片
|
||
func (c *cUpload) CheckMultipart(ctx context.Context, req *common.CheckMultipartReq) (res *common.CheckMultipartRes, err error) {
|
||
data, err := service.CommonUpload().CheckMultipart(ctx, &req.CheckMultipartInp)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
res = new(common.CheckMultipartRes)
|
||
res.CheckMultipartModel = data
|
||
return
|
||
}
|
||
|
||
// UploadPart 上传分片
|
||
func (c *cUpload) UploadPart(ctx context.Context, req *common.UploadPartReq) (res *common.UploadPartRes, err error) {
|
||
data, err := service.CommonUpload().UploadPart(ctx, &req.UploadPartInp)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
res = new(common.UploadPartRes)
|
||
res.UploadPartModel = data
|
||
return
|
||
}
|