mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-05 07:56:51 +08:00
add queries example
This commit is contained in:
103
examples/queries/main.go
Normal file
103
examples/queries/main.go
Normal file
@@ -0,0 +1,103 @@
|
||||
// This example demonstrates how to use GStreamer's query functionality.
|
||||
//
|
||||
// These are a way to query information from either elements or pads.
|
||||
// Such information could for example be the current position within
|
||||
// the stream (i.e. the playing time). Queries can traverse the pipeline
|
||||
// (both up and downstream). This functionality is essential, since most
|
||||
// queries can only answered by specific elements in a pipeline (such as the
|
||||
// stream's duration, which often can only be answered by the demuxer).
|
||||
// Since gstreamer has many elements that itself contain other elements that
|
||||
// we don't know of, we can simply send a query for the duration into the
|
||||
// pipeline and the query is passed along until an element feels capable
|
||||
// of answering.
|
||||
// For convenience, the API has a set of pre-defined queries, but also
|
||||
// allows custom queries (which can be defined and used by your own elements).
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/tinyzimmer/go-gst/examples"
|
||||
"github.com/tinyzimmer/go-gst/gst"
|
||||
)
|
||||
|
||||
func queries(mainLoop *gst.MainLoop) error {
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Println("USAGE: queries <pipeline>")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
gst.Init(nil)
|
||||
|
||||
// Let GStreamer create a pipeline from the parsed launch syntax on the cli.
|
||||
pipelineStr := strings.Join(os.Args[1:], " ")
|
||||
pipeline, err := gst.NewPipelineFromString(pipelineStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get a reference to the pipeline bus
|
||||
bus := pipeline.GetPipelineBus()
|
||||
|
||||
// Start the pipeline
|
||||
pipeline.SetState(gst.StatePlaying)
|
||||
|
||||
// Kick of a goroutine that will send a query to the pipeline
|
||||
// every second.
|
||||
go func() {
|
||||
for range time.NewTicker(time.Second).C {
|
||||
// Create a new position query and send it to the pipeline.
|
||||
// This will traverse all elements in the pipeline, until one feels
|
||||
// capable of answering the query.
|
||||
pos := gst.NewPositionQuery(gst.FormatTime)
|
||||
if ok := pipeline.Query(pos); !ok {
|
||||
fmt.Println("Failed to query position from pipeline")
|
||||
}
|
||||
// Create a new duration query and send it to the pipeline.
|
||||
// This will traverse all elements in the pipeline, until one feels
|
||||
// capable of answering the query.
|
||||
dur := gst.NewDurationQuery(gst.FormatTime)
|
||||
if ok := pipeline.Query(dur); !ok {
|
||||
fmt.Println("Failed to query duration from pipeline")
|
||||
}
|
||||
|
||||
// The values from the queries above are both in nanoseconds (this may be abstracted later).
|
||||
// We can convert them to durations.
|
||||
_, posVal := pos.ParsePosition() // If either of the above queries failed, these values
|
||||
_, durVal := dur.ParseDuration() // will be 0.
|
||||
posDur := time.Duration(posVal) * time.Nanosecond
|
||||
durDur := time.Duration(durVal) * time.Nanosecond
|
||||
|
||||
fmt.Println(posDur, "/", durDur)
|
||||
}
|
||||
}()
|
||||
|
||||
bus.AddWatch(func(msg *gst.Message) bool {
|
||||
switch msg.Type() {
|
||||
case gst.MessageEOS:
|
||||
mainLoop.Quit()
|
||||
case gst.MessageError:
|
||||
gstErr := msg.ParseError()
|
||||
fmt.Printf("Error from %s: %s\n", msg.Source(), gstErr.Error())
|
||||
if debug := gstErr.DebugString(); debug != "" {
|
||||
fmt.Println("go-gst-debug:", debug)
|
||||
}
|
||||
mainLoop.Quit()
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
mainLoop.Run()
|
||||
|
||||
bus.RemoveWatch()
|
||||
|
||||
return pipeline.Destroy()
|
||||
}
|
||||
|
||||
func main() {
|
||||
examples.RunLoop(queries)
|
||||
}
|
Reference in New Issue
Block a user