Example #1
0
        public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken)
        {
            using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
            {
                var index = 1;

                foreach (var trackEvent in info.TrackEvents)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    writer.WriteLine(index.ToString(CultureInfo.InvariantCulture));
                    writer.WriteLine(@"{0:hh\:mm\:ss\,fff} --> {1:hh\:mm\:ss\,fff}", TimeSpan.FromTicks(trackEvent.StartPositionTicks), TimeSpan.FromTicks(trackEvent.EndPositionTicks));

                    var text = trackEvent.Text;

                    // TODO: Not sure how to handle these
                    text = Regex.Replace(text, @"\\N", " ", RegexOptions.IgnoreCase);

                    writer.WriteLine(text);
                    writer.WriteLine(string.Empty);

                    index++;
                }
            }
        }
Example #2
0
        public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken)
        {
            using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
            {
                writer.WriteLine("WEBVTT");
                writer.WriteLine(string.Empty);
                foreach (var trackEvent in info.TrackEvents)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    TimeSpan startTime = TimeSpan.FromTicks(trackEvent.StartPositionTicks);
                    TimeSpan endTime = TimeSpan.FromTicks(trackEvent.EndPositionTicks);

                    // make sure the start and end times are different and seqential
                    if (endTime.TotalMilliseconds <= startTime.TotalMilliseconds)
                    {
                        endTime = startTime.Add(TimeSpan.FromMilliseconds(1));
                    }

                    writer.WriteLine(@"{0:hh\:mm\:ss\.fff} --> {1:hh\:mm\:ss\.fff}", startTime, endTime);

                    var text = trackEvent.Text;

                    // TODO: Not sure how to handle these
                    text = Regex.Replace(text, @"\\n", " ", RegexOptions.IgnoreCase);

                    writer.WriteLine(text);
                    writer.WriteLine(string.Empty);
                }
            }
        }
Example #3
0
        public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken)
        {
            using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
            {
                var json = _json.SerializeToString(info);

                writer.Write(json);
            }
        }
Example #4
0
        public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
        {
            var trackInfo = new SubtitleTrackInfo();
            using ( var reader = new StreamReader(stream))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }
                    var subEvent = new SubtitleTrackEvent {Id = line};
                    line = reader.ReadLine();

                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }
                    
                    var time = Regex.Split(line, @"[\t ]*-->[\t ]*");
                    subEvent.StartPositionTicks = GetTicks(time[0]);
                    var endTime = time[1];
                    var idx = endTime.IndexOf(" ", StringComparison.Ordinal);
                    if (idx > 0)
                        endTime = endTime.Substring(0, idx);
                    subEvent.EndPositionTicks = GetTicks(endTime);
                    var multiline = new List<string>();
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (string.IsNullOrEmpty(line))
                        {
                            break;
                        }
                        multiline.Add(line);
                    }
                    subEvent.Text = string.Join(ParserValues.NewLine, multiline);
                    subEvent.Text = subEvent.Text.Replace(@"\N", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, "<", "&lt;", RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, ">", "&gt;", RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, "&lt;(\\/?(font|b|u|i|s))((\\s+(\\w|\\w[\\w\\-]*\\w)(\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)(\\/?)&gt;", "<$1$3$7>", RegexOptions.IgnoreCase);
                    trackInfo.TrackEvents.Add(subEvent);
                }
            }
            return trackInfo;
        }
        public void TestParse() {

            var expectedSubs =
                new SubtitleTrackInfo {
                                          TrackEvents = new List<SubtitleTrackEvent> {
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "1",
                                                                                                                    StartPositionTicks = 24000000,
                                                                                                                    EndPositionTicks = 72000000,
                                                                                                                    Text =
                                                                                                                        "Senator, we're <br />making our final <br />approach into Coruscant."
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "2",
                                                                                                                    StartPositionTicks = 97100000,
                                                                                                                    EndPositionTicks = 133900000,
                                                                                                                    Text =
                                                                                                                        "Very good, Lieutenant."
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "3",
                                                                                                                    StartPositionTicks = 150400000,
                                                                                                                    EndPositionTicks = 180400000,
                                                                                                                    Text = "It's <br />a <br />trap!"
                                                                                                                }
                                                                                     }
                                      };

            var sut = new SsaParser();

            var stream = File.OpenRead(@"MediaEncoding\Subtitles\TestSubtitles\data.ssa");

            var result = sut.Parse(stream, CancellationToken.None);

            Assert.IsNotNull(result);
            Assert.AreEqual(expectedSubs.TrackEvents.Count,result.TrackEvents.Count);
            for (int i = 0; i < expectedSubs.TrackEvents.Count; i++)
            {
                Assert.AreEqual(expectedSubs.TrackEvents[i].Id, result.TrackEvents[i].Id);
                Assert.AreEqual(expectedSubs.TrackEvents[i].StartPositionTicks, result.TrackEvents[i].StartPositionTicks);
                Assert.AreEqual(expectedSubs.TrackEvents[i].EndPositionTicks, result.TrackEvents[i].EndPositionTicks);
                Assert.AreEqual(expectedSubs.TrackEvents[i].Text, result.TrackEvents[i].Text);
            }

        }
