Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add media duration to lpms_get_codec_info for GetCodecInfo #407

Merged
merged 27 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
eef214e
add fps and duration to GetCodecInfo
ad-astra-video Oct 31, 2023
1fcc47e
update fps and dur calc
ad-astra-video Nov 3, 2023
904f309
add duration if video or audio present
ad-astra-video Jul 3, 2024
6a2b014
add cmd script to test fps and duration
ad-astra-video Jul 3, 2024
0e84f60
revert to using AV_TIME_BASE and add notes for future improvements
ad-astra-video Jul 3, 2024
2b723a4
Fix duration for audio only file
eliteprox Jul 5, 2024
b601475
Code cleanup
eliteprox Jul 5, 2024
bad8498
Fix duration calculation
eliteprox Jul 5, 2024
146d718
Cleanup test
eliteprox Jul 5, 2024
75bd67c
Merge branch 'add-codec-info' of github.com:eliteprox/lpms into add-c…
eliteprox Jul 8, 2024
e6389f2
Move fps duration test to ffmpeg test, add descriptive comment
eliteprox Jul 8, 2024
f05997e
Add tests, cleanup from review
eliteprox Jul 9, 2024
f0eda1a
Generate test files with ffmpeg, check expected duration and fps, rem…
eliteprox Jul 9, 2024
f3c8917
Remove test file
eliteprox Jul 9, 2024
d025d0a
Fix tests and review comments
eliteprox Jul 9, 2024
6579e6e
Save indention
eliteprox Jul 9, 2024
67db771
Remove seek
eliteprox Jul 9, 2024
cc58010
simplify test
eliteprox Jul 10, 2024
8cdef44
Add webm type to test
eliteprox Jul 10, 2024
a8f19c4
add max_analyze_duration and remove strays
eliteprox Jul 10, 2024
d99d32b
Optimize duration calculation
eliteprox Jul 10, 2024
f2edd37
Use the largest pts for last_pts and smallest pts for first
eliteprox Jul 10, 2024
1fd0f5c
Remove calculate_stream_duration, add ffprobe to tests
eliteprox Jul 11, 2024
afaf25d
remove max_analyze_duration
eliteprox Jul 11, 2024
56c2328
Update ffmpeg/ffmpeg_test.go
eliteprox Jul 11, 2024
0e12477
Update ffmpeg/extras.c
eliteprox Jul 11, 2024
c85f817
add ffprobe expected duration and fps values to test
eliteprox Jul 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
})
}
}