go服务通过mediainfo获取媒体信息(图片、音/视频)
一、安装mediainfo
二、go 程序
package shellservice import ( "bytes" "encoding/json" "errors" "fmt" "log" //todo 需要替换为自己的日志库 "math" "os/exec" "context" "strconv" "time" ) func ShellExec(ctx context.Context, cmd string, timeout time.Duration) ([]byte, error) { if timeout < 1 { timeout = 600*time.Second //默认十分钟后超时取消 } cctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() process := exec.CommandContext(cctx, "/bin/bash", "-c", cmd) var b bytes.Buffer process.Stdout = &b process.Stderr = &b err := process.Run() if err != nil { log.InfoWithCtx(ctx, "ShellExec exec.Command err:%s, out:%s", err, string(b.Bytes())) return nil, err } return b.Bytes(), nil } type MediaInfoResp struct { VideoMeta *VideoMeta `json:"video_meta"` ImageMeta *ImageMeta `json:"image_meta"` FileMeta *FileMeta `json:"file_meta"` } type ImageMeta struct { Width int `json:"width"` Height int `json:"height"` } type FileMeta struct { FileSize int64 `json:"file_size"` FileExt string `json:"file_ext"` } type VideoMeta struct { Duration float64 `json:"duration"` } type MediaInfo struct { Media *MediaItem `json:"media"` } type MediaItem struct { Track []map[string]interface{} `json:"track"` }
//cmd := fmt.Sprintf(`ffprobe -v quiet -print_format json=compact=1 -show_format -show_streams -i "%s"`, param.FileUrl) func MediaInfoTask(ctx context.Context, fileUri string) (*MediaInfoResp, error) { cmd := fmt.Sprintf(`mediainfo --output="JSON" "%s"`, fileUri) body, err := ShellExec(ctx, cmd, 0) if err != nil { errMsg := fmt.Sprintf(`{"code":"98", "msg":"Process exception, info:%v"}`, err.Error()) return nil, errors.New(errMsg) } log.InfoWithCtx(ctx, "mediaInfoTask info: %s", string(body)) info := &MediaInfo{} err = json.Unmarshal(body, info) if err != nil { errMsg := fmt.Sprintf(`{"code":"98", "msg":"Process exception, info:%v"}`, err.Error()) return nil, errors.New(errMsg) } if info.Media == nil || len(info.Media.Track) < 1 { return nil, errors.New(`{"code":"98", "msg":"Process exception, mediainfo is nil"}`) } result := &MediaInfoResp{VideoMeta: &VideoMeta{}} for _, mi := range info.Media.Track { mediaType, ok := mi["@type"] if !ok { continue } var duration float64 mType, ok := mediaType.(string) if !ok { continue } var width, height int if mType == "Video" { if _, ok := mi["Duration"]; ok { duration, _ = strconv.ParseFloat(mi["Duration"].(string), 64) duration = duration * 1000 //转成毫秒 duration = math.Floor(duration) } result.VideoMeta = &VideoMeta{ Duration: duration, } } else if mType == "Image" { if _, ok := mi["Width"]; ok { width, _ = strconv.Atoi(mi["Width"].(string)) } if _, ok := mi["Height"]; ok { height, _ = strconv.Atoi(mi["Height"].(string)) } result.ImageMeta = &ImageMeta{ Width: width, Height: height, } } else if mType == "General" { var fileSize int64 var fileExt string if _, ok := mi["FileSize"]; ok { fileSize, _ = strconv.ParseInt(mi["FileSize"].(string), 10, 64) } if _, ok := mi["FileExtension"]; ok { fileExt = mi["FileExtension"].(string) } result.FileMeta = &FileMeta{ FileSize: fileSize, FileExt: fileExt, } } } return result, nil }

浙公网安备 33010602011771号