Live video on the AT Protocol
1package main
2
3import (
4 "flag"
5 "fmt"
6 "log"
7 "os"
8 "runtime"
9 "syscall"
10 "time"
11
12 "github.com/go-gst/go-glib/glib"
13 "github.com/go-gst/go-gst/gst"
14)
15
16// Demonstration of a GStreamer (or go-gst idk) leak
17
18func main() {
19 flag.Parse()
20 if flag.NArg() != 1 {
21 log.Fatal("expected 1 argument")
22 }
23 os.Setenv("GST_DEBUG", "leaks:9,GST_TRACER:9")
24 os.Setenv("GST_TRACERS", "leaks")
25 os.Setenv("GST_LEAKS_TRACER_SIG", "1")
26 err := RunPipeline(flag.Arg(0))
27 if err != nil {
28 log.Fatal(err)
29 }
30 runtime.GC()
31 time.Sleep(1 * time.Second)
32 process, err := os.FindProcess(os.Getpid())
33 if err != nil {
34 log.Fatal(err)
35 }
36 if err := process.Signal(syscall.SIGUSR1); err != nil {
37 log.Fatal(err)
38 }
39 time.Sleep(1 * time.Second)
40}
41
42func RunPipeline(file string) error {
43 gst.Init(nil)
44 pipeline, err := gst.NewPipelineFromString(fmt.Sprintf("filesrc location=%s ! qtdemux ! fakesink", file))
45 if err != nil {
46 return fmt.Errorf("failed to create pipeline: %w", err)
47 }
48
49 mainLoop := glib.NewMainLoop(glib.MainContextDefault(), false)
50 if err := pipeline.BlockSetState(gst.StatePlaying); err != nil {
51 return fmt.Errorf("failed to set pipeline state: %w", err)
52 }
53
54 pipeline.GetBus().AddWatch(func(msg *gst.Message) bool {
55 if msg.Type() == gst.MessageEOS {
56 mainLoop.Quit()
57 return false
58 }
59 return true
60 })
61
62 mainLoop.Run()
63
64 if err := pipeline.BlockSetState(gst.StateNull); err != nil {
65 return fmt.Errorf("failed to set pipeline state: %w", err)
66 }
67
68 return nil
69}