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();
}
}
}