< Summary - Jellyfin

Information
Class: MediaBrowser.MediaEncoding.Subtitles.SubtitleEditParser
Assembly: MediaBrowser.MediaEncoding
File(s): /srv/git/jellyfin/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs
Line coverage
74%
Covered lines: 43
Uncovered lines: 15
Coverable lines: 58
Total lines: 138
Line coverage: 74.1%
Branch coverage
72%
Covered branches: 16
Total branches: 22
Branch coverage: 72.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
Parse(...)50%191264.1%
SupportsFileExtension(...)100%210%
GetSubtitleFormatTypes()100%1010100%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Globalization;
 4using System.IO;
 5using System.Linq;
 6using Jellyfin.Extensions;
 7using MediaBrowser.Model.MediaInfo;
 8using Microsoft.Extensions.Logging;
 9using Nikse.SubtitleEdit.Core.Common;
 10using SubtitleFormat = Nikse.SubtitleEdit.Core.SubtitleFormats.SubtitleFormat;
 11
 12namespace MediaBrowser.MediaEncoding.Subtitles
 13{
 14    /// <summary>
 15    /// SubStation Alpha subtitle parser.
 16    /// </summary>
 17    public class SubtitleEditParser : ISubtitleParser
 18    {
 19        private readonly ILogger<SubtitleEditParser> _logger;
 20        private readonly Dictionary<string, List<Type>> _subtitleFormatTypes;
 21
 22        /// <summary>
 23        /// Initializes a new instance of the <see cref="SubtitleEditParser"/> class.
 24        /// </summary>
 25        /// <param name="logger">The logger.</param>
 26        public SubtitleEditParser(ILogger<SubtitleEditParser> logger)
 27        {
 2628            _logger = logger;
 2629            _subtitleFormatTypes = GetSubtitleFormatTypes();
 2630        }
 31
 32        /// <inheritdoc />
 33        public SubtitleTrackInfo Parse(Stream stream, string fileExtension)
 34        {
 535            var subtitle = new Subtitle();
 536            var lines = stream.ReadAllLines().ToList();
 37
 538            if (!_subtitleFormatTypes.TryGetValue(fileExtension, out var subtitleFormatTypesForExtension))
 39            {
 040                throw new ArgumentException($"Unsupported file extension: {fileExtension}", nameof(fileExtension));
 41            }
 42
 1543            foreach (var subtitleFormatType in subtitleFormatTypesForExtension)
 44            {
 545                var subtitleFormat = (SubtitleFormat)Activator.CreateInstance(subtitleFormatType, true)!;
 546                _logger.LogDebug(
 547                    "Trying to parse '{FileExtension}' subtitle using the {SubtitleFormatParser} format parser",
 548                    fileExtension,
 549                    subtitleFormat.Name);
 550                subtitleFormat.LoadSubtitle(subtitle, lines, fileExtension);
 551                if (subtitleFormat.ErrorCount == 0)
 52                {
 553                    break;
 54                }
 055                else if (subtitleFormat.TryGetErrors(out var errors))
 56                {
 057                    _logger.LogError(
 058                        "{ErrorCount} errors encountered while parsing '{FileExtension}' subtitle using the {SubtitleFor
 059                        subtitleFormat.ErrorCount,
 060                        fileExtension,
 061                        subtitleFormat.Name,
 062                        errors);
 63                }
 64                else
 65                {
 066                    _logger.LogError(
 067                        "{ErrorCount} errors encountered while parsing '{FileExtension}' subtitle using the {SubtitleFor
 068                        subtitleFormat.ErrorCount,
 069                        fileExtension,
 070                        subtitleFormat.Name);
 71                }
 72            }
 73
 574            if (subtitle.Paragraphs.Count == 0)
 75            {
 076                throw new ArgumentException("Unsupported format: " + fileExtension);
 77            }
 78
 579            var trackInfo = new SubtitleTrackInfo();
 580            int len = subtitle.Paragraphs.Count;
 581            var trackEvents = new SubtitleTrackEvent[len];
 2882            for (int i = 0; i < len; i++)
 83            {
 984                var p = subtitle.Paragraphs[i];
 985                trackEvents[i] = new SubtitleTrackEvent(p.Number.ToString(CultureInfo.InvariantCulture), p.Text)
 986                {
 987                    StartPositionTicks = p.StartTime.TimeSpan.Ticks,
 988                    EndPositionTicks = p.EndTime.TimeSpan.Ticks
 989                };
 90            }
 91
 592            trackInfo.TrackEvents = trackEvents;
 593            return trackInfo;
 94        }
 95
 96        /// <inheritdoc />
 97        public bool SupportsFileExtension(string fileExtension)
 098            => _subtitleFormatTypes.ContainsKey(fileExtension);
 99
 100        private Dictionary<string, List<Type>> GetSubtitleFormatTypes()
 101        {
 26102            var subtitleFormatTypes = new Dictionary<string, List<Type>>(StringComparer.OrdinalIgnoreCase);
 26103            var assembly = typeof(SubtitleFormat).Assembly;
 104
 66612105            foreach (var type in assembly.GetTypes())
 106            {
 33280107                if (!type.IsSubclassOf(typeof(SubtitleFormat)) || type.IsAbstract)
 108                {
 109                    continue;
 110                }
 111
 112                try
 113                {
 10322114                    var tempInstance = (SubtitleFormat)Activator.CreateInstance(type, true)!;
 10317115                    var extension = tempInstance.Extension.TrimStart('.');
 10317116                    if (!string.IsNullOrEmpty(extension))
 117                    {
 118                        // Store only the type, we will instantiate from it later
 10317119                        if (!subtitleFormatTypes.TryGetValue(extension, out var subtitleFormatTypesForExtension))
 120                        {
 2439121                            subtitleFormatTypes[extension] = [type];
 122                        }
 123                        else
 124                        {
 7878125                            subtitleFormatTypesForExtension.Add(type);
 126                        }
 127                    }
 10317128                }
 5129                catch (Exception ex)
 130                {
 5131                    _logger.LogWarning(ex, "Failed to create instance of the subtitle format {SubtitleFormatType}", type
 5132                }
 133            }
 134
 26135            return subtitleFormatTypes;
 136        }
 137    }
 138}