示例#1
0
        // Public Methods (1) 

        public static void DeleteWholeRow(SubtitleItems data, SubtitleItem toDelete, string fileNameToSave)
        {
            if (data == null || toDelete == null || string.IsNullOrWhiteSpace(fileNameToSave))
            {
                LogWindow.AddMessage(LogType.Alert, "Please select a line to delete it.");
                return;
            }

            var number = toDelete.Number;

            if (data.Remove(toDelete))
            {
                //fix numbers
                for (var i = 0; i < data.Count; i++)
                {
                    data[i].Number = i + 1;
                }

                //backup original file
                var backupFile = string.Format("{0}.original.bak", fileNameToSave);
                File.Copy(fileNameToSave, backupFile, overwrite: true);

                //write data
                File.WriteAllText(fileNameToSave, ParseSrt.SubitemsToString(data).ApplyCorrectYeKe(), Encoding.UTF8);

                LogWindow.AddMessage(LogType.Info, string.Format("Line {0} has been deleted.", number));
                LogWindow.AddMessage(LogType.Info, string.Format("Backup file: {0}", backupFile));
            }
            else
            {
                LogWindow.AddMessage(LogType.Alert, string.Format("Couldn't delete line {0}", number));
            }
        }
示例#2
0
        //public List<SubtitleItem> items = new List<SubtitleItem>();

        //public SortedSet<string> words = new SortedSet<string>();

        protected bool AddWords(SubtitleItem item)
        {
            if (item == null || item.Lines.Count == 0)
            {
                return(false);
            }

            bool add = false;

            foreach (string line in item.Lines)
            {
                string[] words;

                if (TryParseWords(line, out words) && words.Length > 0)
                {
                    add = true;

                    foreach (string word in words)
                    {
                        item.Words.Add(word);
                    }
                }
            }

            return(add);
        }
        // Private Methods (43)

        private void addSubtitleToFile(SubtitleItem subtitleItem, string mediaPath)
        {
            if (string.IsNullOrWhiteSpace(subtitleItem.Dialog))
            {
                return;
            }

            var subtitleFilePath = string.Empty;

            if (string.IsNullOrWhiteSpace(MainWindowGuiData.OpenedFilePath))
            {
                if (!string.IsNullOrWhiteSpace(mediaPath))
                {
                    subtitleFilePath = createEmptySubtitleFile(mediaPath);
                }
                else
                {
                    LogWindow.AddMessage(LogType.Error, "Please open an empty subtitle file first.");
                    return;
                }
            }

            subtitleItemsDataInternal = ParseSrt.AddSubtitleItemToList(subtitleItemsDataInternal, subtitleItem);
            setFlowDir(subtitleItem.Dialog.ContainsFarsi());
            saveToFile(subtitleFilePath);
            _lastStartTs = subtitleItem.StartTs;
            doScrollToIndex(subtitleItemsDataInternal.Count - 1);
            if (!string.IsNullOrEmpty(subtitleFilePath))
            {
                MainWindowGuiData.OpenedFilePath = subtitleFilePath;
            }
            App.Messenger.NotifyColleagues("doClearSubtitle");
        }
        /// <summary>
        /// Parses one line of the .sub file
        ///
        /// ex:
        /// {0}{180}PIRATES OF THE CARIBBEAN|English subtitlez by tHe.b0dY
        /// </summary>
        /// <param name="line">The .sub file line</param>
        /// <param name="frameRate">The frame rate with which the .sub file was created</param>
        /// <returns>The corresponding SubtitleItem</returns>
        private SubtitleItem ParseLine(string line, float frameRate)
        {
            var match = Regex.Match(line, LineRegex);

            if (match.Success && match.Groups.Count > 2)
            {
                var startFrame    = match.Groups[1].Value;
                var start         = (int)(1000 * double.Parse(startFrame) / frameRate);
                var endTime       = match.Groups[2].Value;
                var end           = (int)(1000 * double.Parse(endTime) / frameRate);
                var text          = match.Groups[match.Groups.Count - 1].Value;
                var lines         = text.Split(_lineSeparators);
                var nonEmptyLines = lines.Where(l => !string.IsNullOrEmpty(l)).ToList();
                var item          = new SubtitleItem
                {
                    Lines     = nonEmptyLines,
                    StartTime = start,
                    EndTime   = end
                };

                return(item);
            }
            else
            {
                var message = string.Format("The subtitle file line {0} is " +
                                            "not in the micro dvd format. We stop the process.", line);
                throw new InvalidDataException(message);
            }
        }
