package soundbox /* #cgo pkg-config: libpipewire-0.3 #include "pipewire-binding.h" */ import "C" import ( "bytes" "context" "io" "net" "log" "os/exec" "unsafe" ) var pipewireAudio = make(chan []byte, 5) func StreamPipewireContext(ctx context.Context, targets []net.HardwareAddr) error { cmd := exec.CommandContext( ctx, "ffmpeg", "-ac", "2", "-ar", "48000", "-f", "s16le", "-channel_layout", "stereo", "-i", "-", "-acodec", "flac", "-f", "ogg", "-", ) stdout, err := cmd.StdoutPipe() if err != nil { return err } stdin, err := cmd.StdinPipe() if err != nil { return err } go C.pw_stdout() go func() { for buffer := range pipewireAudio { tempReader := bytes.NewReader(buffer) _, err := io.Copy(stdin, tempReader) if err != nil { log.Println("Failed to copy from PipeWire to ffmpeg.") break } } }() err = cmd.Start() if err != nil { return err } err = streamContext(ctx, stdout, targets) if err != nil { return err } return cmd.Wait() } //export goHandleData func goHandleData(data *C.int16_t, size C.size_t) { buf := C.GoBytes(unsafe.Pointer(data), C.int(size)) pipewireAudio <- buf }