< Summary - Jellyfin

Information
Class: MediaBrowser.MediaEncoding.Subtitles.SubtitleEditParser
Assembly: MediaBrowser.MediaEncoding
File(s): /srv/git/jellyfin/MediaBrowser.MediaEncoding/Subtitles/SubtitleEditParser.cs
Line coverage
72%
Covered lines: 40
Uncovered lines: 15
Coverable lines: 55
Total lines: 129
Line coverage: 72.7%
Branch coverage
72%
Covered branches: 13
Total branches: 18
Branch coverage: 72.2%
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(...)58.33%19.81262.16%
SupportsFileExtension(...)100%210%
GetSubtitleFormats()100%66100%

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, SubtitleFormat[]> _subtitleFormats;
 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        {
 2728            _logger = logger;
 2729            _subtitleFormats = GetSubtitleFormats()
 2730                .Where(subtitleFormat => !string.IsNullOrEmpty(subtitleFormat.Extension))
 2731                .GroupBy(subtitleFormat => subtitleFormat.Extension.TrimStart('.'), StringComparer.OrdinalIgnoreCase)
 2732                .ToDictionary(g => g.Key, g => g.ToArray(), StringComparer.OrdinalIgnoreCase);
 2733        }
 34
 35        /// <inheritdoc />
 36        public SubtitleTrackInfo Parse(Stream stream, string fileExtension)
 37        {
 538            var subtitle = new Subtitle();
 539            var lines = stream.ReadAllLines().ToList();
 40
 541            if (!_subtitleFormats.TryGetValue(fileExtension, out var subtitleFormats))
 42            {
 043                throw new ArgumentException($"Unsupported file extension: {fileExtension}", nameof(fileExtension));
 44            }
 45
 1546            foreach (var subtitleFormat in subtitleFormats)
 47            {
 548                _logger.LogDebug(
 549                    "Trying to parse '{FileExtension}' subtitle using the {SubtitleFormatParser} format parser",
 550                    fileExtension,
 551                    subtitleFormat.Name);
 552                subtitleFormat.LoadSubtitle(subtitle, lines, fileExtension);
 553                if (subtitleFormat.ErrorCount == 0)
 54                {
 55                    break;
 56                }
 057                else if (subtitleFormat.TryGetErrors(out var errors))
 58                {
 059                    _logger.LogError(
 060                        "{ErrorCount} errors encountered while parsing '{FileExtension}' subtitle using the {SubtitleFor
 061                        subtitleFormat.ErrorCount,
 062                        fileExtension,
 063                        subtitleFormat.Name,
 064                        errors);
 65                }
 66                else
 67                {
 068                    _logger.LogError(
 069                        "{ErrorCount} errors encountered while parsing '{FileExtension}' subtitle using the {SubtitleFor
 070                        subtitleFormat.ErrorCount,
 071                        fileExtension,
 072                        subtitleFormat.Name);
 73                }
 74            }
 75
 576            if (subtitle.Paragraphs.Count == 0)
 77            {
 078                throw new ArgumentException("Unsupported format: " + fileExtension);
 79            }
 80
 581            var trackInfo = new SubtitleTrackInfo();
 582            int len = subtitle.Paragraphs.Count;
 583            var trackEvents = new SubtitleTrackEvent[len];
 2884            for (int i = 0; i < len; i++)
 85            {
 986                var p = subtitle.Paragraphs[i];
 987                trackEvents[i] = new SubtitleTrackEvent(p.Number.ToString(CultureInfo.InvariantCulture), p.Text)
 988                {
 989                    StartPositionTicks = p.StartTime.TimeSpan.Ticks,
 990                    EndPositionTicks = p.EndTime.TimeSpan.Ticks
 991                };
 92            }
 93
 594            trackInfo.TrackEvents = trackEvents;
 595            return trackInfo;
 96        }
 97
 98        /// <inheritdoc />
 99        public bool SupportsFileExtension(string fileExtension)
 0100            => _subtitleFormats.ContainsKey(fileExtension);
 101
 102        private List<SubtitleFormat> GetSubtitleFormats()
 103        {
 27104            var subtitleFormats = new List<SubtitleFormat>();
 27105            var assembly = typeof(SubtitleFormat).Assembly;
 106
 68634107            foreach (var type in assembly.GetTypes())
 108            {
 34290109                if (!type.IsSubclassOf(typeof(SubtitleFormat)) || type.IsAbstract)
 110                {
 111                    continue;
 112                }
 113
 114                try
 115                {
 116                    // It shouldn't be null, but the exception is caught if it is
 10638117                    var subtitleFormat = (SubtitleFormat)Activator.CreateInstance(type, true)!;
 10633118                    subtitleFormats.Add(subtitleFormat);
 10633119                }
 5120                catch (Exception ex)
 121                {
 5122                    _logger.LogWarning(ex, "Failed to create instance of the subtitle format {SubtitleFormatType}", type
 5123                }
 124            }
 125
 27126            return subtitleFormats;
 127        }
 128    }
 129}