示例#5
0
        public string GetTimeStringFor(SubtitleItem item)
        {
            var startTimeStr = (item.StartTime / 1000.0).ToString("#.#s");
            var endTimeStr   = (item.EndTime / 1000.0).ToString("#.#s");

            return($"{startTimeStr} → {endTimeStr}");
        }
示例#6
0
        // Public Methods (11) 

        public static SubtitleItems AddSubtitleItemToList(SubtitleItems subtitleItemsDataInternal, SubtitleItem subtitleItem)
        {
            var localSubItems = subtitleItemsDataInternal.ToList();

            var newItem = new SubtitleItem
            {
                Dialog  = subtitleItem.Dialog,
                EndTs   = subtitleItem.EndTs,
                StartTs = subtitleItem.StartTs
            };

            localSubItems.Add(newItem);
            localSubItems = localSubItems.OrderBy(x => x.StartTs).ToList();

            var i          = 1;
            var finalItems = new SubtitleItems();

            foreach (var item in localSubItems)
            {
                item.Number = i++;
                finalItems.Add(item);
            }

            return(finalItems);
        }
        public static string Header(this SubtitleItem s)
        {
            var startTime = new TimeSpan(0, 0, 0, 0, s.StartTime);
            var endTime   = new TimeSpan(0, 0, 0, 0, s.EndTime);

            return
                ($"{startTime.ToString(TimeFormat, CultureInfo.InvariantCulture)} --> {endTime.ToString(TimeFormat, CultureInfo.InvariantCulture)}");
        }
