mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-16 13:00:58 +08:00
port more examples over to new generated bindings
plugins not yet working, examples mostly untested
This commit is contained in:
@@ -17,57 +17,43 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/go-gst/go-glib/glib"
|
||||
"github.com/go-gst/go-gst/examples"
|
||||
"github.com/go-gst/go-gst/gst"
|
||||
"github.com/go-gst/go-gst/pkg/gst"
|
||||
)
|
||||
|
||||
func tagsetter(mainLoop *glib.MainLoop) error {
|
||||
gst.Init(nil)
|
||||
func tagsetter() error {
|
||||
gst.Init()
|
||||
|
||||
if len(os.Args) < 2 {
|
||||
return errors.New("usage: toc <file>")
|
||||
}
|
||||
|
||||
pipeline, err := gst.NewPipeline("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pipeline := gst.NewPipeline("")
|
||||
|
||||
src, err := gst.NewElement("filesrc")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
decodebin, err := gst.NewElement("decodebin")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
src := gst.ElementFactoryMake("filesrc", "")
|
||||
|
||||
src.SetProperty("location", os.Args[1])
|
||||
decodebin := gst.ElementFactoryMake("decodebin", "")
|
||||
|
||||
src.SetObjectProperty("location", os.Args[1])
|
||||
|
||||
pipeline.AddMany(src, decodebin)
|
||||
gst.ElementLinkMany(src, decodebin)
|
||||
gst.LinkMany(src, decodebin)
|
||||
|
||||
// Connect to decodebin's pad-added signal, that is emitted whenever it found another stream
|
||||
// from the input file and found a way to decode it to its raw format.
|
||||
decodebin.Connect("pad-added", func(_ *gst.Element, srcPad *gst.Pad) {
|
||||
decodebin.ConnectPadAdded(func(srcPad *gst.Pad) {
|
||||
|
||||
// In this example, we are only interested about parsing the ToC, so
|
||||
// we simply pipe every encountered stream into a fakesink, essentially
|
||||
// throwing away the data.
|
||||
elems, err := gst.NewElementMany("queue", "fakesink")
|
||||
if err != nil {
|
||||
fmt.Println("Could not create decodebin pipeline")
|
||||
return
|
||||
}
|
||||
pipeline.AddMany(elems...)
|
||||
gst.ElementLinkMany(elems...)
|
||||
for _, e := range elems {
|
||||
e.SyncStateWithParent()
|
||||
}
|
||||
queue := gst.ElementFactoryMake("queue", "")
|
||||
fakesink := gst.ElementFactoryMake("fakesink", "")
|
||||
|
||||
queue := elems[0]
|
||||
sinkPad := queue.GetStaticPad("sink")
|
||||
pipeline.AddMany(queue, fakesink)
|
||||
gst.LinkMany(queue, fakesink)
|
||||
queue.SyncStateWithParent()
|
||||
fakesink.SyncStateWithParent()
|
||||
|
||||
sinkPad := queue.StaticPad("sink")
|
||||
if sinkPad == nil {
|
||||
fmt.Println("Could not get static pad from sink")
|
||||
return
|
||||
@@ -77,8 +63,8 @@ func tagsetter(mainLoop *glib.MainLoop) error {
|
||||
Link(sinkPad)
|
||||
})
|
||||
|
||||
if err := pipeline.SetState(gst.StatePaused); err != nil {
|
||||
return err
|
||||
if ret := pipeline.BlockSetState(gst.StatePaused, gst.ClockTime(time.Second)); ret != gst.StateChangeSuccess {
|
||||
return fmt.Errorf("could not change state")
|
||||
}
|
||||
|
||||
// Instead of using the main loop, we manually iterate over GStreamer's bus messages
|
||||
@@ -87,37 +73,32 @@ func tagsetter(mainLoop *glib.MainLoop) error {
|
||||
// timed_pop on the bus with the desired timeout for when to stop waiting for new messages.
|
||||
// (-1 = Wait forever)
|
||||
for {
|
||||
msg := pipeline.GetPipelineBus().TimedPop(gst.ClockTimeNone)
|
||||
msg := pipeline.Bus().TimedPop(gst.ClockTimeNone)
|
||||
switch msg.Type() {
|
||||
|
||||
// When we use this method of popping from the bus (instead of a Watch), we own a
|
||||
// reference to every message received (this may be abstracted later).
|
||||
default:
|
||||
// fmt.Println(msg)
|
||||
msg.Unref()
|
||||
|
||||
// End of stream
|
||||
case gst.MessageEOS:
|
||||
msg.Unref()
|
||||
|
||||
case gst.MessageEos:
|
||||
// Errors from any elements
|
||||
case gst.MessageError:
|
||||
gerr := msg.ParseError()
|
||||
if debug := gerr.DebugString(); debug != "" {
|
||||
gerr, debug := msg.ParseError()
|
||||
if debug != "" {
|
||||
fmt.Println("go-gst-debug:", debug)
|
||||
}
|
||||
msg.Unref()
|
||||
return gerr
|
||||
|
||||
// Some element found a ToC in the current media stream and told
|
||||
// us by posting a message to GStreamer's bus.
|
||||
case gst.MessageTOC:
|
||||
case gst.MessageToc:
|
||||
// Parse the toc from the message
|
||||
toc, updated := msg.ParseTOC()
|
||||
msg.Unref()
|
||||
fmt.Printf("Received toc: %s - updated %v\n", toc.GetScope(), updated)
|
||||
toc, updated := msg.ParseToc()
|
||||
fmt.Printf("Received toc: %s - updated %v\n", toc.Scope().String(), updated)
|
||||
// Get a list of tags that are ToC specific.
|
||||
if tags := toc.GetTags(); tags != nil {
|
||||
if tags := toc.Tags(); tags != nil {
|
||||
fmt.Println("- tags:", tags)
|
||||
}
|
||||
// ToCs do not have a fixed structure. Depending on the format that
|
||||
@@ -127,43 +108,41 @@ func tagsetter(mainLoop *glib.MainLoop) error {
|
||||
// interpreting the ToC manually.
|
||||
// In this example, we simply want to print the ToC structure, so
|
||||
// we iterate everything and don't try to interpret anything.
|
||||
for _, entry := range toc.GetEntries() {
|
||||
for _, entry := range toc.Entries() {
|
||||
// Every entry in a ToC has its own type. One type could for
|
||||
// example be Chapter.
|
||||
fmt.Printf("\t%s - %s\n", entry.GetEntryTypeString(), entry.GetUID())
|
||||
fmt.Printf("\t%s - %s\n", entry.EntryType().String(), entry.Uid())
|
||||
|
||||
// Every ToC entry can have a set of timestamps (start, stop).
|
||||
if ok, start, stop := entry.GetStartStopTimes(); ok {
|
||||
if start, stop, ok := entry.StartStopTimes(); ok {
|
||||
startDur := time.Duration(start) * time.Nanosecond
|
||||
stopDur := time.Duration(stop) * time.Nanosecond
|
||||
fmt.Printf("\t- start: %s, stop: %s\n", startDur, stopDur)
|
||||
}
|
||||
|
||||
// Every ToC entry can have tags to it.
|
||||
if tags := entry.GetTags(); tags != nil {
|
||||
if tags := entry.Tags(); tags != nil {
|
||||
fmt.Println("\t- tags:", tags)
|
||||
}
|
||||
|
||||
// Every ToC entry can have a set of child entries.
|
||||
// With this structure, you can create trees of arbitrary depth.
|
||||
for _, subEntry := range entry.GetSubEntries() {
|
||||
fmt.Printf("\n\t\t%s - %s\n", subEntry.GetEntryTypeString(), subEntry.GetUID())
|
||||
if ok, start, stop := entry.GetStartStopTimes(); ok {
|
||||
for _, subEntry := range entry.SubEntries() {
|
||||
fmt.Printf("\n\t\t%s - %s\n", subEntry.EntryType().String(), subEntry.Uid())
|
||||
if start, stop, ok := entry.StartStopTimes(); ok {
|
||||
startDur := time.Duration(start) * time.Nanosecond
|
||||
stopDur := time.Duration(stop) * time.Nanosecond
|
||||
fmt.Printf("\t\t- start: %s, stop: %s\n", startDur, stopDur)
|
||||
}
|
||||
if tags := entry.GetTags(); tags != nil {
|
||||
if tags := entry.Tags(); tags != nil {
|
||||
fmt.Println("\t\t- tags:", tags)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
toc.Unref()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
examples.RunLoop(tagsetter)
|
||||
tagsetter()
|
||||
}
|
||||
|
Reference in New Issue
Block a user