/
webm2seq.go
107 lines (99 loc) · 1.95 KB
/
webm2seq.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
104
105
106
107
package main
import (
"bufio"
"github.com/jacereda/webm"
"flag"
"fmt"
"image"
"image/jpeg"
"image/png"
"io"
"log"
"os"
"runtime"
)
type encjob struct {
path string
img image.Image
}
var (
in = flag.String("i", "", "Input file")
out = flag.String("o", "", "Output prefix")
format = flag.String("f", "png", "Output format")
encoders = flag.Int("j", 4, "Number of parallel encoders")
chans []chan encjob
endchans []chan int
)
func jpegenc(w io.Writer, img image.Image) error {
return jpeg.Encode(w, img, nil)
}
func pngenc(w io.Writer, img image.Image) error {
return png.Encode(w, img)
}
func encoder(ch <-chan encjob, ech chan<- int) {
var enc func(io.Writer, image.Image) error
switch *format {
case "jpeg", "jpg":
enc = jpegenc
case "png":
enc = pngenc
default:
log.Panic("Unsupported output format")
}
for job := range ch {
f, err := os.Create(job.path)
bf := bufio.NewWriter(f)
if err != nil {
log.Panic("unable to open file " + *out)
}
enc(bf, job.img)
f.Close()
}
close(ech)
}
func write(ch <-chan webm.Frame) {
i := 0
for frame := range ch {
if *out != "" {
job := encjob{fmt.Sprint(*out, i, ".", *format), frame}
chans[i%*encoders] <- job
runtime.GC()
}
i++
}
for _, ch := range chans {
close(ch)
}
for _, ech := range endchans {
<-ech
}
}
func main() {
flag.Parse()
if *in == "" {
flag.Usage()
return
}
for i := 0; i < *encoders; i++ {
ch := make(chan encjob, 0)
chans = append(chans, ch)
ech := make(chan int, 0)
endchans = append(endchans, ech)
go encoder(ch, ech)
}
r, err := os.Open(*in)
defer r.Close()
if err != nil {
log.Fatalf("Unable to open file '%s'", *in)
}
var wm webm.WebM
reader, err := webm.Parse(r, &wm)
if err != nil {
log.Fatal("Unable to parse file: ", err)
}
vtrack := wm.FindFirstVideoTrack()
vstream := webm.NewStream(vtrack)
splitter := webm.NewSplitter(reader.Chan)
splitter.Split(vstream)
write(vstream.VideoChannel())
}