示例#8
0
        private string ConvertItem(SubtitleItem item)
        {
            var result = string.IsNullOrEmpty(item.Text)
                ? "&nbsp;"
                : Regex.Replace(item.Text, "(\r\n|\r|\n)", "<br>");

            return($"<SYNC Start={item.StartTime}><P>{result}");
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public static MySubtitleItem CopyToMySubtitleItem(this SubtitleItem item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            return(new MySubtitleItem(s: item.StartTime, e: item.EndTime, l: item.Lines.ToList()));
        }
示例#10
0
        public List <SubtitleItem> ParseStream(Stream xmlStream, Encoding encoding)
        {
            // rewind the stream
            xmlStream.Position = 0;
            var items = new List <SubtitleItem>();

            // parse xml stream
            var xmlDoc = new XmlDocument();

            xmlDoc.Load(xmlStream);

            if (xmlDoc.DocumentElement != null)
            {
                var nodeList = xmlDoc.DocumentElement.SelectNodes("//text");

                if (nodeList != null)
                {
                    for (var i = 0; i < nodeList.Count; i++)
                    {
                        var node = nodeList[i];
                        try
                        {
                            var   startString = node.Attributes["start"].Value;
                            float start       = float.Parse(startString, CultureInfo.InvariantCulture);
                            var   durString   = node.Attributes["dur"].Value;
                            float duration    = float.Parse(durString, CultureInfo.InvariantCulture);
                            var   text        = node.InnerText;

                            SubtitleItem item = new SubtitleItem()
                            {
                                StartTime = (int)(start * 1000),
                                EndTime   = (int)((start + duration) * 1000),
                                Lines     = new List <string>()
                                {
                                    text
                                }
                            };

                            items.Add(item);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Exception raised when parsing xml node {0}: {1}", node, ex);
                        }
                    }
                }
            }

            if (items.Any())
            {
                return(items);
            }
            else
            {
                throw new ArgumentException("Stream is not in a valid Youtube XML format");
            }
        }
示例#11
0
 public static SubtitleItem Clone(this SubtitleItem s1)
 {
     return(new SubtitleItem()
     {
         StartTime = s1.StartTime,
         EndTime = s1.EndTime,
         Lines = new System.Collections.Generic.List <string>(s1.Lines),
     });
 }
示例#12
0
        public void WriteWav(SubtitleItem info, string episode)
        {
            string output = WavName(info, EpisodeCode(episode));

            Process.Start("ffmpeg", $"-hide_banner -i \"{Path.GetFullPath(episode)}\" -ss {info.StartTime} -to {info.EndTime} -f wav {Path.Combine(WavPath, output)} ");

            UpdateCSV(info, output, episode);
            AddToSkip(info, episode);
        }
示例#13
0
        /// <summary>
        /// Đếm thời gian để thay đổi sub
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (subItems == null)
            {
                return;
            }
            int cp = Convert.ToInt32(WMPMain.Ctlcontrols.currentPosition * 1000);

            if (cp < subItems[0].StartTime ||
                cp > subItems[subItems.Count - 1].EndTime)
            {
                return;
            }
            if (currentSubIndex + 1 < subItems.Count)
            {
                if (cp >= subItems[currentSubIndex].StartTime &&
                    cp < subItems[currentSubIndex + 1].StartTime)
                {
                    return;
                }
                if (cp >= subItems[currentSubIndex + 1].StartTime &&
                    cp <= subItems[currentSubIndex + 1].EndTime)
                {
                    currentSubIndex++;
                    boldCurrentSub();
                    return;
                }
            }
            //Tìm sub nếu như tua một đoạn
            //Debug.WriteLine("Find sub = " + WMPMain.Ctlcontrols.currentPosition + " " + subItems[currentSubIndex].StartTime / 1000.0 + " " + currentSubIndex);
            SubtitleItem searchItem = new SubtitleItem();

            searchItem.StartTime = cp;
            int index = ~subItems.BinarySearch(searchItem, new StartTimeComparer());//index = phần tử liền sau, index có thể = count

            index = Math.Abs(index);
            //Debug.WriteLine("Find sub = " + index);
            if (index > 0)
            {
                index--;//Do index = phần tử liền sau
                if (index + 1 < subItems.Count)
                {
                    if (cp >= subItems[index].StartTime &&
                        cp < subItems[index + 1].StartTime)
                    {
                        currentSubIndex = index;
                        boldCurrentSub();
                    }
                }
                else
                {
                    currentSubIndex = subItems.Count - 1;
                    boldCurrentSub();
                }
            }
        }
        private void Dt_Tick(object sender, object e)
        {
            try
            {
                if (SubtitleList != null && SubtitleList.Any())
                {
                    var v = (from item in SubtitleList
                             where item != null &&
                             item.StartTime + seekDouble <= MyPlayer.MediaPlayer.PlaybackSession.Position.TotalMilliseconds &&
                             item.EndTime + seekDouble >= MyPlayer.MediaPlayer.PlaybackSession.Position.TotalMilliseconds
                             orderby item descending
                             select item).FirstOrDefault();
                    CurrentSubtitleItem = v;
                    if (v != null)
                    {
                        richtextblock.Blocks.Clear();

                        Paragraph myParagraph   = new Paragraph();
                        int       nextParagraph = 1;
                        string    paragraph     = "";
                        foreach (string item in v.Lines)
                        {
                            paragraph += item.Trim().ToString() + "\r\n";
                            if (GetRun(item) != null)
                            {
                                myParagraph.Inlines.Add(GetRun(item.Trim()));
                                try
                                {
                                    if (v.Lines[nextParagraph] != null)
                                    {
                                        myParagraph.Inlines.Add(new LineBreak());
                                    }
                                }
                                catch (Exception ex) { Debug.WriteLine("nextParagraph ex: " + ex.Message); }
                            }
                            nextParagraph++;
                        }
                        //Run run = new Run();
                        //run.Text = paragraph.Trim();
                        //myParagraph.Inlines.Add(run);
                        richtextblock.Blocks.Add(myParagraph);
                        border.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        border.Visibility = Visibility.Collapsed;
                        richtextblock.Blocks.Clear();
                    }
                }
                else
                {
                    richtextblock.Blocks.Clear();
                }
            }
            catch (Exception ex) { Debug.WriteLine("mediaPlayer_PositionChanged ex: " + ex.Message); }
        }
示例#15
0
        public static SubtitleRow ToSubtitleRow(this SubtitleItem item)
        {
            SubtitleRow result = new SubtitleRow();

            result.StartTime = new TimeSpan(0, 0, 0, 0, item.StartTime);
            result.EndTime   = new TimeSpan(0, 0, 0, 0, item.EndTime);
            result.Value     = String.Join(" ", item.Lines);

            return(result);
        }
        public static void FixMinReadTime(this SubtitleItem subtitleItem)
        {
            var totalSeconds = (subtitleItem.EndTs - subtitleItem.StartTs).TotalSeconds;
            var readTime     = subtitleItem.Dialog.MinReadTime();
            var minReadTime  = readTime.TotalSeconds;

            if (totalSeconds < minReadTime)
            {
                subtitleItem.EndTs = subtitleItem.StartTs.Add(readTime);
            }
        }
