public Timestamp[] findTimestamps(byte[] inputByteArray)
        {
            List <Timestamp> timestampList = new List <Timestamp>();

            byte openingBracket = stringToBytes("[")[0];
            byte closingBracket = stringToBytes("]")[0];
            byte colon          = stringToBytes(":")[0];
            byte dot            = stringToBytes(".")[0];

            // Offsets for the following characters are relative to the opening bracket.
            int firstColonOffset  = 3;
            int secondColonOffset = 6;
            int dotOffset         = 9;
            int rangeStartOffset  = -16; // Start of binary data before timestamp occurs this far from the opening bracket.

            // Character positions for short timestamp.
            int closingBracketOffset_shortTimestamp = 12;
            int rangeEndOffset_shortTimestamp       = 26; // End of binary data after timestamp occurs this far from the opening bracket.

            // Character positions for long timestamp.
            int closingBracketOffset_longTimestamp = 13;
            // int rangeEndOffset_longTimestamp = 27; // End of binary data after timestamp occurs this far from the opening bracket. // Not used in this part of the code, but still good to be aware of.

            // The distance you can skip forward when searching for the next timestamp. This can vary according to the timestamp format. More logic could be put into this, but taking the length belonging to the shortest format is simplest and safest.
            int minimumRangeEndOffset = rangeEndOffset_shortTimestamp;

            timestampFormat timestampFormat = timestampFormat.shortTimestamp; //Default value, real format will be determined later.

            int  inputIndex     = rangeStartOffset * -1;                      // Valid opening bracket can't occur before this position so start here.
            bool foundTimestamp = false;                                      //Default value, will be set to true later if a timestamp is found.
            byte inputCharacter;
            int  inputLength = inputByteArray.Length;

            // Look for timestamps in the caption file data.
            while (inputIndex < inputLength)
            {
                inputCharacter = inputByteArray[inputIndex];
                // Search for opening bracket.
                if (inputCharacter == openingBracket)
                {
                    // Check if opening bracket belongs to timestamp.
                    if (inputCharacter + minimumRangeEndOffset <= inputLength)
                    {
                        // Timestamps can take 2 forms: [##:##:##.##] and [##:##:##.###].
                        // Check the elements they have in common (::.).
                        if (inputByteArray[inputIndex + firstColonOffset] == colon &&
                            inputByteArray[inputIndex + secondColonOffset] == colon &&
                            inputByteArray[inputIndex + dotOffset] == dot)
                        {
                            // Fixed timestamp identifiers match, now check location of the closing bracket.
                            if (inputByteArray[inputIndex + closingBracketOffset_shortTimestamp] == closingBracket)
                            {
                                // Timestamp was format [##:##:##.##].
                                timestampFormat = timestampFormat.shortTimestamp;
                                foundTimestamp  = true;
                            }
                            else if (inputByteArray[inputIndex + closingBracketOffset_longTimestamp] == closingBracket)
                            {
                                // Timestamp was format [##:##:##.###].
                                timestampFormat = timestampFormat.longTimestamp;
                                foundTimestamp  = true;
                            }
                            else
                            {
                                // No match for closing bracket. Not a timestamp after all, or in an unknown format.
                                foundTimestamp = false;
                            }
                        }
                        else
                        {
                            // Other timestamp identifiers don't match, opening bracket was not part of timestamp.
                            foundTimestamp = false;
                        }
                    }
                    else
                    {
                        // Not enough space after opening bracket for this to be the beginning of a subtitle.
                        foundTimestamp = false;
                    }
                }
                if (foundTimestamp)
                {
                    // The timestamp is preceded by some binary data (rangeStartOffset), so skip over that and add the actual beginning of the timestamp.
                    // Also add the timestamp format ([##:##:##.##] or [##:##:##.###]), this is important later for parsing.
                    timestampList.Add(new Timestamp(inputIndex + rangeStartOffset, timestampFormat));
                    // Set checkpoint for next timestamp beyond the (minimum) range of this one and the leading binary data of the next.
                    inputIndex += minimumRangeEndOffset + 1 - rangeStartOffset;
                    // Reset found flag.
                    foundTimestamp = false;
                }
                else
                {
                    // Advance to the next character in the caption data.
                    inputIndex++;
                }
            }
            // Return timestamp locations in the caption file data.
            return(timestampList.ToArray());
        }
 // Initialize subtitle object.
 public Subtitle(byte[] subtitleData, timestampFormat ts_format)
 {
     extractStartTimestamp(subtitleData, ts_format);
     extractText(subtitleData);
 }
 public Timestamp(int _position, timestampFormat _type)
 {
     position = _position;
     type     = _type;
 }