123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- 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" {
- duration, err = GetMP3PlayDuration(reader)
- }
- 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
- }
- // GetMP3PlayDuration 获取mp3时长,以秒计
- func GetMP3PlayDuration(reader multipart.File) (seconds int, err error) {
- return 0, nil
- //buf := bytes.NewBuffer(nil)
- //if _, err := io.Copy(buf, reader); err != nil {
- // return 0, err
- //}
- //mp3Data := buf.Bytes()
- //dec, _, err := minimp3.DecodeFull(mp3Data)
- //if err != nil {
- // return 0, err
- //}
- //// 音乐时长 = (文件大小(byte) - 128(ID3信息)) * 8(to bit) / (码率(kbps b:bit) * 1000)(kilo bit to bit)
- //seconds = (len(mp3Data) - 128) * 8 / (dec.Kbps * 1000)
- //return seconds, nil
- }
- // 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
- }
|