示例#17
0
 public static bool Overlaps(this SubtitleItem s1, SubtitleItem s2)
 {
     if (s1.StartTime <= s2.StartTime)
     {
         return(s1.EndTime > s2.StartTime);
     }
     else
     {
         return(s2.Overlaps(s1));
     }
 }
示例#18
0
        public List <SubtitleItem> ParseStream(Stream xmlStream, Encoding encoding)
        {
            // rewind the stream
            xmlStream.Position = 0;
            var items = new List <SubtitleItem>();

            // parse xml stream
            var xElement = XElement.Load(xmlStream);
            var tt       = xElement.GetNamespaceOfPrefix("tt") ?? xElement.GetDefaultNamespace();

            var nodeList = xElement.Descendants(tt + "p").ToList();

            foreach (var node in nodeList)
            {
                try
                {
                    var reader = node.CreateReader();
                    reader.MoveToContent();
                    var beginString = node.Attribute("begin").Value.Replace("t", "");
                    var startTicks  = ParseTimecode(beginString);
                    var endString   = node.Attribute("end").Value.Replace("t", "");
                    var endTicks    = ParseTimecode(endString);
                    var text        = reader.ReadInnerXml()
                                      .Replace("<tt:", "<")
                                      .Replace("</tt:", "</")
                                      .Replace(string.Format(@" xmlns:tt=""{0}""", tt), "")
                                      .Replace(string.Format(@" xmlns=""{0}""", tt), "");

                    SubtitleItem item = new SubtitleItem()
                    {
                        StartTime = (int)(startTicks),
                        EndTime   = (int)(endTicks),
                        Lines     = new List <string>()
                        {
                            text
                        }
                    };

                    AddWords(item);

                    items.Add(item);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception raised when parsing xml node {0}: {1}", node, ex);
                }
            }

            if (items.Any())
            {
                return(items);
            }
            throw new ArgumentException("Stream is not in a valid TTML format, or represents empty subtitles");
        }
示例#19
0
        public bool CanSkip(SubtitleItem info, string episode)
        {
            string epCode    = EpisodeCode(episode),
                   startTime = info.StartTime.ToString();

            //If that episode and timecode has been tested
            return(AlreadyTested.AsParallel().Any(s =>
            {
                return s[0] == epCode && s[1] == startTime;
            }));
        }
示例#20
0
        private void initLocalItems()
        {
            _subtitleItems   = new SubtitleItems();
            PreviewModelData = new PreviewModel();
            SubtitleItemData = new SubtitleItem();

            PreviewModelData.PlayImage        = "play";
            PreviewModelData.DragCompleted    = true;
            PreviewModelData.PropertyChanged += previewModelDataPropertyChanged;
            SubtitleItemData.PropertyChanged += subtitleItemDataPropertyChanged;
            SubtitleItemData.CaretIndex       = 1;
        }
        private void Dt_Tick(object sender, object e)
        {
            try
            {
                if (SubtitleList != null && SubtitleList.Any() && showSubtitle)
                {
                    var v = (from item in SubtitleList
                             where item != null &&
                             item.StartTime + seekDouble <= mediaElement.Position.TotalMilliseconds &&
                             item.EndTime + seekDouble >= mediaElement.Position.TotalMilliseconds
                             orderby item descending
                             select item).FirstOrDefault();
                    CurrentSubtitleItem = v;
                    if (v != null)
                    {
                        customMTC.SubtitleText.Blocks.Clear();

                        Paragraph myParagraph   = new Paragraph();
                        int       nextParagraph = 1;
                        foreach (string item in v.Lines)
                        {
                            if (GetRun(item) != null)
                            {
                                myParagraph.Inlines.Add(GetRun(item.Replace("ي", "ی")));
                                try
                                {
                                    if (v.Lines.Count < nextParagraph && v.Lines[nextParagraph] != null)
                                    {
                                        myParagraph.Inlines.Add(new LineBreak());
                                    }
                                }
                                catch (Exception ex) { HelperUP.Output("nextParagraph ex: " + ex.Message); }
                            }
                            nextParagraph++;
                        }
                        customMTC.SubtitleText.Blocks.Add(myParagraph);
                        customMTC.ShadowBorder.Visibility = customMTC.SubtitleText.Visibility = Windows.UI.Xaml.Visibility.Visible;
                    }
                    else
                    {
                        customMTC.ShadowBorder.Visibility = customMTC.SubtitleText.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
                        customMTC.SubtitleText.Blocks.Clear();
                    }
                }
                else
                {
                    customMTC.SubtitleText.Blocks.Clear();
                }
            }
            catch (Exception ex) { HelperUP.Output("mediaPlayer_PositionChanged ex: " + ex.Message); }
        }
        void SeekToNextSubtitle(bool next = true)
        {
            if (PlayerPage.Current == null || PlayerPage.Current != null && PlayerPage.Current.SubtitleList == null)
            {
                return;
            }
            if (PlayerPage.Current.CurrentSubtitleItem == null)
            {
                return;
            }
            var sub   = PlayerPage.Current.CurrentSubtitleItem;
            var index = PlayerPage.Current.SubtitleList.FindIndex(item =>
                                                                  item.StartTime == sub.StartTime && item.EndTime == sub.EndTime);

            if (next)
            {
                if (index > 0)
                {
                    if (index + 1 <= PlayerPage.Current.SubtitleList.Count)
                    {
                        try
                        {
                            SubtitleItem itemSub = PlayerPage.Current.SubtitleList[index + 1];
                            PlayerPage.Current.MediaElement.Pause();
                            PlayerPage.Current.MediaElement.Position = TimeSpan.FromMilliseconds(itemSub.StartTime);
                            PlayerPage.Current.MediaElement.Play();
                        }
                        catch { }
                    }
                }
            }
            else
            {
                if (index > 0)
                {
                    if (index - 1 <= PlayerPage.Current.SubtitleList.Count)
                    {
                        try
                        {
                            SubtitleItem itemSub = PlayerPage.Current.SubtitleList[index - 1];
                            PlayerPage.Current.MediaElement.Pause();
                            PlayerPage.Current.MediaElement.Position = TimeSpan.FromMilliseconds(itemSub.StartTime);
                            PlayerPage.Current.MediaElement.Play();
                        }
                        catch { }
                    }
                }
            }
        }
