-
Notifications
You must be signed in to change notification settings - Fork 0
/
video-to-jpeg.go
117 lines (89 loc) · 2.1 KB
/
video-to-jpeg.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
108
109
110
111
112
113
114
115
116
117
package main
import (
"log"
"os"
"runtime/debug"
"strconv"
. "github.com/3d0c/gmf"
)
func fatal(err error) {
debug.PrintStack()
log.Fatal(err)
}
func assert(i interface{}, err error) interface{} {
if err != nil {
fatal(err)
}
return i
}
var i int = 0
func writeFile(b []byte) {
name := "./tmp/" + strconv.Itoa(i) + ".jpg"
fp, err := os.Create(name)
if err != nil {
fatal(err)
}
defer func() {
if err := fp.Close(); err != nil {
fatal(err)
}
i++
}()
if n, err := fp.Write(b); err != nil {
fatal(err)
} else {
log.Println(n, "bytes written to", name)
}
}
func main() {
srcFileName := "tests-sample.mp4"
os.Mkdir("./tmp", 0755)
if len(os.Args) > 1 {
srcFileName = os.Args[1]
}
inputCtx := assert(NewInputCtx(srcFileName)).(*FmtCtx)
defer inputCtx.CloseInputAndRelease()
srcVideoStream, err := inputCtx.GetBestStream(AVMEDIA_TYPE_VIDEO)
if err != nil {
log.Println("No video stream found in", srcFileName)
}
codec, err := FindEncoder(AV_CODEC_ID_JPEG2000)
if err != nil {
fatal(err)
}
cc := NewCodecCtx(codec)
defer Release(cc)
cc.SetPixFmt(AV_PIX_FMT_RGB24).SetWidth(srcVideoStream.CodecCtx().Width()).SetHeight(srcVideoStream.CodecCtx().Height())
if codec.IsExperimental() {
cc.SetStrictCompliance(FF_COMPLIANCE_EXPERIMENTAL)
}
if err := cc.Open(nil); err != nil {
fatal(err)
}
swsCtx := NewSwsCtx(srcVideoStream.CodecCtx(), cc, SWS_BICUBIC)
defer Release(swsCtx)
dstFrame := NewFrame().
SetWidth(srcVideoStream.CodecCtx().Width()).
SetHeight(srcVideoStream.CodecCtx().Height()).
SetFormat(AV_PIX_FMT_RGB24)
defer Release(dstFrame)
if err := dstFrame.ImgAlloc(); err != nil {
fatal(err)
}
for packet := range inputCtx.GetNewPackets() {
if packet.StreamIndex() != srcVideoStream.Index() {
// skip non video streams
continue
}
ist := assert(inputCtx.GetStream(packet.StreamIndex())).(*Stream)
for frame := range packet.Frames(ist.CodecCtx()) {
swsCtx.Scale(frame, dstFrame)
if p, ready, _ := dstFrame.EncodeNewPacket(cc); ready {
writeFile(p.Data())
defer Release(p)
}
}
Release(packet)
}
Release(dstFrame)
}