/// <summary> /// /// </summary> /// <param name="sText">Time length formatted as [D]:[H]:[M]:[S.MS], [D]:[H]:[M]:[S]:[F], [H]:[M]:[S];[F], [S.MS], [F], /// numbers in arbitrary order but labeled as 0d0h0m0s0ms0f or where /// items in brackets are not in brackets but are instead numbers, and where [D] (days) and anything /// else to the left of [S] is optional.</param> /// <returns>Seconds, or if fails, returns decimal.MinValue instead.</returns> public static decimal SecondsFromDHMSF(string sText, decimal dFrameRate, uint FrameRate_override) { decimal dReturn=0.0M; bool bGood=false; RReporting.sParticiple="trimming DHMSF timecode string"; try { darrToSecondMultiplier[TimeType_Frame]=1.0M/dFrameRate; darrFromSecondDivisor[TimeType_Frame]=dFrameRate; if (sText==null) sText=""; if (sText.Length>0) { //int iMSTotal=0; //string[] sarrNum=new String[sText.Length]; //string[] sarrType=new String[sText.Length]; //for (int iNow=0; iNow<sText.Length; iNow++) { // sarrNum[iNow]=""; // sarrType[iNow]=""; //} int iFirst=0; int iLast=sText.Length-1; while (RString.IsWhiteSpace(sText[iFirst])) { iFirst++; } while (RString.IsWhiteSpace(sText[iLast])) { iLast--; } if (iFirst>0||(iLast!=(sText.Length-1))) { if (iLast>=iFirst) { sText=RString.SafeSubstringByInclusiveEnder(sText,iFirst,iLast); } else sText=""; } int iNums=0; RReporting.sParticiple="checking DHMSF timecode string"; int iDigits=0; int iLastDecimal=-1; int iLastColon=-1; for (int i=0; i<sText.Length; i++) { if (RString.IsDigit(sText[i])) iDigits++; else if (sText[i]=='.') iLastDecimal=i; else if (sText[i]==':') iLastColon=i; } bool bHasDecimalInLastSegment=iLastDecimal>iLastColon; int TimeType_Now=TimeType_Frame; //since SMTPE timecode is [hh]:[mm]:[ss]:[ff] (vegas is [hh]:[mm]:[ss];[ff]) if (bHasDecimalInLastSegment) { TimeType_Now=TimeType_Second;//to account timecode with decimal seconds e.g. [hh]:[mm]:[ss].[_ms] } int iChar=sText.Length-1; bGood=true; int ParsingWhat=Parsing_Delimiter; int SegmentNow_EndBefore=iChar+1; if (RString.IsDigit(sText[iChar])) ParsingWhat=Parsing_Number; //ok to use iChar since this whole process only happens if sText.Length>0 while (iChar>=-1) { if (ParsingWhat==Parsing_Space) { if (iChar==-1) { //do nothing } else if (!RString.IsWhiteSpace(sText[iChar])) { SegmentNow_EndBefore=iChar+1;//+1 since NOT whitespace if (RString.IsDigit(sText[iChar])||(sText[iChar]=='.')) { ParsingWhat=Parsing_Number; //sarrNum[iNums]+=sText.Substring(iChar,1); } else { ParsingWhat=Parsing_Delimiter; } } } else if (ParsingWhat==Parsing_Delimiter) { if (iChar<0) { RReporting.SourceErr("Warning: unknown text found at start of time string","",sText); } else if (RString.IsDigit(sText[iChar])||(sText[iChar]=='.')||(RString.IsWhiteSpace(sText[iChar]))) { int TimeType_Temp=-1; //if (sText[iChar]=='.') { //HANDLED BELOW (TimeType_Now decremented twice) // TimeType_Temp=TimeType_Second //} //else { if (SegmentNow_EndBefore-(iChar+1) == 1) TimeType_Temp=TimeDelimiterToTimeType(sText[iChar+1]); //+1 since [iChar] is NOT delimiter else TimeType_Temp=TimeDelimiterToTimeType(RString.SafeSubstringByExclusiveEnder(sText,iChar+1,SegmentNow_EndBefore)); //+1 since [iChar] is NOT delimiter //} if (TimeType_Temp<0) {//assume generic delimiter //if (sText[iChar]==":"||sText[iChar]==";") { if (carrTimeType[TimeType_Now]=='.') TimeType_Now--;//skip f if on ms TimeType_Now--; } else TimeType_Now=TimeType_Temp; SegmentNow_EndBefore=iChar+1;//+1 since sText[iChar] is NOT delimiter if (RString.IsWhiteSpace(sText[iChar])) { ParsingWhat=Parsing_Space; } else {//digit or '.' ParsingWhat=Parsing_Number; } //sarrNum[iNums]+=sText.Substring(iChar,1); } } else if (ParsingWhat==Parsing_Number) { if ( iChar<0 || ( !RString.IsDigit(sText[iChar]) && !(sText[iChar]=='.') ) ) { if (IsValidTimeType(TimeType_Now)) { //Each hour is 108000 non-drop frames (30 * 60 * 60) or 107892 drop frames (drop 108 frames). In real time, //each hour is 107892.108 frames. //Each "deci-minute" is 18000 non-drop frames (30 * 60 * 10) or 17982 drop frames (drop 18 frames, or 2 frames //for nine out of every ten minutes). In real time, 10 minutes is 17982.018 frames. //Each "single-minute" is 1800 non-drop frames (30 * 60) or 1798 drop frames (drop 2 frames for every minute, or //0 frames when multiplying by 0). In real time, a minute is 1798.202 frames. //Each second is 30 frames (both timebases), or 29.970 frames real-time. if (TimeType_Now==TimeType_Frame) { } else dReturn+=RConvert.ToDecimal( RString.SafeSubstringByExclusiveEnder(sText,iChar+1,SegmentNow_EndBefore) ) * darrToSecondMultiplier[TimeType_Now]; //+1 since [iChar] is NOT digit } if (!(iChar<0)) { SegmentNow_EndBefore=iChar+1;//+1 since [iChar] is NOT part of number if (RString.IsWhiteSpace(sText[iChar])) { ParsingWhat=Parsing_Space; } else { ParsingWhat=Parsing_Delimiter; } }//if not out of range } //else if (sText[iChar]=='.' && TimeType_Now==TimeType_Millisecond) TimeType_Now=TimeType_Second } else { //ParsingWhat does not have valid opcode bGood=false; RReporting.ShowErr("DHMSF Parsing Corruption"); } iChar--; }//end while iChar>=-1 }//end if sText.Length>0 else { bGood=true; //good since it is ok to be blank dReturn=0.0M; } } catch (Exception e) { bGood=false; RReporting.ShowExn(e); } if (!bGood) dReturn=decimal.MinValue; return dReturn; }//end From(sDHMSF)