Changed filename processing when merging with ffmpeg

This commit is contained in:
bytedream 2022-03-14 23:41:55 +01:00
parent 60fed00b0e
commit b1945d672d

View file

@ -14,14 +14,12 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp" "strings"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
) )
var ffmpegInfoPattern = regexp.MustCompile(`Output #0, (.+),`)
// NewDownloader creates a downloader with default settings which should // NewDownloader creates a downloader with default settings which should
// fit the most needs // fit the most needs
func NewDownloader(context context.Context, writer io.Writer, goroutines int, onSegmentDownload func(segment *m3u8.MediaSegment, current, total int, file *os.File) error) Downloader { func NewDownloader(context context.Context, writer io.Writer, goroutines int, onSegmentDownload func(segment *m3u8.MediaSegment, current, total int, file *os.File) error) Downloader {
@ -160,62 +158,54 @@ func (d Downloader) mergeSegmentsFFmpeg(files []string) error {
} }
if d.FFmpegOpts != nil { if d.FFmpegOpts != nil {
command = append(command, d.FFmpegOpts...) command = append(command, d.FFmpegOpts...)
var found bool }
var tmpfile string
if _, ok := d.Writer.(*io.PipeWriter); ok {
if file, ok := d.Writer.(*os.File); ok {
tmpfile = filepath.Base(file.Name())
}
}
if filepath.Ext(tmpfile) == "" {
// checks if the -f flag is set (overwrites the output format)
var hasF bool
for _, opts := range d.FFmpegOpts { for _, opts := range d.FFmpegOpts {
if opts == "-f" { if strings.TrimSpace(opts) == "-f" {
found = true hasF = true
break break
} }
} }
if !found { if !hasF {
if file, ok := d.Writer.(*os.File); ok { command = append(command, "-f", "matroska")
var outBuf bytes.Buffer f, err := os.CreateTemp(d.TempDir, "")
infoCmd := exec.Command("ffmpeg", file.Name()) if err != nil {
infoCmd.Stderr = &outBuf
if infoCmd.Run(); err != nil {
return err return err
} }
if parsed := ffmpegInfoPattern.FindStringSubmatch(outBuf.String()); parsed != nil { f.Close()
command = append(command, "-f", parsed[1]) tmpfile = f.Name()
}
} else {
command = append(command, "-f", "mpegts")
} }
} }
} command = append(command, tmpfile)
command = append(command, "pipe:1")
var errBuf bytes.Buffer var errBuf bytes.Buffer
cmd := exec.Command("ffmpeg", cmd := exec.CommandContext(d.Context, "ffmpeg",
command...) command...)
cmd.Stderr = &errBuf cmd.Stderr = &errBuf
// io.Copy may be better but this uses less code so ¯\_(ツ)_/¯
cmd.Stdout = d.Writer
if err = cmd.Start(); err != nil { if err = cmd.Run(); err != nil {
return err
}
cmdChan := make(chan error, 1)
go func() {
cmdChan <- cmd.Wait()
}()
select {
case err = <-cmdChan:
if err != nil {
if errBuf.Len() > 0 { if errBuf.Len() > 0 {
return fmt.Errorf(errBuf.String()) return fmt.Errorf(errBuf.String())
} else { } else {
return err return err
} }
} }
return nil file, err := os.Open(tmpfile)
case <-d.Context.Done(): if err != nil {
cmd.Process.Kill() return err
return d.Context.Err()
} }
defer file.Close()
_, err = io.Copy(d.Writer, file)
return err
} }
// downloadSegments downloads every mpeg transport stream segment to a given // downloadSegments downloads every mpeg transport stream segment to a given