Example #6
0
        public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
        {
            var trackInfo = new SubtitleTrackInfo();
            var eventIndex = 1;
            using (var reader = new StreamReader(stream))
            {
                string line;
                while (reader.ReadLine() != "[Events]")
                {}
                var headers = ParseFieldHeaders(reader.ReadLine());

                while ((line = reader.ReadLine()) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }
                    if(line.StartsWith("["))
                        break;
                    if(string.IsNullOrEmpty(line))
                        continue;
                    var subEvent = new SubtitleTrackEvent { Id = eventIndex.ToString(_usCulture) };
                    eventIndex++;
                    var sections = line.Substring(10).Split(',');

                    subEvent.StartPositionTicks = GetTicks(sections[headers["Start"]]);
                    subEvent.EndPositionTicks = GetTicks(sections[headers["End"]]);

                    subEvent.Text = string.Join(",", sections.Skip(headers["Text"]));
                    RemoteNativeFormatting(subEvent);

                    subEvent.Text = subEvent.Text.Replace("\\n", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
                    
                    subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase);

                    trackInfo.TrackEvents.Add(subEvent);
                }
            }
            return trackInfo;
        }
Example #7
0
        public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken)
        {
            // Example: https://github.com/zmalltalker/ttml2vtt/blob/master/data/sample.xml
            // Parser example: https://github.com/mozilla/popcorn-js/blob/master/parsers/parserTTML/popcorn.parserTTML.js

            using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
            {
                writer.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                writer.WriteLine("<tt xmlns=\"http://www.w3.org/ns/ttml\" xmlns:tts=\"http://www.w3.org/2006/04/ttaf1#styling\" lang=\"no\">");

                writer.WriteLine("<head>");
                writer.WriteLine("<styling>");
                writer.WriteLine("<style id=\"italic\" tts:fontStyle=\"italic\" />");
                writer.WriteLine("<style id=\"left\" tts:textAlign=\"left\" />");
                writer.WriteLine("<style id=\"center\" tts:textAlign=\"center\" />");
                writer.WriteLine("<style id=\"right\" tts:textAlign=\"right\" />");
                writer.WriteLine("</styling>");
                writer.WriteLine("</head>");

                writer.WriteLine("<body>");
                writer.WriteLine("<div>");

                foreach (var trackEvent in info.TrackEvents)
                {
                    var text = trackEvent.Text;

                    text = Regex.Replace(text, @"\\n", "<br/>", RegexOptions.IgnoreCase);

                    writer.WriteLine("<p begin=\"{0}\" dur=\"{1}\">{2}</p>",
                        trackEvent.StartPositionTicks,
                        (trackEvent.EndPositionTicks - trackEvent.StartPositionTicks),
                        text);
                }

                writer.WriteLine("</div>");
                writer.WriteLine("</body>");
                
                writer.WriteLine("</tt>");
            }
        }
Example #8
0
        private void FilterEvents(SubtitleTrackInfo track, long startPositionTicks, long endTimeTicks, bool preserveTimestamps)
        {
            // Drop subs that are earlier than what we're looking for
            track.TrackEvents = track.TrackEvents
                                .SkipWhile(i => (i.StartPositionTicks - startPositionTicks) < 0 || (i.EndPositionTicks - startPositionTicks) < 0)
                                .ToArray();

            if (endTimeTicks > 0)
            {
                track.TrackEvents = track.TrackEvents
                                    .TakeWhile(i => i.StartPositionTicks <= endTimeTicks)
                                    .ToArray();
            }

            if (!preserveTimestamps)
            {
                foreach (var trackEvent in track.TrackEvents)
                {
                    trackEvent.EndPositionTicks   -= startPositionTicks;
                    trackEvent.StartPositionTicks -= startPositionTicks;
                }
            }
        }
