这是我参与「第五届青训营 」伴学笔记创作活动的第 8 天
这篇笔记是大项目的第二次总结,我会总结在大项目中遇到的一些技术问题以及解决方法
/douyin/publish/action 发表视频
上传视频
data, err := c.FormFile("data")
if err != nil {
c.JSON(http.StatusOK, model.Response{
StatusCode: 1,
StatusMsg: err.Error(),
})
return
}
filename := filepath.Base(data.Filename)
//user := usersLoginInfo[token]
//获取文件名后缀
fileSuffix := path.Ext(filename)
laststVideoId, err := dal.GetLatestVideoId(mysql.DB)
if err != nil {
c.JSON(http.StatusOK, model.Response{
StatusCode: 1,
StatusMsg: err.Error(),
})
return
}
//文件名为用户id_视频id.后缀
finalName := fmt.Sprintf("%d_%d%s", user.Id, laststVideoId+1, fileSuffix)
photoName := fmt.Sprintf("%d_%d", user.Id, laststVideoId+1)
fmt.Println(filename)
saveFile := filepath.Join("./public/video/", finalName)
if err := c.SaveUploadedFile(data, saveFile); err != nil {
c.JSON(http.StatusOK, model.Response{
StatusCode: 1,
StatusMsg: err.Error(),
})
return
}
dal.GetSnapshot("./public/video/"+finalName, "./public/photo/"+photoName, 1)
c.JSON(http.StatusOK, model.Response{
StatusCode: 0,
StatusMsg: finalName + " uploaded successfully",
})
1、使用hertz框架中的FormFile函数接收从前端发送来的文件(如果要上传多个文件,用MultipartForm函数)
2、使用hertz框架中的SaveUploadedFile将文件存到本地,它的参数是文件和保存路径。
上述代码中,我将上传的视频重命名为作者id_视频id.视频后缀,防止文件名的重复,获取后缀用了path.Ext函数。
为了获得视频封面,我用了GetSnapShot函数获取了视频的第一帧作为封面,GetSnapShot函数在下文叙述。
GetSnapShot函数
获取视频的第一帧用了FFmpeg模块。FFmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL或GPL许可证(依据你选择的组件)。它提供了录制、转换以及流化音视频的完整解决方案。
GetSnapShot函数的参数为视频路径,保存图片路径,截取的第几帧。返回值为图片名和error。
导入FFmpeg库
import (
"github.com/disintegration/imaging"
ffmpeg "github.com/u2takey/ffmpeg-go"
)
代码
package main
import (
"bytes"
"fmt"
"github.com/disintegration/imaging"
ffmpeg "github.com/u2takey/ffmpeg-go"
"log"
"os"
"strings"
)
func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) {
buf := bytes.NewBuffer(nil)
err = ffmpeg.Input(videoPath).
Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%d)", frameNum)}).
Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg"}).
WithOutput(buf, os.Stdout).
Run()
if err != nil {
log.Fatal("生成缩略图失败:", err)
return "", err
}
img, err := imaging.Decode(buf)
if err != nil {
log.Fatal("生成缩略图失败:", err)
return "", err
}
err = imaging.Save(img, snapshotPath+".png")
if err != nil {
log.Fatal("生成缩略图失败:", err)
return "", err
}
names := strings.Split(snapshotPath, "\\")
snapshotName = names[len(names)-1] + ".png"
return
}
func main() {
_, err := GetSnapshot("./test.mp4", "test", 1)
if err != nil {
return
}
}
通过上述代码,将函数的参数设为1,就可以得到视频第一帧的图片作为视频封面。
总结
以上就是我对大项目的一些总结,本人水平有限,如有错误欢迎指正。