|
@@ -1,6 +1,8 @@
|
|
|
package controllers
|
|
|
|
|
|
import (
|
|
|
+ "bytes"
|
|
|
+ "encoding/binary"
|
|
|
"encoding/json"
|
|
|
"eta/eta_mini_crm_ht/models"
|
|
|
"eta/eta_mini_crm_ht/models/request"
|
|
@@ -10,6 +12,7 @@ import (
|
|
|
"eta/eta_mini_crm_ht/utils"
|
|
|
"fmt"
|
|
|
"github.com/rdlucklib/rdluck_tools/paging"
|
|
|
+ "io"
|
|
|
"math/rand"
|
|
|
"os"
|
|
|
"path"
|
|
@@ -72,6 +75,18 @@ func (this *VideoController) UploadVideo() {
|
|
|
br.ErrMsg = "视频上传失败,Err:" + err.Error()
|
|
|
return
|
|
|
}
|
|
|
+ duration, err := GetMP4Duration(f)
|
|
|
+ if err != nil {
|
|
|
+ br.Msg = "视频上传失败"
|
|
|
+ br.ErrMsg = "获取MP4时长失败,Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ br.Msg = "音频上传失败"
|
|
|
+ br.ErrMsg = "解析音频时常失败,Err:" + err.Error()
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
audioUploadDir := utils.RESOURCE_DIR + "video/"
|
|
|
savePdfToOssPath := audioUploadDir + time.Now().Format("200601/20060102/")
|
|
|
audioName := utils.GetRandStringNoSpecialChar(28)
|
|
@@ -97,6 +112,7 @@ func (this *VideoController) UploadVideo() {
|
|
|
resp := new(response.MediaUploadResp)
|
|
|
resp.Url = mp3Url
|
|
|
resp.FileName = base
|
|
|
+ resp.DurationMillisecond = duration * 1000
|
|
|
br.Data = resp
|
|
|
br.Msg = "上传成功"
|
|
|
br.Ret = 200
|
|
@@ -138,6 +154,10 @@ func (this *VideoController) AddVideo() {
|
|
|
br.Msg = "视频地址为空"
|
|
|
return
|
|
|
}
|
|
|
+ if req.DurationMillisecond == 0 {
|
|
|
+ br.Msg = "视频时长为空"
|
|
|
+ return
|
|
|
+ }
|
|
|
var err error
|
|
|
var coverSrc int
|
|
|
permissions := strings.Split(req.PermissionIds, ",")
|
|
@@ -238,6 +258,10 @@ func (this *VideoController) EditVideo() {
|
|
|
br.Msg = "视频地址为空"
|
|
|
return
|
|
|
}
|
|
|
+ if req.DurationMillisecond == 0 {
|
|
|
+ br.Msg = "视频时长为空"
|
|
|
+ return
|
|
|
+ }
|
|
|
var err error
|
|
|
|
|
|
audioEdit := &models.Media{
|
|
@@ -384,3 +408,79 @@ func (this *VideoController) VideoList() {
|
|
|
br.Data = resp
|
|
|
br.Msg = "获取成功"
|
|
|
}
|
|
|
+
|
|
|
+type BoxHeader struct {
|
|
|
+ Size uint32
|
|
|
+ FourccType [4]byte
|
|
|
+ Size64 uint64
|
|
|
+}
|
|
|
+
|
|
|
+// GetMP4Duration 获取视频时长,以秒计
|
|
|
+func GetMP4Duration(reader io.ReaderAt) (lengthOfTime int, err error) {
|
|
|
+ var info = make([]byte, 0x10)
|
|
|
+ var boxHeader BoxHeader
|
|
|
+ var offset int64 = 0
|
|
|
+ // 获取moov结构偏移
|
|
|
+ for {
|
|
|
+ _, err = reader.ReadAt(info, offset)
|
|
|
+ if err == io.EOF {
|
|
|
+ fmt.Println("Reached EOF without finding moov box.")
|
|
|
+ return 0, fmt.Errorf("moov box not found")
|
|
|
+ }
|
|
|
+ if err != nil {
|
|
|
+ return 0, fmt.Errorf("error reading at offset %d: %w", offset, err)
|
|
|
+ }
|
|
|
+
|
|
|
+ boxHeader = getHeaderBoxInfo(info)
|
|
|
+ fourccType := getFourccType(boxHeader)
|
|
|
+
|
|
|
+ if fourccType == "moov" {
|
|
|
+ fmt.Println("Found moov box at offset", offset)
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ nextOffset := int64(boxHeader.Size)
|
|
|
+ if fourccType == "mdat" && boxHeader.Size == 1 {
|
|
|
+ nextOffset = int64(boxHeader.Size64)
|
|
|
+ }
|
|
|
+ if nextOffset == 0 {
|
|
|
+ return 0, fmt.Errorf("box size is zero, which is invalid and likely means a parsing error")
|
|
|
+ }
|
|
|
+ offset += nextOffset
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取moov结构开头一部分
|
|
|
+ moovStartBytes := make([]byte, 0x100)
|
|
|
+ _, err = reader.ReadAt(moovStartBytes, offset)
|
|
|
+ if err != nil {
|
|
|
+ return 0, fmt.Errorf("error reading moov box at offset %d: %w", offset, err)
|
|
|
+ }
|
|
|
+ // 定义timeScale与Duration偏移
|
|
|
+ timeScaleOffset := 0x1C
|
|
|
+ durationOffset := 0x20
|
|
|
+ timeScale := binary.BigEndian.Uint32(moovStartBytes[timeScaleOffset : timeScaleOffset+4])
|
|
|
+ duration := binary.BigEndian.Uint32(moovStartBytes[durationOffset : durationOffset+4])
|
|
|
+
|
|
|
+ fmt.Printf("timeScale: %d, duration: %d\n", timeScale, duration)
|
|
|
+ if timeScale == 0 {
|
|
|
+ return 0, fmt.Errorf("timeScale is zero, division by zero is not possible")
|
|
|
+ }
|
|
|
+
|
|
|
+ lengthOfTime = int(duration / timeScale)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// getHeaderBoxInfo 获取头信息
|
|
|
+func getHeaderBoxInfo(data []byte) (boxHeader BoxHeader) {
|
|
|
+ buf := bytes.NewBuffer(data)
|
|
|
+ binary.Read(buf, binary.BigEndian, &boxHeader)
|
|
|
+ if boxHeader.Size == 1 { // Large Size
|
|
|
+ binary.Read(buf, binary.BigEndian, &boxHeader.Size64)
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+// getFourccType 获取信息头类型
|
|
|
+func getFourccType(boxHeader BoxHeader) (fourccType string) {
|
|
|
+ return string(boxHeader.FourccType[:])
|
|
|
+}
|