clipper/backend/media/ffmpeg_reader.go

57 lines
1.2 KiB
Go

package media
import (
"bytes"
"context"
"fmt"
"io"
"os/exec"
)
type ffmpegReader struct {
io.ReadCloser
cmd *exec.Cmd
stdErrBuf *bytes.Buffer
}
func newFfmpegReader(ctx context.Context, input io.Reader, arg ...string) (*ffmpegReader, error) {
var stdErr bytes.Buffer
cmd := exec.CommandContext(ctx, "ffmpeg", arg...)
cmd.Stdin = input
cmd.Stderr = &stdErr
r, err := cmd.StdoutPipe()
if err != nil {
return nil, fmt.Errorf("error creating pipe: %v", err)
}
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("error starting ffmpeg: %v, output: %s", err, stdErr.String())
}
return &ffmpegReader{ReadCloser: r, cmd: cmd, stdErrBuf: &stdErr}, nil
}
func (r *ffmpegReader) Cancel() error {
if err := r.cmd.Process.Kill(); err != nil {
return fmt.Errorf("error killing ffmpeg process: %v", err)
}
return nil
}
func (r *ffmpegReader) Close() error {
state, err := r.cmd.Process.Wait()
if err != nil {
return fmt.Errorf("error returned from ffmpeg process: %v", err)
}
if state.ExitCode() != 0 {
return fmt.Errorf("non-zero status %d returned from ffmpeg process, output: %s", state.ExitCode(), r.stdErrBuf.String())
}
return nil
}