示例#23
0
        public static List <SubtitleItem> RemoveDuplicateItems(List <SubtitleItem> data)
        {
            var filteredItems = new List <SubtitleItem>();
            var previousItem  = new SubtitleItem();

            foreach (var d in data.Where(d =>
                                         previousItem.StartTime != d.StartTime || previousItem.EndTime != d.EndTime ||
                                         previousItem.Text != d.Text))
            {
                previousItem = d;
                filteredItems.Add(d);
            }

            return(filteredItems);
        }
示例#24
0
        public string GetStringFor(SubtitleItem item)
        {
            var builder = new StringBuilder();

            if (item != null && item.Lines != null && item.Lines.Count > 0)
            {
                foreach (var line in item.Lines)
                {
                    builder.Append(line);
                    builder.Append(" ");
                }
                // remove the last " "
                builder.Remove(builder.Length - 1, 1);
            }
            return(builder.ToString());
        }
        private SubtitleItem ParseLine(string line, float frameRate)
        {
            var match = Regex.Match(line, LineRegex);

            if (match.Success && match.Groups.Count > 2)
            {
                var startFrame = match.Groups[1].Value;
                var start      = (int)(1000 * double.Parse(startFrame) / frameRate);
                var endTime    = match.Groups[2].Value;
                var end        = (int)(1000 * double.Parse(endTime) / frameRate);
                var text       = match.Groups[match.Groups.Count - 1].Value;
                var lines      = text.Split(_lineSeparators);
                //... آنچه گذشت|{y:i}RamtinJokar|{y:i}SalAM
                var nonEmptyLines = lines.Where(l => !string.IsNullOrEmpty(l)).ToList();
                if (nonEmptyLines.Count > 0)
                {
                    for (int i = 0; i < nonEmptyLines.Count; i++)
                    {
                        nonEmptyLines[i] = nonEmptyLines[i].Replace("|", Environment.NewLine);
                        if (nonEmptyLines[i].Contains("{y:i}"))
                        {
                            nonEmptyLines[i] = nonEmptyLines[i].Replace("{y:i}", "");
                            nonEmptyLines[i] = "<i>" + nonEmptyLines[i] + "</i>";
                        }
                        if (nonEmptyLines[i].Contains("{Y:b}"))
                        {
                            nonEmptyLines[i] = nonEmptyLines[i].Replace("{Y:b}", "");
                            nonEmptyLines[i] = "<b>" + nonEmptyLines[i] + "</b>";
                        }
                    }
                }
                var item = new SubtitleItem
                {
                    Lines     = nonEmptyLines,
                    StartTime = start,
                    EndTime   = end
                };

                return(item);
            }
            else
            {
                var message = string.Format("The subtitle file line {0} is " +
                                            "not in the micro dvd format. We stop the process.", line);
                throw new InvalidDataException(message);
            }
        }
