tinyzimmer / go-gst

Gstreamer bindings and utilities for golang
GNU Lesser General Public License v2.1
130 stars 37 forks source link

Appsink doesn't write until EOS #27

Closed real-danm closed 1 year ago

real-danm commented 2 years ago

Hello, I am attempting to do streaming uploads to gcp storage using an appsink. This code works with smaller files, however the appsink never writes until the EOS is received. I'm wondering if there is a way to make the appsink use the callback intermittently? I assumed it was a queue/buffer issue and have messed with the sizing there, but no luck.

    asink.SetCallbacks(&app.SinkCallbacks{
        EOSFunc: func(sink *app.Sink) {
            // Signal the pipeline that we've completed EOS.
            // (this should not be required, need to investigate)
            // pipeline.GetPipelineBus().Post(gst.NewEOSMessage(appSink))
        },
        NewSampleFunc: func(sink *app.Sink) gst.FlowReturn {
            // Pull the sample that triggered this callback
            sample := sink.PullSample()
            if sample == nil {
                return gst.FlowEOS
            }

            // Retrieve the buffer from the sample
            buffer := sample.GetBuffer()
            if buffer == nil {
                return gst.FlowError
            }

            fmt.Printf("Writing chunk\n")

            if _, err = io.Copy(wc, buffer.Reader()); err != nil {
                fmt.Errorf("io.Copy: %v", err)
            }
            fmt.Printf("%v uploaded to %v.\n", object, bucket)
            return gst.FlowOK
        },
    })

Thanks!

brucekim commented 2 years ago

Hello ~

How does it send data from buffer to gcp? I could not see relevant code in the example you post.

Since buffer is only reference, you may need to extract data from it. Following example explains how it does. https://github.com/tinyzimmer/go-gst/blob/5437f8a654ee228e8959fb52d6cbc6f5c14123a2/examples/appsink/main.go#L59-L71

How about to use 'Extract()' to copy data from the buffer as follow? In my case, it works well.

            // Retrieve the buffer from the sample
            buffer := sample.GetBuffer()
            if buffer == nil {
                return gst.FlowError
            }
            extracted := buffer.Extract(0, buffer.GetSize())
real-danm commented 2 years ago

I am using the code samples from google here: https://cloud.google.com/storage/docs/streaming#code-samples I have the pre-req auth, etc set up outside of the appsink callback.

This section grabs an io.Reader of the buffer and then copies it:

    if _, err = io.Copy(wc, buffer.Reader()); err != nil {
        fmt.Errorf("io.Copy: %v", err)
    }
RSWilli commented 1 year ago

@real-danm please move this issue to https://github.com/go-gst/go-gst (where future development of the bindings will take place) if you think it is still necessary.