< Summary - Jellyfin

Information
Class: MediaBrowser.MediaEncoding.Subtitles.SubtitleEditParser
Assembly: MediaBrowser.MediaEncoding
File(s): /srv/git/jellyfin/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs
Line coverage
61%
Covered lines: 29
Uncovered lines: 18
Coverable lines: 47
Total lines: 122
Line coverage: 61.7%
Branch coverage
70%
Covered branches: 14
Total branches: 20
Branch coverage: 70%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 4/15/2026 - 12:14:34 AM Line coverage: 74.1% (43/58) Branch coverage: 72.7% (16/22) Total lines: 1387/21/2026 - 12:16:33 AM Line coverage: 68% (32/47) Branch coverage: 70% (14/20) Total lines: 1227/23/2026 - 12:16:48 AM Line coverage: 61.7% (29/47) Branch coverage: 70% (14/20) Total lines: 122 4/15/2026 - 12:14:34 AM Line coverage: 74.1% (43/58) Branch coverage: 72.7% (16/22) Total lines: 1387/21/2026 - 12:16:33 AM Line coverage: 68% (32/47) Branch coverage: 70% (14/20) Total lines: 1227/23/2026 - 12:16:48 AM Line coverage: 61.7% (29/47) Branch coverage: 70% (14/20) Total lines: 122

Coverage delta

Coverage delta 7 -7

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Parse(...)40%231050%
SupportsFileExtension(...)100%210%
GetSubtitleFormatTypes()100%111080%

File(s)

/srv/git/jellyfin/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.IO;
 4using System.Linq;
 5using Jellyfin.Extensions;
 6using Microsoft.Extensions.Logging;
 7using Nikse.SubtitleEdit.Core.Common;
 8using SubtitleFormat = Nikse.SubtitleEdit.Core.SubtitleFormats.SubtitleFormat;
 9
 10namespace MediaBrowser.MediaEncoding.Subtitles
 11{
 12    /// <summary>
 13    /// SubStation Alpha subtitle parser.
 14    /// </summary>
 15    public class SubtitleEditParser : ISubtitleParser
 16    {
 17        private readonly ILogger<SubtitleEditParser> _logger;
 18        private readonly Dictionary<string, List<Type>> _subtitleFormatTypes;
 19
 20        /// <summary>
 21        /// Initializes a new instance of the <see cref="SubtitleEditParser"/> class.
 22        /// </summary>
 23        /// <param name="logger">The logger.</param>
 24        public SubtitleEditParser(ILogger<SubtitleEditParser> logger)
 25        {
 2926            _logger = logger;
 2927            _subtitleFormatTypes = GetSubtitleFormatTypes();
 2928        }
 29
 30        /// <inheritdoc />
 31        public Subtitle Parse(Stream stream, string fileExtension)
 32        {
 10933            var subtitle = new Subtitle();
 10934            var lines = stream.ReadAllLines().ToList();
 35
 10936            if (!_subtitleFormatTypes.TryGetValue(fileExtension, out var subtitleFormatTypesForExtension))
 37            {
 038                throw new ArgumentException($"Unsupported file extension: {fileExtension}", nameof(fileExtension));
 39            }
 40
 32741            foreach (var subtitleFormatType in subtitleFormatTypesForExtension)
 42            {
 10943                var subtitleFormat = (SubtitleFormat)Activator.CreateInstance(subtitleFormatType, true)!;
 10944                _logger.LogDebug(
 10945                    "Trying to parse '{FileExtension}' subtitle using the {SubtitleFormatParser} format parser",
 10946                    fileExtension,
 10947                    subtitleFormat.Name);
 10948                subtitleFormat.LoadSubtitle(subtitle, lines, fileExtension);
 10949                if (subtitleFormat.ErrorCount == 0)
 50                {
 10951                    break;
 52                }
 053                else if (subtitleFormat.TryGetErrors(out var errors))
 54                {
 055                    _logger.LogError(
 056                        "{ErrorCount} errors encountered while parsing '{FileExtension}' subtitle using the {SubtitleFor
 057                        subtitleFormat.ErrorCount,
 058                        fileExtension,
 059                        subtitleFormat.Name,
 060                        errors);
 61                }
 62                else
 63                {
 064                    _logger.LogError(
 065                        "{ErrorCount} errors encountered while parsing '{FileExtension}' subtitle using the {SubtitleFor
 066                        subtitleFormat.ErrorCount,
 067                        fileExtension,
 068                        subtitleFormat.Name);
 69                }
 70            }
 71
 10972            if (subtitle.Paragraphs.Count == 0)
 73            {
 074                throw new ArgumentException("Unsupported format: " + fileExtension);
 75            }
 76
 10977            return subtitle;
 78        }
 79
 80        /// <inheritdoc />
 81        public bool SupportsFileExtension(string fileExtension)
 082            => _subtitleFormatTypes.ContainsKey(fileExtension);
 83
 84        private Dictionary<string, List<Type>> GetSubtitleFormatTypes()
 85        {
 2986            var subtitleFormatTypes = new Dictionary<string, List<Type>>(StringComparer.OrdinalIgnoreCase);
 2987            var assembly = typeof(SubtitleFormat).Assembly;
 88
 7511089            foreach (var type in assembly.GetTypes())
 90            {
 3752691                if (!type.IsSubclassOf(typeof(SubtitleFormat)) || type.IsAbstract)
 92                {
 93                    continue;
 94                }
 95
 96                try
 97                {
 1154298                    var tempInstance = (SubtitleFormat)Activator.CreateInstance(type, true)!;
 1154299                    var extension = tempInstance.Extension.TrimStart('.');
 11542100                    if (!string.IsNullOrEmpty(extension))
 101                    {
 102                        // Store only the type, we will instantiate from it later
 11542103                        if (!subtitleFormatTypes.TryGetValue(extension, out var subtitleFormatTypesForExtension))
 104                        {
 2726105                            subtitleFormatTypes[extension] = [type];
 106                        }
 107                        else
 108                        {
 8816109                            subtitleFormatTypesForExtension.Add(type);
 110                        }
 111                    }
 11542112                }
 0113                catch (Exception ex)
 114                {
 0115                    _logger.LogWarning(ex, "Failed to create instance of the subtitle format {SubtitleFormatType}", type
 0116                }
 117            }
 118
 29119            return subtitleFormatTypes;
 120        }
 121    }
 122}