示例#26
0
        int compareFunc(double timeSeconds, SubtitleItem item)
        {
            int timeMilliSeconds = (int)(timeSeconds * 1000);

            if (timeMilliSeconds < item.StartTime)
            {
                return(-1);
            }
            else if (timeMilliSeconds > item.EndTime)
            {
                return(1);
            }
            else
            {
                return(0);
            }
        }
示例#27
0
        private static void PlayAudio(string file, SubtitleItem info)
        {
            var start = TimeSpan.FromMilliseconds(info.StartTime).ToString("c");
            var end   = TimeSpan.FromMilliseconds(info.EndTime).ToString("c");

            Console.WriteLine(info.ToString());

            var startInfo = new ProcessStartInfo("ffmpeg", $"-hide_banner -loglevel panic -i \"{Path.GetFullPath(file)}\" " + $"-ss {start} " +
                                                 $"-to {end} " +
                                                 "-f pulse " +
                                                 "default"
                                                 );

            startInfo.WindowStyle            = ProcessWindowStyle.Hidden;
            startInfo.CreateNoWindow         = true;
            startInfo.RedirectStandardOutput = false;

            Process.Start(startInfo);
        }
示例#28
0
        public SubtitleItem getSubtitle(double timeSeconds)
        {
            rwLock.EnterReadLock();
            try
            {
                SubtitleItem result = null;

                if (items.Count == 0)
                {
                    return(result);
                }

                int mid  = 0;
                int low  = 0;
                int high = items.Count - 1;

                while (low <= high)
                {
                    mid = (high + low) / 2;

                    int val = compareFunc(timeSeconds, items[mid]);

                    if (val < 0)
                    {
                        high = mid - 1;
                    }
                    else if (val > 0)
                    {
                        low = mid + 1;
                    }
                    else
                    {
                        return(items[mid]);
                    }
                }

                return(result);
            }
            finally
            {
                rwLock.ExitReadLock();
            }
        }
示例#29
0
        private void SetBestSubtitles()
        {
            if (!Monitor.TryEnter(_subtitleSearchLocker, 0))
            {
                // no point in doing this if we are already downloading subtitles, which will do the same thing effectively
                return;
            }

            SubtitleItem bestSubMatch = null;

            try
            {
                if (!_subtitleIsDownloading && Source != null &&
                    SubtitleStreams.Any(s => s.Type == SubtitleItem.SubtitleType.File && File.Exists(s.Path)))
                {
                    // if nothing is downloading and we have file subs in the folder
                    string lcode = Main.SubtitleLanguages.Count > 0 ? Main.SubtitleLanguages[0].Id : "";

                    for (int i = 0; i < Main.SubtitleLanguages.Count; i++)
                    {
                        // TODO this should care also for EMBEDDED subs
                        bestSubMatch = SubtitleStreams.Where(s => s.Type == SubtitleItem.SubtitleType.File && File.Exists(s.Path)).OrderBy(f => Path.GetFileNameWithoutExtension(f.Path).ToLowerInvariant().StartsWith(Path.GetFileNameWithoutExtension(Source.LocalPath.ToLowerInvariant())) && (lcode == "" || Path.GetFileNameWithoutExtension(f.Path).EndsWith(lcode)) ? 0 : 1).FirstOrDefault();
                        if (bestSubMatch != null)
                        {
                            break;
                        }
                    }

                    ServiceLocator.GetService <IMainView>().DelayedInvoke(() => { SelectedSubtitle = bestSubMatch; }, 200);
                    return;
                }
            }
            finally
            {
                Monitor.Exit(_subtitleSearchLocker);
            }
            if (bestSubMatch == null)
            {
                DownloadSubtitleForUriAndQueryIMDB(Source);
            }
        }
示例#30
0
        private void AddSubtitle(string path)
        {
            if (!File.Exists(path))
            {
                return;
            }

            var subtitle = new SubtitleItem();
            subtitle.Name = Path.GetFileName(path);
            subtitle.Type = Path.GetExtension(path).ToUpperInvariant();
            subtitle.Path = path;

            this._subtitles.Add(subtitle);
        }