Example #9
0
        /// <inheritdoc />
        public void Write(SubtitleTrackInfo info, Stream stream, CancellationToken cancellationToken)
        {
            using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
            {
                var trackEvents = info.TrackEvents;
                var timeFormat  = @"hh\:mm\:ss\.ff";

                // Write ASS header
                writer.WriteLine("[Script Info]");
                writer.WriteLine("Title: Jellyfin transcoded ASS subtitle");
                writer.WriteLine("ScriptType: v4.00+");
                writer.WriteLine();
                writer.WriteLine("[V4+ Styles]");
                writer.WriteLine("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding");
                writer.WriteLine("Style: Default,Arial,20,&H00FFFFFF,&H00FFFFFF,&H19333333,&H910E0807,0,0,0,0,100,100,0,0,0,1,0,2,10,10,10,1");
                writer.WriteLine();
                writer.WriteLine("[Events]");
                writer.WriteLine("Format: Layer, Start, End, Style, Text");

                for (int i = 0; i < trackEvents.Count; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var trackEvent = trackEvents[i];
                    var startTime  = TimeSpan.FromTicks(trackEvent.StartPositionTicks).ToString(timeFormat, CultureInfo.InvariantCulture);
                    var endTime    = TimeSpan.FromTicks(trackEvent.EndPositionTicks).ToString(timeFormat, CultureInfo.InvariantCulture);
                    var text       = Regex.Replace(trackEvent.Text, @"\n", "\\n", RegexOptions.IgnoreCase);

                    writer.WriteLine(
                        "Dialogue: 0,{0},{1},Default,{2}",
                        startTime,
                        endTime,
                        text);
                }
            }
        }
Example #10
0
        public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
        {
            var trackInfo = new SubtitleTrackInfo();

            using (var reader = new StreamReader(stream))
            {
                bool eventsStarted = false;

                string[] format      = "Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text".Split(',');
                int      indexLayer  = 0;
                int      indexStart  = 1;
                int      indexEnd    = 2;
                int      indexStyle  = 3;
                int      indexName   = 4;
                int      indexEffect = 8;
                int      indexText   = 9;
                int      lineNumber  = 0;

                var header = new StringBuilder();

                string line;

                while ((line = reader.ReadLine()) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    lineNumber++;
                    if (!eventsStarted)
                    {
                        header.AppendLine(line);
                    }

                    if (line.Trim().ToLower() == "[events]")
                    {
                        eventsStarted = true;
                    }
                    else if (!string.IsNullOrEmpty(line) && line.Trim().StartsWith(";"))
                    {
                        // skip comment lines
                    }
                    else if (eventsStarted && line.Trim().Length > 0)
                    {
                        string s = line.Trim().ToLower();
                        if (s.StartsWith("format:"))
                        {
                            if (line.Length > 10)
                            {
                                format = line.ToLower().Substring(8).Split(',');
                                for (int i = 0; i < format.Length; i++)
                                {
                                    if (format[i].Trim().ToLower() == "layer")
                                    {
                                        indexLayer = i;
                                    }
                                    else if (format[i].Trim().ToLower() == "start")
                                    {
                                        indexStart = i;
                                    }
                                    else if (format[i].Trim().ToLower() == "end")
                                    {
                                        indexEnd = i;
                                    }
                                    else if (format[i].Trim().ToLower() == "text")
                                    {
                                        indexText = i;
                                    }
                                    else if (format[i].Trim().ToLower() == "effect")
                                    {
                                        indexEffect = i;
                                    }
                                    else if (format[i].Trim().ToLower() == "style")
                                    {
                                        indexStyle = i;
                                    }
                                }
                            }
                        }
                        else if (!string.IsNullOrEmpty(s))
                        {
                            string text   = string.Empty;
                            string start  = string.Empty;
                            string end    = string.Empty;
                            string style  = string.Empty;
                            string layer  = string.Empty;
                            string effect = string.Empty;
                            string name   = string.Empty;

                            string[] splittedLine;

                            if (s.StartsWith("dialogue:"))
                            {
                                splittedLine = line.Substring(10).Split(',');
                            }
                            else
                            {
                                splittedLine = line.Split(',');
                            }

                            for (int i = 0; i < splittedLine.Length; i++)
                            {
                                if (i == indexStart)
                                {
                                    start = splittedLine[i].Trim();
                                }
                                else if (i == indexEnd)
                                {
                                    end = splittedLine[i].Trim();
                                }
                                else if (i == indexLayer)
                                {
                                    layer = splittedLine[i];
                                }
                                else if (i == indexEffect)
                                {
                                    effect = splittedLine[i];
                                }
                                else if (i == indexText)
                                {
                                    text = splittedLine[i];
                                }
                                else if (i == indexStyle)
                                {
                                    style = splittedLine[i];
                                }
                                else if (i == indexName)
                                {
                                    name = splittedLine[i];
                                }
                                else if (i > indexText)
                                {
                                    text += "," + splittedLine[i];
                                }
                            }

                            try
                            {
                                var p = new SubtitleTrackEvent();

                                p.StartPositionTicks = GetTimeCodeFromString(start);
                                p.EndPositionTicks   = GetTimeCodeFromString(end);
                                p.Text = GetFormattedText(text);

                                trackInfo.TrackEvents.Add(p);
                            }
                            catch
                            {
                            }
                        }
                    }
                }

                //if (header.Length > 0)
                //subtitle.Header = header.ToString();

                //subtitle.Renumber(1);
            }
            return(trackInfo);
        }
