mirror of
https://github.com/livepeer/lpms
synced 2026-04-22 15:57:25 +08:00
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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user