示例#31
0
        // Methods -------------------------------------------------------------------------

        public List <SubtitleItem> ParseStream(Stream srtStream, Encoding encoding)
        {
            // test if stream if readable and seekable (just a check, should be good)
            if (!srtStream.CanRead || !srtStream.CanSeek)
            {
                var message = string.Format("Stream must be seekable and readable in a subtitles parser. " +
                                            "Operation interrupted; isSeekable: {0} - isReadable: {1}",
                                            srtStream.CanSeek, srtStream.CanSeek);
                throw new ArgumentException(message);
            }

            // seek the beginning of the stream
            srtStream.Position = 0;

            var reader = new StreamReader(srtStream, encoding, true);

            var items       = new List <SubtitleItem>();
            var srtSubParts = GetSrtSubTitleParts(reader).ToList();

            if (srtSubParts.Any())
            {
                foreach (var srtSubPart in srtSubParts)
                {
                    var lines =
                        srtSubPart.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)
                        .Select(s => s.Trim())
                        .Where(l => !string.IsNullOrEmpty(l))
                        .ToList();

                    var item = new SubtitleItem();
                    foreach (var line in lines)
                    {
                        if (item.StartTime == 0 && item.EndTime == 0)
                        {
                            // we look for the timecodes first
                            int startTc;
                            int endTc;
                            var success = TryParseTimecodeLine(line, out startTc, out endTc);
                            if (success)
                            {
                                item.StartTime = startTc;
                                item.EndTime   = endTc;
                            }
                        }
                        else
                        {
                            // we found the timecode, now we get the text
                            item.Lines.Add(line);
                        }
                    }

                    if ((item.StartTime != 0 || item.EndTime != 0) && item.Lines.Any())
                    {
                        // parsing succeeded
                        items.Add(item);
                    }
                }

                if (items.Any())
                {
                    return(items);
                }
                else
                {
                    throw new ArgumentException("Stream is not in a valid Srt format");
                }
            }
            else
            {
                throw new FormatException("Parsing as srt returned no srt part.");
            }
        }
示例#32
0
        // Methods ------------------------------------------------------------------

        public List<SubtitleItem> ParseStream(Stream ssaStream, Encoding encoding)
        {
            // test if stream if readable and seekable (just a check, should be good)
            if (!ssaStream.CanRead || !ssaStream.CanSeek)
            {
                var message = string.Format("Stream must be seekable and readable in a subtitles parser. " +
                                   "Operation interrupted; isSeekable: {0} - isReadable: {1}",
                                   ssaStream.CanSeek, ssaStream.CanSeek);
                throw new ArgumentException(message);
            }

            // seek the beginning of the stream
            ssaStream.Position = 0;

            var reader = new StreamReader(ssaStream, encoding, true);

            var line = reader.ReadLine();
            var lineNumber = 1;
            // read the line until the [Events] section
            while (line != null && line != EventLine)
            {
                line = reader.ReadLine();
                lineNumber++;
            }

            if (line != null)
            {
                // we are at the event section
                var headerLine = reader.ReadLine();
                if (!string.IsNullOrEmpty(headerLine))
                {
                    var columnHeaders = headerLine.Split(Separator).Select(head => head.Trim()).ToList();

                    var startIndexColumn = columnHeaders.IndexOf(StartColumn);
                    var endIndexColumn = columnHeaders.IndexOf(EndColumn);
                    var textIndexColumn = columnHeaders.IndexOf(TextColumn);

                    if (startIndexColumn > 0 && endIndexColumn > 0 && textIndexColumn > 0)
                    {
                        var items = new List<SubtitleItem>();

                        line = reader.ReadLine();
                        while (line != null)
                        {
                            if(!string.IsNullOrEmpty(line))
                            {
                                var columns = line.Split(Separator);
                                var startText = columns[startIndexColumn];
                                var endText = columns[endIndexColumn];


                                var textLine = string.Join(",", columns.Skip(textIndexColumn));

                                var start = ParseSsaTimecode(startText);
                                var end = ParseSsaTimecode(endText);

                                // TODO: split text line?
                                if (start > 0 && end > 0 && !string.IsNullOrEmpty(textLine))
                                {
                                    var item = new SubtitleItem()
                                                            {
                                                                StartTime = start,
                                                                EndTime = end,
                                                                Lines = new List<string>() { textLine }
                                                            };
                                    items.Add(item);
                                }
                            }
                            line = reader.ReadLine();
                        }

                        if (items.Any())
                        {
                            return items;
                        }
                        else
                        {
                            throw new ArgumentException("Stream is not in a valid Ssa format");
                        }
                    }
                    else
                    {
                        var message = string.Format("Couldn't find all the necessary columns " +
                                                    "headers ({0}, {1}, {2}) in header line {3}",
                                                    StartColumn, EndColumn, TextColumn, headerLine);
                        throw new ArgumentException(message);
                    }
                }
                else
                {
                    var message = string.Format("The header line after the line '{0}' was null -> " +
                                                "no need to continue parsing", line);
                    throw new ArgumentException(message);
                }
            }
            else
            {
                var message = string.Format("We reached line '{0}' with line number #{1} without finding to " +
                                            "Event section ({2})", line, lineNumber, EventLine);
                throw new ArgumentException(message);
            }
        }
