mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-05 07:56:51 +08:00
87 lines
3.2 KiB
Go
87 lines
3.2 KiB
Go
// This example demonstrates how events can be created and sent to the pipeline.
|
|
// What this example does is scheduling a timeout in a goroutine, and
|
|
// sending an EOS message on the bus from there - telling the pipeline
|
|
// to shut down. Once that event is processed by everything, the EOS message
|
|
// is going to be sent and we catch that one to shut down everything.
|
|
//
|
|
// GStreamer's bus is an abstraction layer above an arbitrary main loop.
|
|
// This makes sure that GStreamer can be used in conjunction with any existing
|
|
// other framework (GUI frameworks, mostly) that operate their own main loops.
|
|
// Main idea behind the bus is the simplification between the application and
|
|
// GStreamer, because GStreamer is heavily threaded underneath.
|
|
//
|
|
// Any thread can post messages to the bus, which is essentially a thread-safe
|
|
// queue of messages to process. When a new message was sent to the bus, it
|
|
// will wake up the main loop implementation underneath it (which will then
|
|
// process the pending messages from the main loop thread).
|
|
//
|
|
// An application itself can post messages to the bus aswell.
|
|
// This makes it possible, e.g., to schedule an arbitrary piece of code
|
|
// to run in the main loop thread - avoiding potential threading issues.
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/go-gst/go-gst/pkg/gst"
|
|
)
|
|
|
|
func main() {
|
|
gst.Init()
|
|
|
|
// Build a pipeline with fake audio data going to a fakesink
|
|
res, err := gst.ParseLaunch("audiotestsrc ! fakesink")
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
|
|
pipeline := res.(gst.Pipeline)
|
|
|
|
// Retrieve the message bus for the pipeline
|
|
bus := pipeline.GetBus()
|
|
|
|
// Start the pipeline
|
|
pipeline.SetState(gst.StatePlaying)
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
// Kick off a goroutine that after 5 seconds will send an eos event to the pipeline.
|
|
go func() {
|
|
for range time.NewTicker(time.Second * 5).C {
|
|
fmt.Println("Sending EOS")
|
|
// We create an EndOfStream event here, that tells all elements to drain
|
|
// their internal buffers to their following elements, essentially draining the
|
|
// whole pipeline (front to back). It ensuring that no data is left unhandled and potentially
|
|
// headers were rewritten (e.g. when using something like an MP4 or Matroska muxer).
|
|
// The EOS event is handled directly from this very goroutine until the first
|
|
// queue element is reached during pipeline-traversal, where it is then queued
|
|
// up and later handled from the queue's streaming thread for the elements
|
|
// following that queue.
|
|
// Once all sinks are done handling the EOS event (and all buffers that were before the
|
|
// EOS event in the pipeline already), the pipeline would post an EOS message on the bus,
|
|
// essentially telling the application that the pipeline is completely drained.
|
|
pipeline.SendEvent(gst.NewEventEOS())
|
|
return
|
|
}
|
|
}()
|
|
|
|
for msg := range bus.Messages(ctx) {
|
|
switch msg.Type() {
|
|
case gst.MessageEOS:
|
|
fmt.Println("Received EOS")
|
|
// An EndOfStream event was sent to the pipeline, so we tell our main loop
|
|
// to stop execution here.
|
|
cancel()
|
|
case gst.MessageError:
|
|
err, debug := msg.ParseError()
|
|
fmt.Println("ERROR:", err)
|
|
fmt.Println("DEBUG:", debug)
|
|
cancel()
|
|
}
|
|
}
|
|
}
|