BDInfo.TSPlaylistFile.Scan C# (CSharp) Method

Scan() public method

public Scan ( ) : void
return void
        public void Scan()
            //Dictionary<string, TSStreamFile> streamFiles,
            //Dictionary<string, TSStreamClipFile> streamClipFiles)
        {
            FileStream fileStream = null;
            BinaryReader fileReader = null;

            int streamFileCount = 0;
            Dictionary<string, TSStreamClipFile> streamClipFiles = new Dictionary<string, TSStreamClipFile>();

            try
            {
#if DEBUG
                Debug.WriteLine(string.Format(
                    "Scanning {0}...", Name));
#endif
                Streams.Clear();
                StreamClips.Clear();

                fileStream = File.OpenRead(FileInfo.FullName);
                fileReader = new BinaryReader(fileStream);

                byte[] data = new byte[fileStream.Length];
                int dataLength = fileReader.Read(data, 0, data.Length);

                byte[] fileType = new byte[8];
                Array.Copy(data, 0, fileType, 0, fileType.Length);
                
                FileType = ASCIIEncoding.ASCII.GetString(fileType);
                if ((FileType != "MPLS0100" && FileType != "MPLS0200") 
                    /*|| data[45] != 1*/)
                {
                    throw new Exception(string.Format(
                        "Playlist {0} has an unknown file type {1}.",
                        FileInfo.Name, FileType));
                }
#if DEBUG
                Debug.WriteLine(string.Format(
                    "\tFileType: {0}", FileType));
#endif
                int playlistIndex =
                    ((int)data[8] << 24) +
                    ((int)data[9] << 16) +
                    ((int)data[10] << 8) +
                    ((int)data[11]);

                // TODO: Hack for bad TSRemux output.
                int playlistLength = data.Length - playlistIndex - 4;
                int playlistLengthCorrect =
                    ((int)data[playlistIndex] << 24) +
                    ((int)data[playlistIndex + 1] << 16) +
                    ((int)data[playlistIndex + 2] << 8) +
                    ((int)data[playlistIndex + 3]);

                byte[] playlistData = new byte[playlistLength];
                Array.Copy(data, playlistIndex + 4, 
                    playlistData, 0, playlistData.Length);

                streamFileCount =
                    (((int)playlistData[2] << 8) + (int)playlistData[3]);
#if DEBUG
                Debug.WriteLine(string.Format(
                    "\tStreamFileCount: {0}", streamFileCount));
#endif
                List<TSStreamClip> chapterClips = new List<TSStreamClip>();
                int streamFileOffset = 6;
                for (int streamFileIndex = 0; 
                    streamFileIndex < streamFileCount; 
                    streamFileIndex++)
                {
                    byte[] streamFileNameData = new byte[5];
                    Array.Copy(playlistData, streamFileOffset + 2, 
                        streamFileNameData, 0, streamFileNameData.Length);

                    //TSStreamFile streamFile = null;
                    //string streamFileName = string.Format(
                    //    "{0}.M2TS",
                    //    ASCIIEncoding.ASCII.GetString(streamFileNameData));
                    //if (streamFiles.ContainsKey(streamFileName))
                    //{
                    //    streamFile = streamFiles[streamFileName];
                    //}
                    //if (streamFile == null)
                    //{
                    //    throw new Exception(string.Format(
                    //        "Playlist {0} referenced missing file {1}.",
                    //        FileInfo.Name, streamFileName));
                    //}

                    TSStreamClipFile streamClipFile = null;
                    string streamClipFileName = string.Format(
                        "{0}.CLPI",
                        ASCIIEncoding.ASCII.GetString(streamFileNameData));
                    string streamClipFilePath = Path.Combine(Path.Combine(FileInfo.Directory.Parent.FullName, "CLIPINF"),
                      streamClipFileName);
                    if (File.Exists(streamClipFilePath) && !streamClipFiles.ContainsKey(streamClipFileName)) 
                      streamClipFiles.Add(streamClipFileName, new TSStreamClipFile(new FileInfo(streamClipFilePath)));

                    if (streamClipFiles.ContainsKey(streamClipFileName))
                    {
                        streamClipFile = streamClipFiles[streamClipFileName];
                    }
                    if (streamClipFile == null)
                    {
                        continue;
                        //throw new Exception(string.Format(
                        //    "Playlist {0} referenced missing file {1}.",
                        //    FileInfo.Name, streamClipFileName));
                    }
                    
                    byte condition = (byte)
                        (playlistData[streamFileOffset + 12] & 0xF);

                    ulong timeIn =
                        ((ulong)playlistData[streamFileOffset + 14] << 24) +
                        ((ulong)playlistData[streamFileOffset + 15] << 16) +
                        ((ulong)playlistData[streamFileOffset + 16] << 8) +
                        ((ulong)playlistData[streamFileOffset + 17]);

                    ulong timeOut =
                        ((ulong)playlistData[streamFileOffset + 18] << 24) +
                        ((ulong)playlistData[streamFileOffset + 19] << 16) +
                        ((ulong)playlistData[streamFileOffset + 20] << 8) +
                        ((ulong)playlistData[streamFileOffset + 21]);

                    TSStreamClip streamClip = new TSStreamClip(
                        //streamFile, 
                        streamClipFile);

                    streamClip.TimeIn = (double)timeIn / 45000;
                    streamClip.TimeOut = (double)timeOut / 45000;
                    streamClip.Length = streamClip.TimeOut - streamClip.TimeIn;
                    streamClip.RelativeTimeIn = TotalLength;
                    streamClip.RelativeTimeOut = streamClip.RelativeTimeIn + streamClip.Length;
                    StreamClips.Add(streamClip);
                    chapterClips.Add(streamClip);
#if DEBUG
                    Debug.WriteLine(string.Format(
                        "\t{0} {1} {2} {3}", 
                        streamClip.Name,
                        streamClip.TimeIn.TotalSeconds,
                        streamClip.TimeOut.TotalSeconds,
                        streamClip.Length.TotalSeconds));
#endif
                    if ((playlistData[streamFileOffset + 12] & 0x10) > 0)
                    {
                        int angleCount = playlistData[streamFileOffset + 34];
                        if (angleCount - 1 > AngleCount)
                        {
                            AngleCount = angleCount - 1;
                        }
                        for (int angle = 0; angle < (angleCount - 1); angle++)
                        {
                            byte[] angleFileNameData = new byte[5];
                            int angleOffset = 
                                streamFileOffset + 26 + ((angle + 1) * 10);
                            Array.Copy(playlistData, angleOffset, 
                                angleFileNameData, 0, angleFileNameData.Length);

                            //TSStreamFile angleFile = null;
                            //string angleFileName = string.Format(
                            //    "{0}.M2TS",
                            //    ASCIIEncoding.ASCII.GetString(angleFileNameData));
                            //if (streamFiles.ContainsKey(angleFileName))
                            //{
                            //    angleFile = streamFiles[angleFileName];
                            //}
                            //if (angleFile == null)
                            //{
                            //    throw new Exception(string.Format(
                            //        "Playlist {0} referenced missing angle file {1}.",
                            //        FileInfo.Name, angleFileName));
                            //}

                            TSStreamClipFile angleClipFile = null;
                            string angleClipFileName = string.Format(
                                "{0}.CLPI",
                                ASCIIEncoding.ASCII.GetString(angleFileNameData));
                            if (streamClipFiles.ContainsKey(angleClipFileName))
                            {
                                angleClipFile = streamClipFiles[angleClipFileName];
                            }
                            if (angleClipFile == null)
                            {
                                continue;
                                //throw new Exception(string.Format(
                                //    "Playlist {0} referenced missing angle file {1}.",
                                //    FileInfo.Name, angleClipFileName));
                            }

                            TSStreamClip angleClip =
                                new TSStreamClip(//angleFile, 
                                  angleClipFile);
                            angleClip.AngleIndex = angle + 1;
                            angleClip.TimeIn = streamClip.TimeIn;
                            angleClip.TimeOut = streamClip.TimeOut;
                            angleClip.RelativeTimeIn = streamClip.RelativeTimeIn;
                            angleClip.RelativeTimeOut = streamClip.RelativeTimeOut;
                            angleClip.Length = streamClip.Length;
                            StreamClips.Add(angleClip);
#if DEBUG
                            Debug.WriteLine(string.Format(
                                "\t\t{0}", angleFileName));
#endif
                        }
                    }
                    streamFileOffset += 2 +
                        ((int)playlistData[streamFileOffset] << 8) +
                        ((int)playlistData[streamFileOffset + 1]);
                }

                int chaptersIndex =
                    ((int)data[12] << 24) +
                    ((int)data[13] << 16) +
                    ((int)data[14] << 8) +
                    ((int)data[15]);

                int chaptersLength =
                    ((int)data[chaptersIndex] << 24) +
                    ((int)data[chaptersIndex + 1] << 16) +
                    ((int)data[chaptersIndex + 2] << 8) +
                    ((int)data[chaptersIndex + 3]);

                byte[] chapterData = 
                    new byte[chaptersLength];
                Array.Copy(data, chaptersIndex + 4, 
                    chapterData, 0, chaptersLength);

                int chapterCount = 
                    ((int)chapterData[0] << 8) + chapterData[1];
                int chapterOffset = 2;
                for (int chapterIndex = 0; 
                    chapterIndex < chapterCount; 
                    chapterIndex++)
                {
                    if (chapterData[chapterOffset + 1] == 1)
                    {
                        int streamFileIndex =
                            ((int)chapterData[chapterOffset + 2] << 8) + 
                            chapterData[chapterOffset + 3];

                        TSStreamClip streamClip = chapterClips[streamFileIndex];

                        long chapterTime =
                            ((long)chapterData[chapterOffset + 4] << 24) +
                            ((long)chapterData[chapterOffset + 5] << 16) +
                            ((long)chapterData[chapterOffset + 6] << 8) +
                            ((long)chapterData[chapterOffset + 7]);

                        double chapterSeconds = (double)chapterTime / 45000;
                        double relativeSeconds =
                            chapterSeconds -
                            streamClip.TimeIn +
                            streamClip.RelativeTimeIn;

                        // TODO: Ignore short last chapter?
                        if (TotalLength - relativeSeconds > 1.0)
                        {
                            streamClip.Chapters.Add(chapterSeconds);
                            this.Chapters.Add(relativeSeconds);
                        }
#if DEBUG
                        Debug.WriteLine(string.Format(
                            "\t{0} {1} {2}", 
                            chapterIndex, 
                            streamClip.Name, 
                            chapter.TotalSeconds));
#endif
                    }
                    chapterOffset += 14;
                }
#if DEBUG
                Debug.WriteLine(string.Format(
                    "\tLength: {0}", Length.TotalSeconds));
                Debug.WriteLine(string.Format(
                    "\tAngleLength: {0}", AngleLength.TotalSeconds));
#endif
                //LoadStreamClips();
                IsInitialized = true;
            }
            finally
            {
                if (fileReader != null)
                {
                    fileReader.Close();
                }
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }

Usage Example

        public override List<ChapterInfo> GetStreams(string location)
        {
            ChapterInfo pgc = new ChapterInfo();
              pgc.Chapters = new List<ChapterEntry>();
              pgc.SourceHash = ChapterExtractor.ComputeMD5Sum(location);
              pgc.SourceName = location;
              pgc.Title = Path.GetFileNameWithoutExtension(location);
              pgc.SourceType = "Blu-Ray";
              pgc.Extractor = Application.ProductName + " " + Application.ProductVersion;

              FileInfo fileInfo = new FileInfo(location);

              OnStreamDetected(pgc);
              TSPlaylistFile mpls = new TSPlaylistFile(fileInfo);
              //Dictionary<string, TSStreamClipFile> clips = new Dictionary<string,TSStreamClipFile>();
              mpls.Scan();
              foreach (double d in mpls.Chapters)
              {
            pgc.Chapters.Add(new ChapterEntry()
              {
            Name = string.Empty,
            Time = new TimeSpan((long)(d * (double)TimeSpan.TicksPerSecond))
              });
              }

              pgc.Duration = new TimeSpan((long)(mpls.TotalLength * (double)TimeSpan.TicksPerSecond));

              foreach (TSStreamClip clip in mpls.StreamClips)
              {
              try
              {
              clip.StreamClipFile.Scan();
                foreach (TSStream stream in clip.StreamClipFile.Streams.Values)
                {
                  if (stream.IsVideoStream)
                  {
                    pgc.FramesPerSecond = (double)((TSVideoStream)stream).FrameRateEnumerator /
                    (double)((TSVideoStream)stream).FrameRateDenominator;
                    break;
                  }
                }
                if (pgc.FramesPerSecond != 0) break;
              }
              catch (Exception ex)
              {
              Trace.WriteLine(ex);
              }
              }

              OnChaptersLoaded(pgc);
              OnExtractionComplete();
              return new List<ChapterInfo>() { pgc };
        }
All Usage Examples Of BDInfo.TSPlaylistFile::Scan