Skip to content

Commit 12d27ce

Browse files
eliteproxj0sh
authored andcommitted
Add media duration to lpms_get_codec_info for GetCodecInfo (#407)
* add fps and duration to GetCodecInfo
1 parent 59d07f5 commit 12d27ce

File tree

5 files changed

+58
-3
lines changed

5 files changed

+58
-3
lines changed

ffmpeg/decoder.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ int open_input(input_params *params, struct input_ctx *ctx)
337337

338338
ctx->transmuxing = params->transmuxing;
339339

340-
// open demuxer
340+
// open demuxer/ open demuxer
341341
AVDictionary **demuxer_opts = NULL;
342342
if (params->demuxer.opts) demuxer_opts = &params->demuxer.opts;
343343
ret = avformat_open_input(&ic, inp, NULL, demuxer_opts);

ffmpeg/extras.c

+4
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ int lpms_get_codec_info(char *fname, pcodec_info out)
164164
// instead of returning -1
165165
ret = GET_CODEC_STREAMS_MISSING;
166166
}
167+
if (ic->duration != AV_NOPTS_VALUE) {
168+
out->dur = ic->duration / AV_TIME_BASE;
169+
}
167170
// Return
168171
if (video_present && vc->name) {
169172
strncpy(out->video_codec, vc->name, MIN(strlen(out->video_codec), strlen(vc->name))+1);
@@ -176,6 +179,7 @@ int lpms_get_codec_info(char *fname, pcodec_info out)
176179
}
177180
out->width = ic->streams[vstream]->codecpar->width;
178181
out->height = ic->streams[vstream]->codecpar->height;
182+
out->fps = av_q2d(ic->streams[vstream]->r_frame_rate);
179183
} else {
180184
// Indicate failure to extract video codec from given container
181185
out->video_codec[0] = 0;

ffmpeg/extras.h

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ typedef struct s_codec_info {
77
int pixel_format;
88
int width;
99
int height;
10+
double fps;
11+
double dur;
1012
} codec_info, *pcodec_info;
1113

1214
int lpms_rtmp2hls(char *listen, char *outf, char *ts_tmpl, char *seg_time, char *seg_start);

ffmpeg/ffmpeg.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ type MediaFormatInfo struct {
245245
Acodec, Vcodec string
246246
PixFormat PixelFormat
247247
Width, Height int
248+
FPS float32
249+
DurSecs int64
248250
}
249251

250252
func (f *MediaFormatInfo) ScaledHeight(width int) int {
@@ -277,6 +279,8 @@ func GetCodecInfo(fname string) (CodecStatus, MediaFormatInfo, error) {
277279
format.PixFormat = PixelFormat{int(params_c.pixel_format)}
278280
format.Width = int(params_c.width)
279281
format.Height = int(params_c.height)
282+
format.FPS = float32(params_c.fps)
283+
format.DurSecs = int64(params_c.dur)
280284
return status, format, nil
281285
}
282286

@@ -979,7 +983,7 @@ func (t *Transcoder) Transcode(input *TranscodeOptionsIn, ps []TranscodeOptions)
979983
input.Profile.FramerateDen = 1
980984
}
981985

982-
// Do not try tofree in this function because in the C code avformat_open_input()
986+
// Do not try to free in this function because in the C code avformat_open_input()
983987
// will destroy this
984988
demuxerOpts.opts = newAVOpts(map[string]string{
985989
"framerate": fmt.Sprintf("%d/%d", input.Profile.Framerate, input.Profile.FramerateDen),

ffmpeg/ffmpeg_test.go

+46-1
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,6 @@ func TestTranscoder_VFR(t *testing.T) {
18731873
run, dir := setupTest(t)
18741874
defer os.RemoveAll(dir)
18751875

1876-
18771876
// prepare the input by generating a vfr video and verify its properties
18781877
cmd := `
18791878
ffmpeg -hide_banner -i "$1/../transcoder/test.ts" -an -vf "setpts='\
@@ -1967,3 +1966,49 @@ PTS_EOF
19671966
`
19681967
run(cmd)
19691968
}
1969+
1970+
func TestDurationFPS_GetCodecInfo(t *testing.T) {
1971+
run, dir := setupTest(t)
1972+
defer os.RemoveAll(dir)
1973+
1974+
//Generate test files
1975+
cmd := `
1976+
cp "$1/../data/duplicate-audio-dts.ts" test.ts
1977+
ffprobe -loglevel warning -show_format test.ts | grep duration=2.008555
1978+
ffprobe -loglevel warning -show_streams -select_streams v test.ts | grep r_frame_rate=30/1
1979+
cp "$1/../data/bunny.mp4" test.mp4
1980+
ffmpeg -loglevel warning -i test.mp4 -c:v copy -c:a copy -t 2 test-short.mp4
1981+
ffprobe -loglevel warning -show_format test-short.mp4 | grep duration=2.043356
1982+
ffprobe -loglevel warning -show_streams -select_streams v test-short.mp4 | grep r_frame_rate=24/1
1983+
ffmpeg -loglevel warning -i test-short.mp4 -c:v libvpx -c:a vorbis -strict -2 -t 2 test.webm
1984+
ffprobe -loglevel warning -show_format test.webm | grep duration=2.049000
1985+
ffprobe -loglevel warning -show_streams -select_streams v test.webm | grep r_frame_rate=24/1
1986+
ffmpeg -loglevel warning -i test-short.mp4 -vn -c:a aac -b:a 128k test.m4a
1987+
ffprobe -loglevel warning -show_format test.m4a | grep duration=2.042993
1988+
ffmpeg -loglevel warning -i test-short.mp4 -vn -c:a flac test.flac
1989+
ffprobe -loglevel warning -show_format test.flac | grep duration=2.043356
1990+
`
1991+
run(cmd)
1992+
1993+
files := []struct {
1994+
Filename string
1995+
Duration int64
1996+
FPS float32
1997+
}{
1998+
{Filename: "test-short.mp4", Duration: 2, FPS: 24},
1999+
{Filename: "test.ts", Duration: 2, FPS: 30.0},
2000+
{Filename: "test.flac", Duration: 2, FPS: 0.0},
2001+
{Filename: "test.webm", Duration: 2, FPS: 24},
2002+
{Filename: "test.m4a", Duration: 2, FPS: 0.0},
2003+
}
2004+
for _, file := range files {
2005+
t.Run(file.Filename, func(t *testing.T) {
2006+
assert := assert.New(t)
2007+
status, format, err := GetCodecInfo(path.Join(dir, file.Filename))
2008+
assert.Nil(err, "getcodecinfo error")
2009+
assert.Equal(CodecStatusOk, status, "status not ok")
2010+
assert.Equal(file.Duration, format.DurSecs, "duration mismatch")
2011+
assert.Equal(file.FPS, format.FPS, "fps mismatch")
2012+
})
2013+
}
2014+
}

0 commit comments

Comments
 (0)