-
Notifications
You must be signed in to change notification settings - Fork 71
/
transcoding.go
103 lines (95 loc) · 2.58 KB
/
transcoding.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main
import (
"flag"
"fmt"
"os"
"strings"
"time"
"github.com/livepeer/lpms/ffmpeg"
)
func validRenditions() []string {
valids := make([]string, len(ffmpeg.VideoProfileLookup))
for p := range ffmpeg.VideoProfileLookup {
valids = append(valids, p)
}
return valids
}
func main() {
from := flag.Duration("from", 0, "Skip all frames before that timestamp, from start of the file")
hevc := flag.Bool("hevc", false, "Use H.265/HEVC for encoding")
to := flag.Duration("to", 0, "Skip all frames after that timestamp, from start of the file")
flag.Parse()
var err error
args := append([]string{os.Args[0]}, flag.Args()...)
if len(args) <= 3 {
panic("Usage: [-hevc] [-from dur] [-to dur] <input file> <output renditions, comma separated> <sw/nv/nt>")
}
str2accel := func(inp string) (ffmpeg.Acceleration, string) {
if inp == "nv" {
return ffmpeg.Nvidia, "nv"
}
if inp == "nt" {
return ffmpeg.Netint, "nt"
}
return ffmpeg.Software, "sw"
}
str2profs := func(inp string) []ffmpeg.VideoProfile {
profs := []ffmpeg.VideoProfile{}
strs := strings.Split(inp, ",")
for _, k := range strs {
p, ok := ffmpeg.VideoProfileLookup[k]
if !ok {
panic(fmt.Sprintf("Invalid rendition %s. Valid renditions are:\n%s", k, validRenditions()))
}
if *hevc {
p.Encoder = ffmpeg.H265
} else {
p.Profile = ffmpeg.ProfileH264High
}
profs = append(profs, p)
}
return profs
}
fname := args[1]
profiles := str2profs(args[2])
accel, lbl := str2accel(args[3])
profs2opts := func(profs []ffmpeg.VideoProfile) []ffmpeg.TranscodeOptions {
opts := []ffmpeg.TranscodeOptions{}
for i := range profs {
o := ffmpeg.TranscodeOptions{
Oname: fmt.Sprintf("out_%s_%d_out.mp4", lbl, i),
Profile: profs[i],
Accel: accel,
}
o.From = *from
o.To = *to
opts = append(opts, o)
}
return opts
}
options := profs2opts(profiles)
var dev string
if accel != ffmpeg.Software {
if len(args) <= 4 {
panic("Expected device number")
}
dev = args[4]
}
ffmpeg.InitFFmpeg()
t := time.Now()
fmt.Printf("Setting fname %s encoding %d renditions with %v from %s to %s\n", fname, len(options), lbl, *from, *to)
res, err := ffmpeg.Transcode3(&ffmpeg.TranscodeOptionsIn{
Fname: fname,
Accel: accel,
Device: dev,
}, options)
if err != nil {
panic(err)
}
end := time.Now()
fmt.Printf("profile=input frames=%v pixels=%v\n", res.Decoded.Frames, res.Decoded.Pixels)
for i, r := range res.Encoded {
fmt.Printf("profile=%v frames=%v pixels=%v\n", profiles[i].Name, r.Frames, r.Pixels)
}
fmt.Printf("Transcoding time %0.4v\n", end.Sub(t).Seconds())
}