Example #11
0
        public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
        {
            var trackInfo = new SubtitleTrackInfo();
            List <SubtitleTrackEvent> trackEvents = new List <SubtitleTrackEvent>();

            using (var reader = new StreamReader(stream))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }
                    var subEvent = new SubtitleTrackEvent {
                        Id = line
                    };
                    line = reader.ReadLine();

                    if (string.IsNullOrWhiteSpace(line))
                    {
                        continue;
                    }

                    var time = Regex.Split(line, @"[\t ]*-->[\t ]*");

                    if (time.Length < 2)
                    {
                        // This occurs when subtitle text has an empty line as part of the text.
                        // Need to adjust the break statement below to resolve this.
                        _logger.LogWarning("Unrecognized line in srt: {0}", line);
                        continue;
                    }
                    subEvent.StartPositionTicks = GetTicks(time[0]);
                    var endTime = time[1];
                    var idx     = endTime.IndexOf(" ", StringComparison.Ordinal);
                    if (idx > 0)
                    {
                        endTime = endTime.Substring(0, idx);
                    }
                    subEvent.EndPositionTicks = GetTicks(endTime);
                    var multiline = new List <string>();
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (string.IsNullOrEmpty(line))
                        {
                            break;
                        }
                        multiline.Add(line);
                    }
                    subEvent.Text = string.Join(ParserValues.NewLine, multiline);
                    subEvent.Text = subEvent.Text.Replace(@"\N", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, @"\{(?:\\\d?[\w.-]+(?:\([^\)]*\)|&H?[0-9A-Fa-f]+&|))+\}", string.Empty, RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, "<", "&lt;", RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, ">", "&gt;", RegexOptions.IgnoreCase);
                    subEvent.Text = Regex.Replace(subEvent.Text, "&lt;(\\/?(font|b|u|i|s))((\\s+(\\w|\\w[\\w\\-]*\\w)(\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)(\\/?)&gt;", "<$1$3$7>", RegexOptions.IgnoreCase);
                    trackEvents.Add(subEvent);
                }
            }
            trackInfo.TrackEvents = trackEvents.ToArray();
            return(trackInfo);
        }
