123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package common
- import (
- "bytes"
- "encoding/binary"
- "mime/multipart"
- )
- // GetMediaDuration 得到媒体文件时长
- func GetMediaDuration(reader multipart.File, contentType string) (int, error) {
- var duration int
- var err error
- if contentType == "video/mp4" {
- duration, err = GetMP4Duration(reader)
- }
- if contentType == "audio/mpeg" {
- playDuration, _ := GetMP3PlayDuration(reader)
- duration = int(playDuration)
- }
- if err != nil {
- return 0, err
- }
- return duration * 1000, err
- }
- // GetMP4Duration 获取视频时长,以秒计
- func GetMP4Duration(reader multipart.File) (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 != nil {
- return
- }
- boxHeader = getHeaderBoxInfo(info)
- fourccType := getFourccType(boxHeader)
- if fourccType == "moov" {
- break
- }
- // 有一部分mp4 mdat尺寸过大需要特殊处理
- if fourccType == "mdat" {
- if boxHeader.Size == 1 {
- offset += int64(boxHeader.Size64)
- continue
- }
- }
- offset += int64(boxHeader.Size)
- }
- // 获取moov结构开头一部分
- moovStartBytes := make([]byte, 0x100)
- _, err = reader.ReadAt(moovStartBytes, offset)
- if err != nil {
- return
- }
- // 定义timeScale与Duration偏移
- timeScaleOffset := 0x1C
- durationOffest := 0x20
- timeScale := binary.BigEndian.Uint32(moovStartBytes[timeScaleOffset : timeScaleOffset+4])
- Duration := binary.BigEndian.Uint32(moovStartBytes[durationOffest : durationOffest+4])
- lengthOfTime = int(Duration / timeScale)
- return
- }
- // BoxHeader 信息头
- type BoxHeader struct {
- Size uint32
- FourccType [4]byte
- Size64 uint64
- }
- func getHeaderBoxInfo(data []byte) (boxHeader BoxHeader) {
- buf := bytes.NewBuffer(data)
- binary.Read(buf, binary.BigEndian, &boxHeader)
- return
- }
- // getFourccType 获取信息头类型
- func getFourccType(boxHeader BoxHeader) (fourccType string) {
- fourccType = string(boxHeader.FourccType[:])
- return
- }
|