示例#33
0
        /// <summary>
        /// Parses one line of the .sub file
        /// 
        /// ex:
        /// {0}{180}PIRATES OF THE CARIBBEAN|English subtitlez by tHe.b0dY
        /// </summary>
        /// <param name="line">The .sub file line</param>
        /// <param name="frameRate">The frame rate with which the .sub file was created</param>
        /// <returns>The corresponding SubtitleItem</returns>
        private SubtitleItem ParseLine(string line, float frameRate)
        {
            var match = Regex.Match(line, LineRegex);
            if (match.Success && match.Groups.Count > 2)
            {
                var startFrame = match.Groups[1].Value;
                var start = (int)(1000 * double.Parse(startFrame) / frameRate);
                var endTime = match.Groups[2].Value;
                var end = (int)(1000 * double.Parse(endTime) / frameRate);
                var text = match.Groups[match.Groups.Count - 1].Value;
                var lines = text.Split(_lineSeparators);
                var nonEmptyLines = lines.Where(l => !string.IsNullOrEmpty(l)).ToList();
                var item = new SubtitleItem
                    {
                        Lines = nonEmptyLines,
                        StartTime = start,
                        EndTime = end
                    };

                return item;
            }
            else
            {
                var message = string.Format("The subtitle file line {0} is " +
                                            "not in the micro dvd format. We stop the process.", line);
                throw new InvalidDataException(message);
            }
        }
示例#34
0
        // Methods -------------------------------------------------------------------------

        public List<SubtitleItem> ParseStream(Stream vttStream, Encoding encoding)
        {
            // test if stream if readable and seekable (just a check, should be good)
            if (!vttStream.CanRead || !vttStream.CanSeek)
            {
                var message = string.Format("Stream must be seekable and readable in a subtitles parser. " +
                                   "Operation interrupted; isSeekable: {0} - isReadable: {1}",
                                   vttStream.CanSeek, vttStream.CanSeek);
                throw new ArgumentException(message);
            }

            // seek the beginning of the stream
            vttStream.Position = 0;

            var reader = new StreamReader(vttStream, encoding, true);

            var items = new List<SubtitleItem>();
            var vttSubParts = GetVttSubTitleParts(reader).ToList();
            if (vttSubParts.Any())
            {
                foreach (var vttSubPart in vttSubParts)
                {
                    var lines =
                        vttSubPart.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)
                                  .Select(s => s.Trim())
                                  .Where(l => !string.IsNullOrEmpty(l))
                                  .ToList();

                    var item = new SubtitleItem();
                    foreach (var line in lines)
                    {
                        if (item.StartTime == 0 && item.EndTime == 0)
                        {
                            // we look for the timecodes first
                            int startTc;
                            int endTc;
                            var success = TryParseTimecodeLine(line, out startTc, out endTc);
                            if (success)
                            {
                                item.StartTime = startTc;
                                item.EndTime = endTc;
                            }
                        }
                        else
                        {
                            // we found the timecode, now we get the text
                            item.Lines.Add(line);
                        }
                    }

                    if ((item.StartTime != 0 || item.EndTime != 0) && item.Lines.Any())
                    {
                        // parsing succeeded
                        items.Add(item);
                    }
                }

                if (items.Any())
                {
                    return items;
                }
                else
                {
                    throw new ArgumentException("Stream is not in a valid VTT format");
                }
            }
            else
            {
                throw new FormatException("Parsing as VTT returned no VTT part.");
            }
        }