Enforce more strict webm check

The webm spec only supports video and video streams, and other type of streams in the container should disqualify its webm container type and be treated as mkv.

Some tools might allow users to add subtitle streams to webm and still claim it is webm, but such files are not guranteed to play directly everywhere, and the actuall support is implementation specific.

With the advent of the (unreliable) native mkv support in firefox, this will be required to properly trigger remux for such files.
This commit is contained in:
gnattu
2025-12-16 22:48:43 +08:00
parent 1e27f460fe
commit 879706a901
2 changed files with 18 additions and 3 deletions

View File

@@ -299,8 +299,11 @@ namespace MediaBrowser.MediaEncoding.Probing
// Handle WebM
else if (string.Equals(splitFormat[i], "webm", StringComparison.OrdinalIgnoreCase))
{
// Limit WebM to supported codecs
if (mediaStreams.Any(stream => (stream.Type == MediaStreamType.Video && !_webmVideoCodecs.Contains(stream.Codec, StringComparison.OrdinalIgnoreCase))
// Limit WebM to supported stream types and codecs.
// FFprobe can report "matroska,webm" for Matroska-like containers, so only keep "webm" if all streams are WebM-compatible.
// Any stream that is not video nor audio is not supported in WebM and should disqualify the webm container probe result.
if (mediaStreams.Any(stream => stream.Type is not MediaStreamType.Video and not MediaStreamType.Audio)
|| mediaStreams.Any(stream => (stream.Type == MediaStreamType.Video && !_webmVideoCodecs.Contains(stream.Codec, StringComparison.OrdinalIgnoreCase))
|| (stream.Type == MediaStreamType.Audio && !_webmAudioCodecs.Contains(stream.Codec, StringComparison.OrdinalIgnoreCase))))
{
splitFormat[i] = string.Empty;

View File

@@ -195,6 +195,18 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
Assert.False(res.MediaStreams[0].IsAVC);
}
[Fact]
public void GetMediaInfo_WebM_Like_Mkv()
{
var bytes = File.ReadAllBytes("Test Data/Probing/video_web_like_mkv_with_subtitle.json");
var internalMediaInfoResult = JsonSerializer.Deserialize<InternalMediaInfoResult>(bytes, _jsonOptions);
MediaInfo res = _probeResultNormalizer.GetMediaInfo(internalMediaInfoResult, VideoType.VideoFile, false, "Test Data/Probing/video_metadata.mkv", MediaProtocol.File);
Assert.Equal("mkv", res.Container);
Assert.Equal(3, res.MediaStreams.Count);
}
[Fact]
public void GetMediaInfo_ProgressiveVideoNoFieldOrder_Success()
{