mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-01-15 15:48:03 +00:00
Fix OverflowException when scanning media with a very short duration (#13949)
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
OpenAPI / OpenAPI - HEAD (push) Waiting to run
OpenAPI / OpenAPI - BASE (push) Waiting to run
OpenAPI / OpenAPI - Difference (push) Blocked by required conditions
OpenAPI / OpenAPI - Publish Unstable Spec (push) Blocked by required conditions
OpenAPI / OpenAPI - Publish Stable Spec (push) Blocked by required conditions
Tests / run-tests (macos-latest) (push) Waiting to run
Tests / run-tests (ubuntu-latest) (push) Waiting to run
Tests / run-tests (windows-latest) (push) Waiting to run
Project Automation / Project board (push) Waiting to run
Merge Conflict Labeler / Labeling (push) Waiting to run
Some checks are pending
CodeQL / Analyze (csharp) (push) Waiting to run
OpenAPI / OpenAPI - HEAD (push) Waiting to run
OpenAPI / OpenAPI - BASE (push) Waiting to run
OpenAPI / OpenAPI - Difference (push) Blocked by required conditions
OpenAPI / OpenAPI - Publish Unstable Spec (push) Blocked by required conditions
OpenAPI / OpenAPI - Publish Stable Spec (push) Blocked by required conditions
Tests / run-tests (macos-latest) (push) Waiting to run
Tests / run-tests (ubuntu-latest) (push) Waiting to run
Tests / run-tests (windows-latest) (push) Waiting to run
Project Automation / Project board (push) Waiting to run
Merge Conflict Labeler / Labeling (push) Waiting to run
This commit is contained in:
@@ -965,7 +965,7 @@ namespace MediaBrowser.MediaEncoding.Probing
|
||||
// Get average bitrate info from tag "NUMBER_OF_BYTES" and "DURATION" if possible.
|
||||
var durationInSeconds = GetRuntimeSecondsFromTags(streamInfo);
|
||||
var bytes = GetNumberOfBytesFromTags(streamInfo);
|
||||
if (durationInSeconds is not null && bytes is not null)
|
||||
if (durationInSeconds is not null && durationInSeconds.Value >= 1 && bytes is not null)
|
||||
{
|
||||
bps = Convert.ToInt32(bytes * 8 / durationInSeconds, CultureInfo.InvariantCulture);
|
||||
if (bps > 0)
|
||||
|
||||
@@ -288,6 +288,40 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
|
||||
Assert.True(res.VideoStream.IsDefault);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetMediaInfo_VideoWithSingleFrameMjpeg_Success()
|
||||
{
|
||||
var bytes = File.ReadAllBytes("Test Data/Probing/video_single_frame_mjpeg.json");
|
||||
|
||||
var internalMediaInfoResult = JsonSerializer.Deserialize<InternalMediaInfoResult>(bytes, _jsonOptions);
|
||||
MediaInfo res = _probeResultNormalizer.GetMediaInfo(internalMediaInfoResult, VideoType.VideoFile, false, "Test Data/Probing/video_interlaced.mp4", MediaProtocol.File);
|
||||
|
||||
Assert.Equal(3, res.MediaStreams.Count);
|
||||
|
||||
Assert.NotNull(res.VideoStream);
|
||||
Assert.Equal(res.MediaStreams[0], res.VideoStream);
|
||||
Assert.Equal(0, res.VideoStream.Index);
|
||||
Assert.Equal("h264", res.VideoStream.Codec);
|
||||
Assert.Equal("High", res.VideoStream.Profile);
|
||||
Assert.Equal(MediaStreamType.Video, res.VideoStream.Type);
|
||||
Assert.Equal(1080, res.VideoStream.Height);
|
||||
Assert.Equal(1920, res.VideoStream.Width);
|
||||
Assert.False(res.VideoStream.IsInterlaced);
|
||||
Assert.Equal("16:9", res.VideoStream.AspectRatio);
|
||||
Assert.Equal("yuv420p", res.VideoStream.PixelFormat);
|
||||
Assert.Equal(42d, res.VideoStream.Level);
|
||||
Assert.Equal(1, res.VideoStream.RefFrames);
|
||||
Assert.True(res.VideoStream.IsAVC);
|
||||
Assert.Equal(50f, res.VideoStream.RealFrameRate);
|
||||
Assert.Equal("1/1000", res.VideoStream.TimeBase);
|
||||
Assert.Equal(8, res.VideoStream.BitDepth);
|
||||
Assert.True(res.VideoStream.IsDefault);
|
||||
|
||||
var mjpeg = res.MediaStreams[2];
|
||||
Assert.NotNull(mjpeg);
|
||||
Assert.Equal("mjpeg", mjpeg.Codec);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetMediaInfo_MusicVideo_Success()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
{
|
||||
"streams": [
|
||||
{
|
||||
"index": 0,
|
||||
"codec_name": "h264",
|
||||
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
|
||||
"profile": "High",
|
||||
"codec_type": "video",
|
||||
"codec_tag_string": "[0][0][0][0]",
|
||||
"codec_tag": "0x0000",
|
||||
"width": 1920,
|
||||
"height": 1080,
|
||||
"coded_width": 1920,
|
||||
"coded_height": 1080,
|
||||
"closed_captions": 0,
|
||||
"film_grain": 0,
|
||||
"has_b_frames": 0,
|
||||
"sample_aspect_ratio": "1:1",
|
||||
"display_aspect_ratio": "16:9",
|
||||
"pix_fmt": "yuv420p",
|
||||
"level": 42,
|
||||
"chroma_location": "left",
|
||||
"field_order": "progressive",
|
||||
"refs": 1,
|
||||
"is_avc": "true",
|
||||
"nal_length_size": "4",
|
||||
"r_frame_rate": "50/1",
|
||||
"avg_frame_rate": "50/1",
|
||||
"time_base": "1/1000",
|
||||
"start_pts": 0,
|
||||
"start_time": "0.000000",
|
||||
"bits_per_raw_sample": "8",
|
||||
"extradata_size": 55,
|
||||
"disposition": {
|
||||
"default": 1,
|
||||
"dub": 0,
|
||||
"original": 0,
|
||||
"comment": 0,
|
||||
"lyrics": 0,
|
||||
"karaoke": 0,
|
||||
"forced": 0,
|
||||
"hearing_impaired": 0,
|
||||
"visual_impaired": 0,
|
||||
"clean_effects": 0,
|
||||
"attached_pic": 0,
|
||||
"timed_thumbnails": 0,
|
||||
"non_diegetic": 0,
|
||||
"captions": 0,
|
||||
"descriptions": 0,
|
||||
"metadata": 0,
|
||||
"dependent": 0,
|
||||
"still_image": 0
|
||||
},
|
||||
"tags": {
|
||||
"language": "deu",
|
||||
"HANDLER_NAME": "VideoHandler",
|
||||
"VENDOR_ID": "[0][0][0][0]",
|
||||
"BPS": "3950584",
|
||||
"DURATION": "00:00:10.000000000",
|
||||
"NUMBER_OF_FRAMES": "500",
|
||||
"NUMBER_OF_BYTES": "4938231",
|
||||
"_STATISTICS_WRITING_APP": "mkvpropedit v90.0 ('Hanging On') 64-bit",
|
||||
"_STATISTICS_WRITING_DATE_UTC": "2025-04-19 10:37:57",
|
||||
"_STATISTICS_TAGS": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
|
||||
}
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"codec_name": "aac",
|
||||
"codec_long_name": "AAC (Advanced Audio Coding)",
|
||||
"profile": "LC",
|
||||
"codec_type": "audio",
|
||||
"codec_tag_string": "[0][0][0][0]",
|
||||
"codec_tag": "0x0000",
|
||||
"sample_fmt": "fltp",
|
||||
"sample_rate": "48000",
|
||||
"channels": 2,
|
||||
"channel_layout": "stereo",
|
||||
"bits_per_sample": 0,
|
||||
"initial_padding": 0,
|
||||
"r_frame_rate": "0/0",
|
||||
"avg_frame_rate": "0/0",
|
||||
"time_base": "1/1000",
|
||||
"start_pts": 0,
|
||||
"start_time": "0.000000",
|
||||
"extradata_size": 2,
|
||||
"disposition": {
|
||||
"default": 1,
|
||||
"dub": 0,
|
||||
"original": 0,
|
||||
"comment": 0,
|
||||
"lyrics": 0,
|
||||
"karaoke": 0,
|
||||
"forced": 0,
|
||||
"hearing_impaired": 0,
|
||||
"visual_impaired": 0,
|
||||
"clean_effects": 0,
|
||||
"attached_pic": 0,
|
||||
"timed_thumbnails": 0,
|
||||
"non_diegetic": 0,
|
||||
"captions": 0,
|
||||
"descriptions": 0,
|
||||
"metadata": 0,
|
||||
"dependent": 0,
|
||||
"still_image": 0
|
||||
},
|
||||
"tags": {
|
||||
"language": "deu",
|
||||
"HANDLER_NAME": "SoundHandler",
|
||||
"VENDOR_ID": "[0][0][0][0]",
|
||||
"BPS": "255785",
|
||||
"DURATION": "00:00:09.984000000",
|
||||
"NUMBER_OF_FRAMES": "469",
|
||||
"NUMBER_OF_BYTES": "319220",
|
||||
"_STATISTICS_WRITING_APP": "mkvpropedit v90.0 ('Hanging On') 64-bit",
|
||||
"_STATISTICS_WRITING_DATE_UTC": "2025-04-19 10:37:57",
|
||||
"_STATISTICS_TAGS": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
|
||||
}
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"codec_name": "mjpeg",
|
||||
"codec_long_name": "Motion JPEG",
|
||||
"profile": "Baseline",
|
||||
"codec_type": "video",
|
||||
"codec_tag_string": "[0][0][0][0]",
|
||||
"codec_tag": "0x0000",
|
||||
"width": 960,
|
||||
"height": 540,
|
||||
"coded_width": 960,
|
||||
"coded_height": 540,
|
||||
"closed_captions": 0,
|
||||
"film_grain": 0,
|
||||
"has_b_frames": 0,
|
||||
"sample_aspect_ratio": "1:1",
|
||||
"display_aspect_ratio": "16:9",
|
||||
"pix_fmt": "yuvj420p",
|
||||
"level": -99,
|
||||
"color_range": "pc",
|
||||
"color_space": "bt470bg",
|
||||
"chroma_location": "center",
|
||||
"refs": 1,
|
||||
"r_frame_rate": "1000/1",
|
||||
"avg_frame_rate": "30000/1",
|
||||
"time_base": "1/1000",
|
||||
"start_pts": 0,
|
||||
"start_time": "0.000000",
|
||||
"bits_per_raw_sample": "8",
|
||||
"disposition": {
|
||||
"default": 0,
|
||||
"dub": 0,
|
||||
"original": 0,
|
||||
"comment": 0,
|
||||
"lyrics": 0,
|
||||
"karaoke": 0,
|
||||
"forced": 0,
|
||||
"hearing_impaired": 0,
|
||||
"visual_impaired": 0,
|
||||
"clean_effects": 0,
|
||||
"attached_pic": 0,
|
||||
"timed_thumbnails": 0,
|
||||
"non_diegetic": 0,
|
||||
"captions": 0,
|
||||
"descriptions": 0,
|
||||
"metadata": 0,
|
||||
"dependent": 0,
|
||||
"still_image": 0
|
||||
},
|
||||
"tags": {
|
||||
"BPS": "0",
|
||||
"DURATION": "00:00:00.000011111",
|
||||
"NUMBER_OF_FRAMES": "1",
|
||||
"NUMBER_OF_BYTES": "155034",
|
||||
"_STATISTICS_WRITING_APP": "mkvpropedit v90.0 ('Hanging On') 64-bit",
|
||||
"_STATISTICS_WRITING_DATE_UTC": "2025-04-19 10:37:57",
|
||||
"_STATISTICS_TAGS": "BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES"
|
||||
}
|
||||
}
|
||||
],
|
||||
"chapters": [],
|
||||
"format": {
|
||||
"filename": "file:broken_mkv_covers - 01x03 - statistics added using mkvpropedit.mkv",
|
||||
"nb_streams": 3,
|
||||
"nb_programs": 0,
|
||||
"nb_stream_groups": 0,
|
||||
"format_name": "matroska,webm",
|
||||
"format_long_name": "Matroska / WebM",
|
||||
"start_time": "0.000000",
|
||||
"duration": "10.005000",
|
||||
"size": "5425928",
|
||||
"bit_rate": "4338573",
|
||||
"probe_score": 100,
|
||||
"tags": {
|
||||
"title": "Folge 1: Jackpot Immobilie · Wie wir klug vererben",
|
||||
"EPISODE_SORT": "1",
|
||||
"MAJOR_BRAND": "isom",
|
||||
"MINOR_VERSION": "512",
|
||||
"COMPATIBLE_BRANDS": "isomiso2avc1mp41",
|
||||
"DATE": "20250318",
|
||||
"SEASON_NUMBER": "1",
|
||||
"COMMENT": "https://www.ardmediathek.de/video/Y3JpZDovL2JyLmRlL2Jyb2FkY2FzdC8zZWFmYTcxOC1mZDJmLTRmZTMtYWE4Ny03ZjdlNWViNTk1NDhfb25saW5lYnJvYWRjYXN0",
|
||||
"DESCRIPTION": "Jeder kennt es: Enge Familienmitglieder sprechen plötzlich nicht mehr miteinander, der Streit ums Erbe entzweit die Familie. Was steht im Testament? Kann sich die Erbengemeinschaft einigen? Wie läuft das mit der Erbschaftssteuer und was sagt das Erbrecht?\n\nDas \"Lohnt sich das?\"-Team hat zwei Familien gefunden, die das Tabu rund ums Erben brechen. Sie erzählen, um wie viel Geld es geht, aber auch, was dieses Immobilienerbe mit ihrer Familie gemacht hat. Warum es einmal gelingt, Häuser in Millionenhöhe ohne jegliche Erbschaftssteuer zu vererben, während andere Geschwister sich über ihr Elternhaus komplett zerstritten haben. Erbfolge, Freibeträge, Nießbrauch - für alle Basics rund ums Erben ist Ralph Caspers zuständig, der kompetent erklärt. ",
|
||||
"SYNOPSIS": "Jeder kennt es: Enge Familienmitglieder sprechen plötzlich nicht mehr miteinander, der Streit ums Erbe entzweit die Familie. Was steht im Testament? Kann sich die Erbengemeinschaft einigen? Wie läuft das mit der Erbschaftssteuer und was sagt das Erbrecht?\n\nDas \"Lohnt sich das?\"-Team hat zwei Familien gefunden, die das Tabu rund ums Erben brechen. Sie erzählen, um wie viel Geld es geht, aber auch, was dieses Immobilienerbe mit ihrer Familie gemacht hat. Warum es einmal gelingt, Häuser in Millionenhöhe ohne jegliche Erbschaftssteuer zu vererben, während andere Geschwister sich über ihr Elternhaus komplett zerstritten haben. Erbfolge, Freibeträge, Nießbrauch - für alle Basics rund ums Erben ist Ralph Caspers zuständig, der kompetent erklärt. ",
|
||||
"SHOW": "Generation Wohnkrise. Lohnt sich das?",
|
||||
"EPISODE_ID": "Folge 1: Jackpot Immobilie · Wie wir klug vererben",
|
||||
"ENCODER": "Lavf61.7.100"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user