Example #12
0
        public void TestParse() {

            var expectedSubs =
                new SubtitleTrackInfo {
                                          TrackEvents = new List<SubtitleTrackEvent> {
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "1",
                                                                                                                    StartPositionTicks = 24000000,
                                                                                                                    EndPositionTicks = 52000000,
                                                                                                                    Text =
                                                                                                                        "[Background Music Playing]"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "2",
                                                                                                                    StartPositionTicks = 157120000,
                                                                                                                    EndPositionTicks = 173990000,
                                                                                                                    Text =
                                                                                                                        "Oh my god, Watch out!<br />It's coming!!"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "3",
                                                                                                                    StartPositionTicks = 257120000,
                                                                                                                    EndPositionTicks = 303990000,
                                                                                                                    Text = "[Bird noises]"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "4",
                                                                                                                    StartPositionTicks = 310000000,
                                                                                                                    EndPositionTicks = 319990000,
                                                                                                                    Text =
                                                                                                                        "This text is <font color=\"red\">RED</font> and has not been positioned."
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "5",
                                                                                                                    StartPositionTicks = 320000000,
                                                                                                                    EndPositionTicks = 329990000,
                                                                                                                    Text =
                                                                                                                        "This is a<br />new line, as is<br />this"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "6",
                                                                                                                    StartPositionTicks = 330000000,
                                                                                                                    EndPositionTicks = 339990000,
                                                                                                                    Text =
                                                                                                                        "This contains nested <b>bold, <i>italic, <u>underline</u> and <s>strike-through</s></u></i></b> HTML tags"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "7",
                                                                                                                    StartPositionTicks = 340000000,
                                                                                                                    EndPositionTicks = 349990000,
                                                                                                                    Text =
                                                                                                                        "Unclosed but <b>supported HTML tags are left in,  SSA italics aren't"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "8",
                                                                                                                    StartPositionTicks = 350000000,
                                                                                                                    EndPositionTicks = 359990000,
                                                                                                                    Text =
                                                                                                                        "&lt;ggg&gt;Unsupported&lt;/ggg&gt; HTML tags are escaped and left in, even if &lt;hhh&gt;not closed."
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "9",
                                                                                                                    StartPositionTicks = 360000000,
                                                                                                                    EndPositionTicks = 369990000,
                                                                                                                    Text =
                                                                                                                        "Multiple SSA tags are stripped"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "10",
                                                                                                                    StartPositionTicks = 370000000,
                                                                                                                    EndPositionTicks = 379990000,
                                                                                                                    Text =
                                                                                                                        "Greater than (&lt;) and less than (&gt;) are shown"
                                                                                                                }
                                                                                     }
                                      };

            var sut = new SrtParser();

            var stream = File.OpenRead(@"MediaEncoding\Subtitles\TestSubtitles\unit.srt");

            var result = sut.Parse(stream, CancellationToken.None);

            Assert.IsNotNull(result);
            Assert.AreEqual(expectedSubs.TrackEvents.Count,result.TrackEvents.Count);
            for (int i = 0; i < expectedSubs.TrackEvents.Count; i++)
            {
                Assert.AreEqual(expectedSubs.TrackEvents[i].Id, result.TrackEvents[i].Id);
                Assert.AreEqual(expectedSubs.TrackEvents[i].StartPositionTicks, result.TrackEvents[i].StartPositionTicks);
                Assert.AreEqual(expectedSubs.TrackEvents[i].EndPositionTicks, result.TrackEvents[i].EndPositionTicks);
                Assert.AreEqual(expectedSubs.TrackEvents[i].Text, result.TrackEvents[i].Text);
            }

        }
Example #13
0
        public SubtitleTrackInfo Parse(Stream stream, CancellationToken cancellationToken)
        {
            var trackInfo = new SubtitleTrackInfo();

            using (var reader = new StreamReader(stream))
            {
                bool eventsStarted = false;

                string[] format = "Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text".Split(',');
                int indexLayer = 0;
                int indexStart = 1;
                int indexEnd = 2;
                int indexStyle = 3;
                int indexName = 4;
                int indexEffect = 8;
                int indexText = 9;
                int lineNumber = 0;

                var header = new StringBuilder();

                string line;

                while ((line = reader.ReadLine()) != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    lineNumber++;
                    if (!eventsStarted)
                        header.AppendLine(line);

                    if (line.Trim().ToLower() == "[events]")
                    {
                        eventsStarted = true;
                    }
                    else if (!string.IsNullOrEmpty(line) && line.Trim().StartsWith(";"))
                    {
                        // skip comment lines
                    }
                    else if (eventsStarted && line.Trim().Length > 0)
                    {
                        string s = line.Trim().ToLower();
                        if (s.StartsWith("format:"))
                        {
                            if (line.Length > 10)
                            {
                                format = line.ToLower().Substring(8).Split(',');
                                for (int i = 0; i < format.Length; i++)
                                {
                                    if (format[i].Trim().ToLower() == "layer")
                                        indexLayer = i;
                                    else if (format[i].Trim().ToLower() == "start")
                                        indexStart = i;
                                    else if (format[i].Trim().ToLower() == "end")
                                        indexEnd = i;
                                    else if (format[i].Trim().ToLower() == "text")
                                        indexText = i;
                                    else if (format[i].Trim().ToLower() == "effect")
                                        indexEffect = i;
                                    else if (format[i].Trim().ToLower() == "style")
                                        indexStyle = i;
                                }
                            }
                        }
                        else if (!string.IsNullOrEmpty(s))
                        {
                            string text = string.Empty;
                            string start = string.Empty;
                            string end = string.Empty;
                            string style = string.Empty;
                            string layer = string.Empty;
                            string effect = string.Empty;
                            string name = string.Empty;

                            string[] splittedLine;

                            if (s.StartsWith("dialogue:"))
                                splittedLine = line.Substring(10).Split(',');
                            else
                                splittedLine = line.Split(',');

                            for (int i = 0; i < splittedLine.Length; i++)
                            {
                                if (i == indexStart)
                                    start = splittedLine[i].Trim();
                                else if (i == indexEnd)
                                    end = splittedLine[i].Trim();
                                else if (i == indexLayer)
                                    layer = splittedLine[i];
                                else if (i == indexEffect)
                                    effect = splittedLine[i];
                                else if (i == indexText)
                                    text = splittedLine[i];
                                else if (i == indexStyle)
                                    style = splittedLine[i];
                                else if (i == indexName)
                                    name = splittedLine[i];
                                else if (i > indexText)
                                    text += "," + splittedLine[i];
                            }

                            try
                            {
                                var p = new SubtitleTrackEvent();

                                p.StartPositionTicks = GetTimeCodeFromString(start);
                                p.EndPositionTicks = GetTimeCodeFromString(end);
                                p.Text = GetFormattedText(text);

                                trackInfo.TrackEvents.Add(p);
                            }
                            catch
                            {
                            }
                        }
                    }
                } 
                
                //if (header.Length > 0)
                    //subtitle.Header = header.ToString();

                //subtitle.Renumber(1);
            }
            return trackInfo;
        }
