/// <summary> /// Read a float setting. /// </summary> public static float getFloat(string key, float def) { string defString = def.ToString(); string valString = ""; float value = 0; valString = getString(key, defString); try { value = (float)UtilsLang.toDouble(valString); } catch { value = def; } return(value); }
/// <summary> /// Parse the subtitle file and return a list of lines. /// </summary> override public List <InfoLine> parse() { List <InfoLine> lineInfos = new List <InfoLine>(); StreamReader subFile = new StreamReader(this.File, this.SubsEncoding); XmlTextReader xmlReader = new XmlTextReader(subFile); xmlReader.XmlResolver = null; // Ignore dtd DateTime startTime = new DateTime(); DateTime endTime = new DateTime(); DateTime curTime = new DateTime(); DateTime turnEndTime = new DateTime(); string dialogText = ""; int syncCount = 0; while (xmlReader.Read()) { if (xmlReader.NodeType == XmlNodeType.Element) { if (xmlReader.Name.ToLower() == "sync") { // Example sync: <Sync time="1.027"/> syncCount++; string timeStr = xmlReader.GetAttribute("time"); try { curTime = new DateTime(); curTime = curTime.AddSeconds(UtilsLang.toDouble(timeStr)); } catch (Exception e1) { throw new Exception(String.Format("Incorrect time format detected: {0}\n\n{1}", timeStr, e1)); } if (syncCount == 1) { startTime = curTime; } else if (syncCount == 2) { endTime = curTime; } else { startTime = endTime; endTime = curTime; } // If this is not the first time and the length isn't blank if ((syncCount > 1) && (dialogText.Length != 0)) { lineInfos.Add(this.createLineInfo(dialogText, startTime, endTime)); dialogText = ""; } } else if (xmlReader.Name.ToLower() == "turn") { // Example turn: <Turn speaker="spk1" startTime="2.263" endTime="25.566"> string timeStr = xmlReader.GetAttribute("endTime"); turnEndTime = new DateTime(); turnEndTime = curTime.AddSeconds(UtilsLang.toDouble(timeStr)); } } else if (xmlReader.NodeType == XmlNodeType.Text) { dialogText += xmlReader.Value; } else if (xmlReader.NodeType == XmlNodeType.EndElement) { // This section handles the final line before the </turn>. // We need to do this because there isn't a Sync tag after the final line. if (xmlReader.Name.ToLower() == "turn") // </Turn> { const double MAX_FINAL_LINE_DURATION = 10.0; startTime = endTime; endTime = turnEndTime; // Calculate the difference between the startTime and turnEndTime and make sure that // it is a reasonable length. We do this because the turn end time isn't necessarily // the end of the line. If it is not a reasonable length, set it to MAX_FINAL_LINE_DURATION. double diffTime = endTime.TimeOfDay.TotalSeconds - startTime.TimeOfDay.TotalSeconds; if (diffTime > MAX_FINAL_LINE_DURATION) { endTime = startTime; endTime = endTime.AddSeconds(MAX_FINAL_LINE_DURATION); } if ((syncCount >= 1) && (dialogText.Length != 0)) { lineInfos.Add(this.createLineInfo(dialogText, startTime, endTime)); dialogText = ""; } // If needed, restore endtime to the turnEndTime if (diffTime >= MAX_FINAL_LINE_DURATION) { endTime = turnEndTime; } } } } subFile.Close(); // Since the dialog lines don't have to be in chronological order, sort by the start time lineInfos.Sort(); return(lineInfos); }