io

package
v0.6.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2026 License: GPL-3.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ShellReader

type ShellReader struct {
	// contains filtered or unexported fields
}

ShellReader spawns a ffmpeg subprocess, exposes its stdout as a Reader, captures the tail of stderr in a fixed-size ring, and cleans up when the context is canceled or the process exits.

ShellReader is safe to use across goroutines for Close and Err. Read must be serialized by a single consumer (the convention for io.Reader).

We manage the stdout pipe ourselves (os.Pipe + cmd.Stdout = pw) rather than using cmd.StdoutPipe so that cmd.Wait does NOT close the read end out from under us. That's a documented stdlib gotcha — when Wait fires the moment the child exits, StdoutPipe closes the read end immediately, discarding any unread bytes in the kernel pipe buffer (i.e. the last chunk of audio the streamer hadn't paced through yet). With a manual pipe, reads drain naturally to io.EOF after the child's pw closes.

func NewShellReader

func NewShellReader(parent context.Context, program string, args []string, log *slog.Logger, streamStderr bool) (*ShellReader, error)

NewShellReader spawns program with args and starts the process. The returned reader streams stdout. If the program cannot be started, ErrFFmpegSpawn is returned wrapped. When streamStderr is true, ffmpeg's stderr is also tee'd line-by-line into the logger at Debug level — useful for diagnosing "ffmpeg runs but I hear nothing" symptoms.

func (*ShellReader) Close

func (r *ShellReader) Close() error

Close terminates the subprocess (if still running) and our copy of the read end of the pipe, then waits for the reaper. Closing the read end unblocks any pending Read in-flight by another goroutine.

func (*ShellReader) Done

func (r *ShellReader) Done() <-chan struct{}

Done is closed when the subprocess exits.

func (*ShellReader) Err

func (r *ShellReader) Err() error

Err returns the process exit error (after Done is closed).

func (*ShellReader) Read

func (r *ShellReader) Read(p []byte) (int, error)

Read pulls bytes from the subprocess stdout.

func (*ShellReader) SetOnExit added in v0.6.1

func (r *ShellReader) SetOnExit(fn func(error))

SetOnExit registers a callback invoked once the subprocess exits and the reap goroutine has captured its exit error. Used to eliminate the need for a separate watch goroutine in consumers like RTMPCall — instead of `go waitForExit(cmd)` you set OnExit and the existing reap goroutine dispatches the lifecycle event. Must be set BEFORE the first reap exit (i.e. immediately after NewShellReader returns).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL