コード例 #1
0
        /* Public methods */

        /// <summary>Creates new empty <see cref="Subtitles" />.</summary>
        /// <returns>The newly created subtitles.</returns>
        public Subtitles New()
        {
            SubtitleCollection collection = new SubtitleCollection();
            SubtitleProperties properties = new SubtitleProperties();

            return(new Subtitles(collection, properties));
        }
コード例 #2
0
        /// <summary>Parses the specified text, using the specified format.</summary>
        /// <remarks>The created <see cref="SubtitleCollection" /> will have its <see cref="SubtitleProperties" /> property set to null.
        /// It is mandatory to use <see cref="SubtitleCollection.SetPropertiesForAll" /> after.</remarks>
        internal ParsingProperties Parse(string text, SubtitleFormat format, float inputFrameRate,
                                         out SubtitleCollection collection, out IncompleteSubtitleCollection incompleteSubtitles)
        {
            collection          = new SubtitleCollection();
            incompleteSubtitles = new IncompleteSubtitleCollection();
            ParsingProperties properties = new ParsingProperties();

            properties.InputFrameRate = inputFrameRate;

            Regex subtitleRegex = null;
            int   bodyIndex     = 0;

            text = ClearComments(text, format);

            /* Read the headers if available */
            if (format.Mode == SubtitleMode.Both)
            {
                //Read headers to know if format is using Times or Frames
                bodyIndex = text.Length;
                int lastIndex = ReadHeaders(text, bodyIndex, format, properties);
                subtitleRegex = CreateSubtitleRegex(format, properties.TimingMode);

                /* Detect body index from matching the first subtitle or the end of headers */
                bodyIndex = FindBodyIndex(text, format, subtitleRegex);
                if (lastIndex > bodyIndex)
                {
                    bodyIndex = lastIndex;
                }
            }
            else
            {
                //End of headers is detected by start of subtitles' body
                properties.TimingMode = format.ModeAsTimingMode;
                subtitleRegex         = CreateSubtitleRegex(format);
                bodyIndex             = FindBodyIndex(text, format, subtitleRegex);
                ReadHeaders(text, bodyIndex, format, properties);
            }

            /* Get properties from the whole input, if available */
            format.GlobalInputGetProperties(text, properties);

            int textLength = text.Length;

            /* Read the subtitles */
            bodyIndex = ReadSubtitles(text, bodyIndex, textLength, subtitleRegex, format,
                                      properties, collection, incompleteSubtitles);

            /* Read the end text of the subtitles */
            bodyIndex = ReadBodyEnd(text, bodyIndex, format, collection, incompleteSubtitles);

            /* Check if there's still text remaining */
            if ((bodyIndex < textLength) && includeIncompleteSubtitles)
            {
                AddIncompleteSubtitle(incompleteSubtitles, text.Substring(bodyIndex), collection.Count);
            }

            return(properties);
        }
コード例 #3
0
        /// <summary>Parses the specified text.</summary>
        /// <remarks>The created <see cref="SubtitleCollection" /> will have its <see cref="SubtitleProperties" /> property set to null.
        /// It is mandatory to use <see cref="SubtitleCollection.SetPropertiesForAll" /> after.</remarks>
        internal ParsingProperties Parse(string text, TimingMode timingMode, Encoding encoding, out SubtitleCollection collection)
        {
            collection = new SubtitleCollection();
            ParsingProperties properties = new ParsingProperties();

            this.text             = text;
            properties.TimingMode = timingMode;

            /* Read the subtitles */
            ReadSubtitles(encoding, properties, collection);

            return(properties);
        }
コード例 #4
0
        private int ReadBodyEnd(string text, int bodyIndex, SubtitleFormat format,
                                SubtitleCollection collection, IncompleteSubtitleCollection incompleteSubtitles)
        {
            Regex bodyEnd      = new Regex(format.BodyEndIn + @"\s*", RegexOptions.IgnoreCase);
            Match bodyEndMatch = bodyEnd.Match(text, bodyIndex);

            if (bodyEndMatch.Success)
            {
                AddIncompleteSubtitleIfExists(text, bodyEndMatch, bodyIndex, collection.Count, incompleteSubtitles);
                bodyIndex = bodyEndMatch.Index + bodyEndMatch.Length;
            }
            return(bodyIndex);
        }
コード例 #5
0
 private void ReadSubtitles(Encoding encoding, ParsingProperties properties, SubtitleCollection collection)
 {
     string[] lines = text.Split(new char[] { '\n' });
     for (int i = 0; i < lines.Length; i++)
     {
         SubtitleText stext = ParseSubtitleText(lines[i]);
         Style        style = new Style();
         if (!stext.IsEmpty)
         {
             Subtitle subtitle = new Subtitle(null, stext, style);
             collection.Add(subtitle);
         }
     }
 }
コード例 #6
0
        /// <summary>Searches backward for text using the specified search options.</summary>
        /// <param name="options">The search options.</param>
        /// <returns>The search results, or null in case no results were found.</returns>
        private SubtitleSearchResults FindBackward(SubtitleSearchOptions options)
        {
            SubtitleCollection collection = subtitles.Collection;

            if (collection.Count == 0)
            {
                return(null);
            }

            /* Search the subtitle starting at the startIndex */
            SubtitleSearchResults results = FindInSubtitleFromIndex(options.StartSubtitle, options.LineBreak, options.Regex, options.StartIndex, options.TextType, options.Backwards);

            if (results != null)
            {
                return(results);
            }

            /* Iterate through the start of the collection */
            for (int subtitleNumber = options.StartSubtitle - 1; subtitleNumber > 0; subtitleNumber--)
            {
                results = FindInSubtitle(subtitleNumber, options.LineBreak, options.Regex, options.Backwards);
                if (results != null)
                {
                    return(results);
                }
            }

            if (options.Wrap)
            {
                /* Iterate from the end back to the subtitle */
                for (int subtitleNumber = collection.Count - 1; subtitleNumber > options.StartSubtitle; subtitleNumber--)
                {
                    results = FindInSubtitle(subtitleNumber, options.LineBreak, options.Regex, options.Backwards);
                    if (results != null)
                    {
                        return(results);
                    }
                }
                /* Search the subtitle ending at the startIndex */
                results = FindInSubtitleTillIndex(options.StartSubtitle, options.LineBreak, options.Regex, options.StartIndex, options.TextType, options.Backwards);
                if (results != null)
                {
                    return(results);
                }
            }

            /* Text not found */
            return(null);
        }
コード例 #7
0
        /// <summary>Finds the subtitle containing the specified time.</summary>
        /// <param name="time">The time position.</param>
        /// <returns>The number of the subtitle that was found, or -1 if no subtitle was found.</returns>
        public int FindWithTime(TimeSpan time)
        {
            SubtitleCollection collection = subtitles.Collection;

            for (int subtitleNumber = 0; subtitleNumber < collection.Count; subtitleNumber++)
            {
                Subtitle subtitle = collection[subtitleNumber];
                if ((time >= subtitle.Times.Start) && (time <= subtitle.Times.End))
                {
                    return(subtitleNumber);
                }
            }

            return(-1);    // No subtitles were found
        }
コード例 #8
0
ファイル: SrtSubtitle.cs プロジェクト: yangwen27/moonlit
        /// <summary>
        /// Writes the specified filename.
        /// </summary>
        /// <param name="filename">The filename.</param>
        /// <param name="subs">The subs.</param>
        public void Write(string filename, SubtitleCollection subs)
        {
            using (FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) {
                StreamWriter writer = new StreamWriter(fs, System.Text.Encoding.Default);

                foreach (SubtitleItem subtitle in subs) {
                    writer.WriteLine(subtitle.Order);
                    writer.WriteLine("{0} --> {1}", ToString(subtitle.Start), ToString(subtitle.End));
                    writer.WriteLine(subtitle.Content);
                    writer.WriteLine();
                }
                writer.Flush();
                fs.Flush();
            }
        }
コード例 #9
0
        /// <summary>Finds the subtitle nearer the specified time.</summary>
        /// <param name="time">The time position.</param>
        /// <returns>The number of the subtitle that was found, or -1 if no subtitle was found.</returns>
        public int FindNearTime(TimeSpan time)
        {
            SubtitleCollection collection = subtitles.Collection;

            if (collection.Count == 0)
            {
                return(-1);
            }

            /* Check if before the first subtitle */
            if (time < collection[0].Times.Start)
            {
                return(0);
            }

            /* Iterate subtitles two by two - the last subtitle is handled in pair and individually afterwards */
            for (int subtitleNumber = 0; subtitleNumber < collection.Count - 1; subtitleNumber++)
            {
                Subtitle subtitle = collection[subtitleNumber];

                /* Continue iterating if didn't reach subtitle start yet */
                TimeSpan start = subtitle.Times.Start;
                if (time < start)
                {
                    continue;
                }

                /* Check if time is contained by the subtitle */
                TimeSpan end = subtitle.Times.End;
                if (time <= end)
                {
                    return(subtitleNumber);
                }

                /* Check if contained between this and the next subtitle, and which is nearest */
                int      nextSubtitleIndex = subtitleNumber + 1;
                Subtitle nextSubtitle      = collection[nextSubtitleIndex];
                TimeSpan nextSubtitleStart = nextSubtitle.Times.Start;
                if (time < nextSubtitleStart)
                {
                    return(((time - end) < (nextSubtitleStart - time)) ? subtitleNumber : nextSubtitleIndex);
                }
            }

            /* If no rule matched before, time must be after last subtitle */
            return(collection.Count - 1);
        }
コード例 #10
0
        private Subtitles ParsedSubtitlesPlain(string path, Encoding fileEncoding, string text, bool withCharacterNames, TimingMode timingMode, string lineSeparator)
        {
            SubtitleCollection collection        = null;
            PlainTextParser    plainParser       = new PlainTextParser(withCharacterNames, lineSeparator);
            ParsingProperties  parsingProperties = plainParser.Parse(text, timingMode, fileEncoding, out collection);

            SubtitleProperties subtitleProperties = new SubtitleProperties(parsingProperties);

            collection.SetPropertiesForAll(subtitleProperties);

            Subtitles subtitles = new Subtitles(collection, subtitleProperties);

            CompleteTimingsAfterParsing(subtitles, parsingProperties);

            fileProperties = new FileProperties(path, fileEncoding, parsingProperties.TimingMode);

            Logger.Info("[SubtitleFactory] Opened {0} with encoding {1}", path, fileEncoding);
            return(subtitles);
        }
コード例 #11
0
ファイル: SrtSubtitle.cs プロジェクト: yangwen27/moonlit
 /// <summary>
 /// Builds the specified filename.
 /// </summary>
 /// <param name="filename">The filename.</param>
 /// <returns></returns>
 public SubtitleCollection Build(string filename)
 {
     using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read)) {
         StreamReader reader = new StreamReader(fs,  Encoding.Default, true);
         SubtitleCollection subs = new SubtitleCollection();
         SrtSubtitleItem current = new SrtSubtitleItem();
         do {
             string text = reader.ReadLine();
             current.Load(text);
             if (current.Complected) {
                 subs.Add(current);
                 current = new SrtSubtitleItem();
             }
         } while (!reader.EndOfStream);
         if (!current.Empty) {
             subs.Add(current);
         }
         return subs;
     }
 }
コード例 #12
0
        internal string Build(SubtitleCollection collection, SubtitleProperties subtitleProperties, FileProperties fileProperties)
        {
            this.subtitleProperties = subtitleProperties;
            StringBuilder output = new StringBuilder();

            if (format.HasHeaders)
            {
                output.Append(format.HeadersToString(subtitleProperties, fileProperties));
            }

            if (format.HasBodyBegin)
            {
                output.Append(format.BodyBeginOut);
            }

            string         subtitleExpression = GetSubtitleExpression(format, subtitleProperties, fileProperties);
            Regex          fieldExpression    = new Regex(@"<<(?<Field>\w+)(,(?<Width>\d+))?>>");
            MatchEvaluator matchEvaluator     = new MatchEvaluator(this.FieldEvaluator);

            foreach (Subtitle currentSubtitle in collection)
            {
                subtitle = currentSubtitle;
                string outputSubtitle = fieldExpression.Replace(subtitleExpression, matchEvaluator);
                output.Append(outputSubtitle);
                output.Append("\n");
                subtitleNumber++;
                previousSubtitle = subtitle;
            }

            if (format.HasBodyEnd)
            {
                output.Append(format.BodyEndOut);
            }

            subtitle         = null;
            previousSubtitle = null;
            subtitleNumber   = 1;

            ConvertNewlines(output, fileProperties);
            return(output.ToString());
        }
コード例 #13
0
        /* Private members */

        private Subtitles ParsedSubtitles(string path, Encoding fileEncoding, SubtitleFormat format, float inputFrameRate, string text)
        {
            SubtitleCollection collection        = null;
            SubtitleParser     subtitleParser    = new SubtitleParser(includeIncompleteSubtitles);
            ParsingProperties  parsingProperties = subtitleParser.Parse(text, format, inputFrameRate, out collection, out incompleteSubtitles);

            SubtitleProperties subtitleProperties = new SubtitleProperties(parsingProperties);

            collection.SetPropertiesForAll(subtitleProperties);

            Subtitles subtitles = new Subtitles(collection, subtitleProperties);

            CompleteTimingsAfterParsing(subtitles, parsingProperties);

            fileProperties = new FileProperties(path, fileEncoding, format.Type, parsingProperties.TimingMode);

            Logger.Info("[SubtitleFactory] Opened \"{0}\" with encoding \"{1}\", format \"{2}\", timing mode \"{3}\" and frame rate \"{4}\" (input frame rate was \"{5}\")",
                        path, fileEncoding, format.Name, parsingProperties.TimingMode, subtitleProperties.CurrentFrameRate, inputFrameRate);

            return(subtitles);
        }
コード例 #14
0
        private int ReadSubtitles(string text, int bodyIndex, int textLength, Regex subtitleRegex, SubtitleFormat format,
                                  ParsingProperties properties, SubtitleCollection collection, IncompleteSubtitleCollection incompleteSubtitles)
        {
            Subtitle previousSubtitle = null;

            /* Read the subtitles. BodyIndex points to the start of the subtitles, skipping its possible beginning text*/
            while (bodyIndex < textLength)
            {
                Match match = subtitleRegex.Match(text, bodyIndex);
                if (match.Success)
                {
                    Subtitle subtitle = ParseSubtitle(match, format, properties, previousSubtitle);
                    collection.Add(subtitle);
                    AddIncompleteSubtitleIfExists(text, match, bodyIndex, collection.Count, incompleteSubtitles);
                    bodyIndex        = match.Index + match.Length;
                    previousSubtitle = subtitle;
                }
                else
                {
                    break;
                }
            }
            return(bodyIndex);
        }
コード例 #15
0
        private void ParseSubtitles(StreamReader reader, SubtitleCollection subtitleCollection)
        {
            var subtitleLines = new List<string>();
            var subtitles = 0;
            Subtitle previousSubtitle = null;
            var startTime = new TimeSpan();
            var readNextLine = true;
            var line = string.Empty;
            while (reader.Peek() >= 0)
            {
                if (readNextLine) line = reader.ReadLine();
                switch (_state)
                {
                    case State.EndHeader:
                        if (!string.IsNullOrEmpty(line))
                        {
                            if (line.Length > 0 && line[0].Equals('}'))
                            {
                                _state = State.BeginSubtitle;
                                line = line.Substring(1, line.Length - 1);
                                readNextLine = false;
                                break;
                            }
                        }
                        readNextLine = true;
                        break;
                    case State.BeginSubtitle:
                        if (!string.IsNullOrEmpty(line))
                        {
                            if (line.Length > 0 && line[0].Equals('{'))
                            {
                                _state = State.SubtitleStartTime;
                                line = line.Substring(1, line.Length - 1);
                                readNextLine = false;
                                break;
                            }
                        }
                        readNextLine = true;
                        break;
                    case State.SubtitleStartTime:
                        readNextLine = ParseSubtitleStartTime(subtitleLines, ref line, ref startTime);
                        break;
                    case State.Subtitle:
                        if (!string.IsNullOrEmpty(line))
                        {
                            if (line.Length > 0)
                            {
                                if (line[0].Equals('}'))
                                {
                                    _state = State.BeginSubtitle;
                                    line = line.Substring(1, line.Length - 1);
                                    readNextLine = false;
                                    if (previousSubtitle != null)
                                    {
                                        subtitleCollection.Add(new Subtitle(previousSubtitle.Number, previousSubtitle.Offset, startTime - previousSubtitle.Offset, previousSubtitle.Text));
                                        previousSubtitle = null;
                                    }
                                    if (subtitleLines.Count > 0)
                                    {
                                        subtitles++;
                                        previousSubtitle = new Subtitle(subtitles, startTime, new TimeSpan(), subtitleLines.ToArray());
                                    }
                                    break;
                                }
                                subtitleLines.Add(line);
                            }
                        }
                        readNextLine = true;
                        break;

                }
            }
            return;
        }
コード例 #16
0
ファイル: Video.cs プロジェクト: famalberts/SubTitleChecker
 public Video(Author author, Medium medium, SubtitleCollection subtitles)
 {
     Medium = medium;
     Author = author;
     Subtitles = subtitles;
 }