56 lines
1.1 KiB
Go
56 lines
1.1 KiB
Go
package media
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os/exec"
|
|
)
|
|
|
|
type ffmpegReader struct {
|
|
io.ReadCloser
|
|
|
|
cmd *exec.Cmd
|
|
}
|
|
|
|
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}, 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", state.ExitCode())
|
|
}
|
|
|
|
return nil
|
|
}
|