navidrome/engine/stream.go

60 lines
1.4 KiB
Go
Raw Normal View History

2016-03-09 15:12:26 +01:00
package engine
import (
2020-01-09 02:45:07 +01:00
"context"
"io"
"os"
"os/exec"
"strconv"
"strings"
2016-03-09 15:12:26 +01:00
2017-04-01 15:47:14 +02:00
"github.com/cloudsonic/sonic-server/conf"
2020-01-09 02:45:07 +01:00
"github.com/cloudsonic/sonic-server/log"
)
// TODO Encapsulate as a io.Reader
2020-01-09 02:45:07 +01:00
func Stream(ctx context.Context, path string, bitRate int, maxBitRate int, w io.Writer) error {
var f io.Reader
var err error
2017-04-01 15:47:14 +02:00
enabled := !conf.Sonic.DisableDownsampling
2016-03-30 06:05:57 +02:00
if enabled && maxBitRate > 0 && bitRate > maxBitRate {
2020-01-09 02:45:07 +01:00
f, err = downsample(ctx, path, maxBitRate)
} else {
f, err = os.Open(path)
}
if err != nil {
2020-01-09 02:45:07 +01:00
log.Error(ctx, "Error opening file", "path", path, err)
return err
}
if _, err = io.Copy(w, f); err != nil {
2020-01-09 02:45:07 +01:00
log.Error(ctx, "Error copying file", "path", path, err)
return err
}
return err
}
2020-01-09 02:45:07 +01:00
func downsample(ctx context.Context, path string, maxBitRate int) (f io.Reader, err error) {
cmdLine, args := createDownsamplingCommand(path, maxBitRate)
2020-01-09 02:45:07 +01:00
log.Debug(ctx, "Executing command", "cmdLine", cmdLine, "args", args)
cmd := exec.Command(cmdLine, args...)
cmd.Stderr = os.Stderr
if f, err = cmd.StdoutPipe(); err != nil {
return f, err
}
return f, cmd.Start()
}
func createDownsamplingCommand(path string, maxBitRate int) (string, []string) {
2017-04-01 15:47:14 +02:00
cmd := conf.Sonic.DownsampleCommand
split := strings.Split(cmd, " ")
for i, s := range split {
s = strings.Replace(s, "%s", path, -1)
s = strings.Replace(s, "%b", strconv.Itoa(maxBitRate), -1)
split[i] = s
}
2016-03-23 17:35:10 +01:00
return split[0], split[1:]
}