Skip to content

Commit

Permalink
Add media duration to lpms_get_codec_info for GetCodecInfo (#407)
Browse files Browse the repository at this point in the history
* add fps and duration to GetCodecInfo
  • Loading branch information
eliteprox authored Jul 11, 2024
1 parent de94555 commit 2273258
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
4 changes: 4 additions & 0 deletions ffmpeg/extras.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ int lpms_get_codec_info(char *fname, pcodec_info out)
// instead of returning -1
ret = GET_CODEC_STREAMS_MISSING;
}
if (ic->duration != AV_NOPTS_VALUE) {
out->dur = ic->duration / AV_TIME_BASE;
}
// Return
if (video_present && vc->name) {
strncpy(out->video_codec, vc->name, MIN(strlen(out->video_codec), strlen(vc->name))+1);
Expand All @@ -176,6 +179,7 @@ int lpms_get_codec_info(char *fname, pcodec_info out)
}
out->width = ic->streams[vstream]->codecpar->width;
out->height = ic->streams[vstream]->codecpar->height;
out->fps = av_q2d(ic->streams[vstream]->r_frame_rate);
} else {
// Indicate failure to extract video codec from given container
out->video_codec[0] = 0;
Expand Down
2 changes: 2 additions & 0 deletions ffmpeg/extras.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ typedef struct s_codec_info {
int pixel_format;
int width;
int height;
double fps;
double dur;
} codec_info, *pcodec_info;

int lpms_rtmp2hls(char *listen, char *outf, char *ts_tmpl, char *seg_time, char *seg_start);
Expand Down
4 changes: 4 additions & 0 deletions ffmpeg/ffmpeg.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ type MediaFormatInfo struct {
Acodec, Vcodec string
PixFormat PixelFormat
Width, Height int
FPS float32
DurSecs int64
}

func (f *MediaFormatInfo) ScaledHeight(width int) int {
Expand Down Expand Up @@ -277,6 +279,8 @@ func GetCodecInfo(fname string) (CodecStatus, MediaFormatInfo, error) {
format.PixFormat = PixelFormat{int(params_c.pixel_format)}
format.Width = int(params_c.width)
format.Height = int(params_c.height)
format.FPS = float32(params_c.fps)
format.DurSecs = int64(params_c.dur)
return status, format, nil
}

Expand Down
50 changes: 50 additions & 0 deletions ffmpeg/ffmpeg_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1869,3 +1869,53 @@ func TestResolution_Clamp(t *testing.T) {
checkError = require.Error
test(l, Size{300, 600}, portrait, Size{300, 600})
}

func TestDurationFPS_GetCodecInfo(t *testing.T) {
run, dir := setupTest(t)
defer os.RemoveAll(dir)

//Generate test files
cmd := `
cp "$1/../data/duplicate-audio-dts.ts" test.ts
ffprobe -loglevel warning -show_format test.ts | grep duration=2.008555
ffprobe -loglevel warning -show_streams -select_streams v test.ts | grep r_frame_rate=30/1
cp "$1/../data/bunny.mp4" test.mp4
ffmpeg -loglevel warning -i test.mp4 -c:v copy -c:a copy -t 2 test-short.mp4
ffprobe -loglevel warning -show_format test-short.mp4 | grep duration=2.043356
ffprobe -loglevel warning -show_streams -select_streams v test-short.mp4 | grep r_frame_rate=24/1
ffmpeg -loglevel warning -i test-short.mp4 -c:v libvpx -c:a vorbis -strict -2 -t 2 test.webm
ffprobe -loglevel warning -show_format test.webm | grep duration=2.049000
ffprobe -loglevel warning -show_streams -select_streams v test.webm | grep r_frame_rate=24/1
ffmpeg -loglevel warning -i test-short.mp4 -vn -c:a aac -b:a 128k test.m4a
ffprobe -loglevel warning -show_format test.m4a | grep duration=2.042993
ffmpeg -loglevel warning -i test-short.mp4 -vn -c:a flac test.flac
ffprobe -loglevel warning -show_format test.flac | grep duration=2.043356
`
run(cmd)

files := []struct {
Filename string
Duration int64
FPS float32
}{
{Filename: "test-short.mp4", Duration: 2, FPS: 24},
{Filename: "test.ts", Duration: 2, FPS: 30.0},
{Filename: "test.flac", Duration: 2, FPS: 0.0},
{Filename: "test.webm", Duration: 2, FPS: 24},
{Filename: "test.m4a", Duration: 2, FPS: 0.0},
}
for _, file := range files {
t.Run(file.Filename, func(t *testing.T) {
assert := assert.New(t)
status, format, err := GetCodecInfo(path.Join(dir, file.Filename))
assert.Nil(err, "getcodecinfo error")
assert.Equal(CodecStatusOk, status, "status not ok")
assert.Equal(file.Duration, format.DurSecs, "duration mismatch")
assert.Equal(file.FPS, format.FPS, "fps mismatch")
})
}
}

0 comments on commit 2273258

Please sign in to comment.