forked from asticode/go-astiav
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
114 lines (97 loc) · 2.38 KB
/
main.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
package main
import (
"errors"
"flag"
"fmt"
"log"
"os"
"strings"
"github.com/asticode/go-astiav"
)
var (
input = flag.String("i", "", "the input path")
)
func main() {
// Handle ffmpeg logs
astiav.SetLogLevel(astiav.LogLevelDebug)
astiav.SetLogCallback(func(c astiav.Classer, l astiav.LogLevel, fmt, msg string) {
var cs string
if c != nil {
if cl := c.Class(); cl != nil {
cs = " - class: " + cl.String()
}
}
log.Printf("ffmpeg log: %s%s - level: %d\n", strings.TrimSpace(msg), cs, l)
})
// Parse flags
flag.Parse()
// Usage
if *input == "" {
log.Println("Usage: <binary path> -i <input path>")
return
}
// Allocate packet
pkt := astiav.AllocPacket()
defer pkt.Free()
// Allocate input format context
inputFormatContext := astiav.AllocFormatContext()
if inputFormatContext == nil {
log.Fatal(errors.New("main: input format context is nil"))
}
defer inputFormatContext.Free()
// Open file
f, err := os.Open(*input)
if err != nil {
log.Fatal(fmt.Errorf("main: opening %s failed: %w", *input, err))
}
defer f.Close()
// Allocate io context
ioContext, err := astiav.AllocIOContext(
4096,
false,
func(b []byte) (n int, err error) {
return f.Read(b)
},
func(offset int64, whence int) (n int64, err error) {
return f.Seek(offset, whence)
},
nil,
)
if err != nil {
log.Fatal(fmt.Errorf("main: allocating io context failed: %w", err))
}
defer ioContext.Free()
// Store io context
inputFormatContext.SetPb(ioContext)
// Open input
if err := inputFormatContext.OpenInput("", nil, nil); err != nil {
log.Fatal(fmt.Errorf("main: opening input failed: %w", err))
}
defer inputFormatContext.CloseInput()
// Find stream info
if err := inputFormatContext.FindStreamInfo(nil); err != nil {
log.Fatal(fmt.Errorf("main: finding stream info failed: %w", err))
}
// Loop through packets
for {
// We use a closure to ease unreferencing the packet
if stop := func() bool {
// Read frame
if err := inputFormatContext.ReadFrame(pkt); err != nil {
if errors.Is(err, astiav.ErrEof) {
return true
}
log.Fatal(fmt.Errorf("main: reading frame failed: %w", err))
}
// Make sure to unreference the packet
defer pkt.Unref()
// Do something with the packet
log.Printf("new packet: stream %d - pts: %d", pkt.StreamIndex(), pkt.Pts())
return false
}(); stop {
break
}
}
// Success
log.Println("success")
}