forked from cajax/yami
-
Notifications
You must be signed in to change notification settings - Fork 0
/
yami.go
84 lines (69 loc) · 1.97 KB
/
yami.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//Package yami is a wrapper for mediainfo cli tool.
//It provides simple access to media details
package yami
import (
"bytes"
"context"
"encoding/xml"
"errors"
"os/exec"
"time"
)
var (
// ErrBinNotFound is returned when the mediainfo binary was not found
ErrBinNotFound = errors.New("mediainfo bin not found")
// ErrTimeout is returned when the mediainfo process did not succeed within the given time
ErrTimeout = errors.New("process timeout exceeded")
binPath = "mediainfo"
)
//SetMediainfoBinPath sets path to Mediainfo binary
func SetMediainfoBinPath(newBinPath string) {
binPath = newBinPath
}
//GetMediaInfo executes mediainfo with specific time limit and returns parsed output.
// You may provide additional arguments like --Language=raw or SSL options
func GetMediaInfo(filePath string, timeout time.Duration, arg ...string) (mediaInfo *MediaInfo, err error) {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
return GetMediaInfoContext(ctx, filePath, arg...)
}
//GetMediaInfoContext executes mediainfo with given context and returns parsed output.
// You may provide additional arguments like --Language=raw or SSL options
func GetMediaInfoContext(ctx context.Context, filePath string, arg ...string) (mediaInfo *MediaInfo, err error) {
Args := append([]string{"--Output=XML", "-f"}, arg...)
Args = append(Args, filePath)
cmd := exec.Command(
binPath,
Args...,
)
var outputBuf bytes.Buffer
cmd.Stdout = &outputBuf
err = cmd.Start()
if err == exec.ErrNotFound {
return nil, ErrBinNotFound
} else if err != nil {
return nil, err
}
done := make(chan error, 1)
go func() {
done <- cmd.Wait()
}()
select {
case <-ctx.Done():
err = cmd.Process.Kill()
if err == nil {
return nil, ErrTimeout
}
return nil, err
case err = <-done:
if err != nil {
return nil, err
}
}
mediaInfo = &MediaInfo{}
err = xml.Unmarshal(outputBuf.Bytes(), mediaInfo)
if err != nil {
return nil, err
}
return mediaInfo, nil
}