add duration check for input files (#434)

* add duration check for input file to ensure not transcoding long inputs and protect against inputs that have time stamp anomalies causing the output to be much longer than the input

---------

Co-authored-by: Josh Allmann <joshua.allmann@gmail.com>
This commit is contained in:
Brad | ad-astra
2025-05-29 11:10:47 -05:00
committed by GitHub
parent e1872bf609
commit c1eefa63ff
2 changed files with 48 additions and 0 deletions
+5
View File
@@ -33,6 +33,7 @@ var ErrTranscoderHw = errors.New("TranscoderInvalidHardware")
var ErrTranscoderInp = errors.New("TranscoderInvalidInput")
var ErrTranscoderClipConfig = errors.New("TranscoderInvalidClipConfig")
var ErrTranscoderVid = errors.New("TranscoderInvalidVideo")
var ErrTranscoderDuration = errors.New("TranscoderInvalidDuration")
var ErrTranscoderStp = errors.New("TranscoderStopped")
var ErrTranscoderFmt = errors.New("TranscoderUnrecognizedFormat")
var ErrTranscoderPrf = errors.New("TranscoderUnrecognizedProfile")
@@ -880,6 +881,10 @@ func (t *Transcoder) Transcode(input *TranscodeOptionsIn, ps []TranscodeOptions)
if err != nil {
return nil, err
}
if format.DurSecs > 300 {
glog.Errorf("Input file %s has duration of %d seconds, which is more than 5 minutes. This is not supported by the transcoder.", input.Fname, format.DurSecs)
return nil, ErrTranscoderDuration
}
// TODO hoist the rest of this into C so we don't have to invoke GetCodecInfo
if !t.started {
// NeedsBypass is state where video is present in container & without any frames
+43
View File
@@ -3,6 +3,7 @@ package ffmpeg
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
@@ -2424,3 +2425,45 @@ func TestTranscoder_PNGDemuxerOpts(t *testing.T) {
assert.Equal(t, 3, res.Decoded.Frames)
assert.Equal(t, 180, res.Encoded[0].Frames)
}
func TestTranscode_DurationLimit(t *testing.T) {
run, dir := setupTest(t)
defer os.RemoveAll(dir)
cmd := `
# generate a 1fps sample
ffmpeg -i "$1"/../transcoder/test.ts -c copy -bsf:v setts=ts=N/TB/1 -frames:v 301 -y test.ts
# double check the sample actually has the characteristics we expect
ffprobe -show_format test.ts | grep duration=301.00
`
run(cmd)
// Set up transcode options
fileInput := &TranscodeOptionsIn{
Fname: fmt.Sprintf("%v/test.ts", dir),
}
options := []TranscodeOptions{
{
Oname: fmt.Sprintf("%s/out-test.ts", dir),
VideoEncoder: ComponentOptions{Name: "copy"},
AudioEncoder: ComponentOptions{Name: "copy"},
Muxer: ComponentOptions{Name: "md5"},
},
}
// transcode long input from file, should error out
_, err := Transcode3(fileInput, options)
assert.Equal(t, ErrTranscoderDuration, err)
// transcode long input from pipe, should *not* error out
ir, iw, err := os.Pipe()
go func(iw *os.File) {
defer iw.Close()
f, _ := os.Open(fileInput.Fname)
io.Copy(iw, f)
}(iw)
pipeInput := &TranscodeOptionsIn{
Fname: fmt.Sprintf("pipe:%d", ir.Fd()),
}
_, err = Transcode3(pipeInput, options)
assert.Nil(t, err)
}