Example #14
0
        public void TestWrite()
        {
            var infoSubs =
                new SubtitleTrackInfo
                {
                    TrackEvents = new List<SubtitleTrackEvent> {
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "1",
                                                                                                                    StartPositionTicks = 24000000,
                                                                                                                    EndPositionTicks = 52000000,
                                                                                                                    Text =
                                                                                                                        "[Background Music Playing]"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "2",
                                                                                                                    StartPositionTicks = 157120000,
                                                                                                                    EndPositionTicks = 173990000,
                                                                                                                    Text =
                                                                                                                        "Oh my god, Watch out!<br />It's coming!!"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "3",
                                                                                                                    StartPositionTicks = 257120000,
                                                                                                                    EndPositionTicks = 303990000,
                                                                                                                    Text = "[Bird noises]"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "4",
                                                                                                                    StartPositionTicks = 310000000,
                                                                                                                    EndPositionTicks = 319990000,
                                                                                                                    Text =
                                                                                                                        "This text is <font color=\"red\">RED</font> and has not been positioned."
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "5",
                                                                                                                    StartPositionTicks = 320000000,
                                                                                                                    EndPositionTicks = 329990000,
                                                                                                                    Text =
                                                                                                                        "This is a<br />new line, as is<br />this"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "6",
                                                                                                                    StartPositionTicks = 330000000,
                                                                                                                    EndPositionTicks = 339990000,
                                                                                                                    Text =
                                                                                                                        "This contains nested <b>bold, <i>italic, <u>underline</u> and <s>strike-through</s></u></i></b> HTML tags"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "7",
                                                                                                                    StartPositionTicks = 340000000,
                                                                                                                    EndPositionTicks = 349990000,
                                                                                                                    Text =
                                                                                                                        "Unclosed but <b>supported HTML tags are left in,  SSA italics aren't"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "8",
                                                                                                                    StartPositionTicks = 350000000,
                                                                                                                    EndPositionTicks = 359990000,
                                                                                                                    Text =
                                                                                                                        "&lt;ggg&gt;Unsupported&lt;/ggg&gt; HTML tags are escaped and left in, even if &lt;hhh&gt;not closed."
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "9",
                                                                                                                    StartPositionTicks = 360000000,
                                                                                                                    EndPositionTicks = 369990000,
                                                                                                                    Text =
                                                                                                                        "Multiple SSA tags are stripped"
                                                                                                                },
                                                                                         new SubtitleTrackEvent {
                                                                                                                    Id = "10",
                                                                                                                    StartPositionTicks = 370000000,
                                                                                                                    EndPositionTicks = 379990000,
                                                                                                                    Text =
                                                                                                                        "Greater than (&lt;) and less than (&gt;) are shown"
                                                                                                                }
                                                                                     }
                };

            var sut = new VttWriter();

            if(File.Exists("testVTT.vtt"))
                File.Delete("testVTT.vtt");
            using (var file = File.OpenWrite("testVTT.vtt"))
            {
                sut.Write(infoSubs, file, CancellationToken.None);
            }

            var result = File.ReadAllText("testVTT.vtt");
            var expectedText = File.ReadAllText(@"MediaEncoding\Subtitles\TestSubtitles\expected.vtt");

            Assert.AreEqual(expectedText, result);
        }