コード例 #1
0
ファイル: PictureDataTest.cs プロジェクト: stackprobe/Craft
        public void Test01()
        {
            PictureData picture = new PictureData(new Canvas2(@"C:\wb2\20191204_ジャケット的な\バンドリ_イニシャル.jpg"), 1920, 1080);

            const int FRAME_NUM = 200;

            const int D_MAX = 20;
            int       dTarg = D_MAX;
            int       d     = D_MAX;

            using (WorkingDir wd = new WorkingDir())
            {
                FileTools.CreateDir(wd.GetPath("img"));

                for (int frame = 0; frame < FRAME_NUM; frame++)
                {
                    Console.WriteLine(frame);                     // test

                    picture.SetFrame(frame * 1.0 / FRAME_NUM);

                    // ---- 暗くする ----

                    if (frame == 10)
                    {
                        dTarg = 0;
                    }
                    else if (frame + 10 + D_MAX == FRAME_NUM)
                    {
                        dTarg = D_MAX;
                    }

                    if (d < dTarg)
                    {
                        d++;
                    }
                    else if (dTarg < d)
                    {
                        d--;
                    }

                    if (0 < d)
                    {
                        picture.SetDrakness(d * 1.0 / D_MAX);
                    }

                    // ----

                    picture.Save(wd.GetPath("img\\" + frame + ".jpg"));
                }

                ProcessTools.Batch(new string[]
                {
                    @"C:\app\ffmpeg-4.1.3-win64-shared\bin\ffmpeg.exe -r 20 -i %%d.jpg ..\out.mp4",
                },
                                   wd.GetPath("img")
                                   );

                File.Copy(wd.GetPath("out.mp4"), @"C:\temp\1.mp4", true);
            }
        }
コード例 #2
0
        public WaveData(string wavFile)
        {
            using (WorkingDir wd = new WorkingDir())
            {
                File.Copy(wavFile, wd.GetPath("1.wav"));

                ProcessTools.Batch(new string[]
                {
                    Consts.wavCsv_FILE + " /W2C 1.wav 1.csv 1.hz",
                },
                                   wd.GetPath(".")
                                   );

                using (CsvFileReader reader = new CsvFileReader(wd.GetPath("1.csv")))
                {
                    List <double> wavData_L = new List <double>();
                    List <double> wavData_R = new List <double>();

                    for (; ;)
                    {
                        string[] row = reader.ReadRow();

                        if (row == null)
                        {
                            break;
                        }

                        // memo: row[0,1]の値域は0~65535だが、32768が波形0(無音?)なので、これを0にするために65536で割る。

                        // 波形を [-1.0, 1.0) の区間にする。
                        wavData_L.Add((int.Parse(row[0]) / 65536.0 - 0.5) * 2.0);
                        wavData_R.Add((int.Parse(row[1]) / 65536.0 - 0.5) * 2.0);
                    }
                    //if (wavData_R.Count == 0)
                    if (wavData_L.Count == 0)
                    {
                        throw new Exception("wavData_L.Count == 0");
                    }

                    this.WavData_L = wavData_L.ToArray();
                    this.WavData_R = wavData_R.ToArray();
                }
                this.WavHz = int.Parse(File.ReadAllText(wd.GetPath("1.hz"), Encoding.ASCII));

                if (this.WavHz < 1 || IntTools.IMAX < this.WavHz)
                {
                    throw new Exception("Bad WavHz: " + this.WavHz);
                }
            }
        }
コード例 #3
0
        public static void MP3FileToWavFile(string rMP3File, string wWavFile)
        {
            if (string.IsNullOrEmpty(rMP3File))
            {
                throw null;
            }

            if (string.IsNullOrEmpty(wWavFile))
            {
                throw null;
            }

            FileTools.Delete(wWavFile);

            if (File.Exists(rMP3File) == false)
            {
                throw null;
            }

            if (File.Exists(wWavFile))
            {
                throw null;
            }

            using (WorkingDir wd = new WorkingDir())
            {
                File.Copy(rMP3File, wd.GetPath("1.mp3"));

                ProcessTools.Batch(new string[]
                {
                    Consts.FFMPEG_FILE + " -i 1.mp3 2.wav",
                },
                                   wd.GetPath(".")
                                   );

                if (File.Exists(wd.GetPath("2.wav")) == false)
                {
                    throw new Exception("変換に失敗しました。");
                }

                File.Copy(wd.GetPath("2.wav"), wWavFile);

                if (File.Exists(wWavFile) == false)
                {
                    throw new Exception("コピーに失敗しました。");
                }
            }
        }
コード例 #4
0
        private static byte[] LoadFile(ResInfo resInfo)
        {
            byte[] fileData;

            if (resInfo.CachedFile == null)
            {
                fileData = LoadFile(resInfo.ResFile, resInfo.Offset, resInfo.Size);

#if true
                {
                    Func <string> a_makeLocalName = () => "$" + SCommon.CRandom.GetRange(1, 3);
                    string        dir             = Path.Combine(WD.GetPath(a_makeLocalName()), a_makeLocalName(), a_makeLocalName(), a_makeLocalName());
                    SCommon.CreateDir(dir);
                    resInfo.CachedFile = Path.Combine(dir, "$" + CachedFileCounter++);
                }
#else // シンプル
                resInfo.CachedFile = WD.MakePath();
#endif

                File.WriteAllBytes(resInfo.CachedFile, fileData);
            }
            else
            {
                fileData = File.ReadAllBytes(resInfo.CachedFile);
            }
            return(fileData);
        }
コード例 #5
0
        public WaveData(string wavFile)
        {
            using (WorkingDir wd = new WorkingDir())
            {
                File.Copy(wavFile, wd.GetPath("1.wav"));

                ProcessTools.Batch(new string[]
                {
                    Ground.I.wavCsvExeFile + " /W2C 1.wav 1.csv 1.hz",
                },
                                   wd.GetPath(".")
                                   );

                using (CsvFileReader reader = new CsvFileReader(wd.GetPath("1.csv")))
                {
                    List <double> wavData_L = new List <double>();
                    List <double> wavData_R = new List <double>();

                    for (; ;)
                    {
                        string[] row = reader.ReadRow();

                        if (row == null)
                        {
                            break;
                        }

                        wavData_L.Add((int.Parse(row[0]) / 65536.0 - 0.5) * 2.0);
                        wavData_R.Add((int.Parse(row[1]) / 65536.0 - 0.5) * 2.0);
                    }
                    if (wavData_L.Count == 0)
                    {
                        throw new Exception("wavData_L.Count == 0");
                    }

                    this.WavData_L = wavData_L.ToArray();
                    this.WavData_R = wavData_R.ToArray();
                }
                this.WavHz = int.Parse(File.ReadAllText(wd.GetPath("1.hz"), Encoding.ASCII));

                if (this.WavHz < 1 || IntTools.IMAX < this.WavHz)
                {
                    throw new Exception("Bad WavHz: " + this.WavHz);
                }
            }
        }
コード例 #6
0
ファイル: ConvFileMain.cs プロジェクト: stackprobe/Craft
        private void MasteringWavFile()
        {
            using (WorkingDir wd = new WorkingDir())
            {
                File.Copy(this.WavFile, wd.GetPath("1.wav"));

                this.Batch(
                    Consts.MASTER_FILE + " /E " + Consts.EV_STOP_MASTER + " /-LV 1.wav 2.wav 3.txt",
                    wd.GetPath(".")
                    );

                Ground.I.Logger.Info("Master.exe Log: " + File.ReadAllText(wd.GetPath("3.txt"), StringTools.ENCODING_SJIS));

                if (File.Exists(wd.GetPath("2.wav")))                 // ? 音量調整した。
                {
                    Ground.I.Logger.Info("音量調整_Y");
                }
                else                 // ? 音量調整しなかった。
                {
                    Ground.I.Logger.Info("音量調整_N");

                    File.Copy(wd.GetPath("1.wav"), wd.GetPath("2.wav"));                     // そのままコピー
                }

                File.Move(wd.GetPath("2.wav"), this.MasterWavFile);
            }
        }
コード例 #7
0
        public static bool Mastering(string sourceWavFile, string destWavFile, Action <string[]> writeReport = null)
        {
            FileTools.Delete(destWavFile);

            using (WorkingDir wd = new WorkingDir())
            {
                File.Copy(sourceWavFile, wd.GetPath("in.wav"));

                ProcessTools.Batch(new string[]
                {
                    string.Format(@"{0} /E {1} in.wav out.wav report.txt",
                                  Ground.I.MasterExeFile,
                                  CANCEL_EV_NAME
                                  ),
                },
                                   wd.GetPath(".")
                                   );

                {
                    string reportFile = wd.GetPath("report.txt");

                    if (File.Exists(reportFile) == false)
                    {
                        throw new Exception("[Mastering]レポートファイルが出力されませんでした。");
                    }

                    if (writeReport != null)
                    {
                        writeReport(File.ReadAllLines(reportFile, StringTools.ENCODING_SJIS));
                    }
                }

                {
                    string midFile = wd.GetPath("out.wav");

                    if (File.Exists(midFile) == false)
                    {
                        return(false);
                    }

                    File.Copy(midFile, destWavFile);
                }
            }
            return(true);
        }
コード例 #8
0
ファイル: ConvFileMain.cs プロジェクト: stackprobe/Craft
        private void MakeWavFile()
        {
            using (WorkingDir wd = new WorkingDir())
            {
                string audioExt = Path.GetExtension(this.AudioFile);

#if true // .wav にもサラウンドとかある様なのでステレオにする。
                File.Copy(this.AudioFile, wd.GetPath("1" + audioExt));

                this.Batch(
                    Consts.FFMPEG_FILE + " -i 1" + audioExt + " -ac 2 2.wav",
                    wd.GetPath(".")
                    );
#else
                if (StringTools.EqualsIgnoreCase(audioExt, ".wav"))
                {
                    File.Copy(this.AudioFile, wd.GetPath("2.wav"));
                }
                else
                {
                    File.Copy(this.AudioFile, wd.GetPath("1" + audioExt));

                    this.Run(
                        Consts.FFMPEG_FILE + " -i 1" + audioExt + " 2.wav",
                        wd.GetPath(".")
                        );
                }
#endif
                File.Move(wd.GetPath("2.wav"), this.WavFile);
            }
        }
コード例 #9
0
ファイル: ConvFileMain.cs プロジェクト: stackprobe/Craft
        private void MakeVideoJpg()
        {
            try
            {
                Ground.I.EvCancellable_N.Set();
                Ground.I.EvMessage_StartGenVideo.Set();

                Thread.Sleep(200);                 // 予告期間
                //Thread.Sleep(5000); // 予告期間

                Ground.I.EvMessage_GenVideoRunning.Set();

                using (WorkingDir wd = new WorkingDir())
                {
                    string wdJacketFile = wd.GetPath("2x" + Path.GetExtension(this.JacketFile));

                    File.Copy(this.SpectrumFile, wd.GetPath("1.csv"));
                    File.Copy(this.JacketFile, wdJacketFile);

                    this.AdjustJacketSize(wdJacketFile, wd.GetPath("2.png"));

                    FileTools.CreateDir(wd.GetPath("3"));

                    this.Batch(
                        "START /WAIT " + Ground.I.ConvGenVideoFile + " CS-ConvGenVideo " + wd.GetPath("1.csv") + " " + wd.GetPath("2.png") + " " + wd.GetPath("3") + " " + wd.GetPath("4.flg") + " " + wd.GetPath("5.flg"),
                        ProcMain.SelfDir
                        );

                    if (File.Exists(wd.GetPath("4.flg")))
                    {
                        Ground.I.Logger.Info("映像データ生成プロセスによってキャンセルされました。");

                        throw new Cancelled();
                    }
                    if (File.Exists(wd.GetPath("5.flg")) == false)
                    {
                        throw new Exception("映像データ生成プロセスが正常に動作しなかったようです。");
                    }

                    this.CheckVideoJpg(wd.GetPath("3"));

                    FileTools.MoveDir(wd.GetPath("3"), this.VideoJpgDir);
                }
            }
            finally
            {
                Ground.I.EvCancellable_Y.Set();
                Ground.I.EvMessage_Normal.Set();
            }
        }
コード例 #10
0
ファイル: FFmpegConv.cs プロジェクト: stackprobe/Craft
        public static void MakeWavFile(string movieOrAudioFile, string destWavFile)
        {
            FileTools.Delete(destWavFile);

            if (Path.GetExtension(movieOrAudioFile).ToLower() == ".wav")
            {
                File.Copy(movieOrAudioFile, destWavFile);
            }
            else
            {
                using (FFmpegMedia audio = new FFmpegMedia())
                    using (WorkingDir wd = new WorkingDir())
                    {
                        audio.PutAudioFile(movieOrAudioFile);

                        ProcessTools.Batch(new string[]
                        {
                            // ステレオにする。
                            string.Format(@"{0}ffmpeg.exe -i {1} -map 0:{2} -ac 2 out.wav",
                                          AudioPicMP4Props.FFmpegPathBase,
                                          audio.GetFile(),
                                          audio.GetInfo().GetAudioStreamIndex()
                                          ),
                        },
                                           wd.GetPath(".")
                                           );

                        {
                            string midFile = wd.GetPath("out.wav");

                            if (File.Exists(midFile) == false)
                            {
                                throw new Exception();
                            }

                            File.Copy(midFile, destWavFile);
                        }
                    }
            }
        }
コード例 #11
0
        public void Test01_a(string wavFile, string imgFile, string mp4File)
        {
            using (WorkingDir wd = new WorkingDir())
            {
                string imgDir = wd.GetPath("img");

                FileTools.CreateDir(imgDir);

                PictureData picture = new PictureData(new Canvas2(imgFile), 1920, 1080);
                WaveData    wave    = new WaveData(wavFile);

                VideoData video  = new VideoData(picture, (wave.Length * VideoData.FPS) / wave.WavHz, imgDir);
                IEffect   effect = new SpectrumEffect01(wave);

                video.MakeImages(new VideoData.FadeInOutInfo()
                {
                    StartMargin   = 2 * VideoData.FPS,
                    EndMargin     = -1,
                    FadeInOutSpan = 20,
                },
                                 effect,
                                 new VideoData.FadeInOutInfo()
                {
                    StartMargin   = -1,
                    EndMargin     = 10,
                    FadeInOutSpan = 10,
                });

                File.Copy(wavFile, wd.GetPath("audio.wav"));

                ProcessTools.Batch(new string[]
                {
                    @"C:\app\ffmpeg-4.1.3-win64-shared\bin\ffmpeg.exe -r 20 -i %%d.jpg -i ..\audio.wav ..\out.mp4",
                },
                                   imgDir
                                   );

                File.Copy(wd.GetPath("out.mp4"), mp4File, true);
            }
        }
コード例 #12
0
ファイル: ConvFileMain.cs プロジェクト: stackprobe/Craft
        private void MakeMovieFile()
        {
            using (WorkingDir wd = new WorkingDir())
            {
                FileTools.CopyDir(this.VideoJpgDir, wd.GetPath("1"));

                this.Batch(
                    Consts.FFMPEG_FILE + " -r " + Consts.FPS + " -i %%d.jpg ..\\2.mp4",
                    wd.GetPath("1")
                    );

                if (File.Exists(wd.GetPath("2.mp4")) == false)
                {
                    throw new Exception("映像ファイルの生成に失敗しました。");
                }

                File.Copy(this.MasterWavFile, wd.GetPath("3.wav"));

                // -codec:a copy を除去
                // -ab 160k を追加
                this.Batch(
                    Consts.FFMPEG_FILE + " -i 2.mp4 -i 3.wav -map 0:0 -map 1:0 -vcodec copy -ab 160k 4.mp4",
                    wd.GetPath(".")
                    );

                if (File.Exists(wd.GetPath("4.mp4")) == false)
                {
                    throw new Exception("動画ファイルの生成に失敗しました。");
                }

                this.Batch(
                    "ECHO Y|CACLS 4.mp4 /P Users:F Guest:F",
                    wd.GetPath(".")
                    );

                if (File.Exists(this.MovieFile))                 // 2bs
                {
                    throw null;
                }

                File.Move(wd.GetPath("4.mp4"), this.MovieFile);

                if (File.Exists(this.MovieFile) == false)
                {
                    throw new Exception("動画ファイルの書き出しに失敗しました。");
                }
            }
        }
コード例 #13
0
        private void Main2(ArgsReader ar)
        {
            string        resDir    = null;
            List <string> srcDirs   = new List <string>();
            string        outJSFile = null;
            string        tagsFile  = null;

            while (true)
            {
                if (ar.ArgIs("/R"))
                {
                    resDir = ar.NextArg();
                    continue;
                }
                if (ar.ArgIs("/S"))
                {
                    srcDirs.Add(ar.NextArg());
                    continue;
                }
                if (ar.ArgIs("/WB"))
                {
                    outJSFile  = ar.NextArg();
                    outJSFile  = FileTools.MakeFullPath(outJSFile);
                    outJSFile += ".js";
                    continue;
                }
                if (ar.ArgIs("/T"))
                {
                    tagsFile = ar.NextArg();
                    continue;
                }
                if (ar.HasArgs())
                {
                    throw new Exception("不明なコマンド引数");
                }

                break;
            }

            if (resDir == null)
            {
                throw new Exception("リソースディレクトリを指定して下さい。");
            }

            if (srcDirs.Count == 0)
            {
                throw new Exception("ソースディレクトリを指定して下さい。");
            }

            if (outJSFile == null)
            {
                throw new Exception("出力JSファイルを指定して下さい。");
            }

            if (tagsFile == null)
            {
                throw new Exception("tagsファイルを指定して下さい。");
            }

            {
                JSModuleConverter mc = new JSModuleConverter();

                mc.LoadResourceDir(resDir);

                foreach (string srcDir in srcDirs)
                {
                    mc.LoadSourceDir(srcDir);
                }

                mc.WriteJSFile(outJSFile);
            }

            using (WorkingDir wd = new WorkingDir())
            {
                const string MID_TAGS_FILE = "tags.mid.tmp";

                ProcessTools.Batch(new string[]
                {
                    string.Format(@"C:\Factory\DevTools\makeTags.exe /JS {0} {1}", outJSFile, MID_TAGS_FILE),
                },
                                   wd.GetPath(".")
                                   );

                if (File.Exists(wd.GetPath(MID_TAGS_FILE)) == false)
                {
                    throw new Exception("tagsファイルの生成に失敗しました。");
                }

                string[] tagsLines = File.ReadAllLines(wd.GetPath(MID_TAGS_FILE), StringTools.ENCODING_SJIS);

                File.AppendAllLines(tagsFile, tagsLines, StringTools.ENCODING_SJIS);                 // 注意:追記する。
            }
        }
コード例 #14
0
ファイル: ConvFileMain.cs プロジェクト: stackprobe/Craft
        private void MakeSpectrumFile()
        {
            Ground.I.Logger.Info("MakeSpectrumFile.1");
            WaveData wavDat = new WaveData(this.MasterWavFile);

            Ground.I.Logger.Info("MakeSpectrumFile.2");

#if true
            using (WorkingDir wd = new WorkingDir())
                using (MultiThreadEx mtx = new MultiThreadEx())
                {
                    Ground.I.Logger.Info("MakeSpectrumFile.3");

                    int frameEnd;

                    {
                        int frame;

                        for (frame = 1; MPF_GetWavPartPos(frame, wavDat) < wavDat.Length; frame++)
                        {
                        }

                        frameEnd = frame;
                    }

                    int THREAD_NUM = this.ThreadCount;

                    Ground.I.Logger.Info("THREAD_NUM:" + THREAD_NUM);

                    if (THREAD_NUM < 1)
                    {
                        throw null;
                    }

                    const string SP_CSV_LOCAL_FILE_BASE = "SP_Csv_";

                    for (int c = 0; c < THREAD_NUM; c++)
                    {
                        string thc_wFile            = wd.GetPath(SP_CSV_LOCAL_FILE_BASE + c);
                        int    thc_frameSt          = (frameEnd * (c + 0)) / THREAD_NUM;
                        int    thc_frameEd          = (frameEnd * (c + 1)) / THREAD_NUM;
                        WaveData.WavPartInfo thc_wp = new WaveData.WavPartInfo();

                        mtx.Add(() =>
                        {
                            using (CsvFileWriter writer = new CsvFileWriter(thc_wFile))
                            {
                                for (int frame = thc_frameSt; frame < thc_frameEd; frame++)
                                {
                                    int wavPartPos = MPF_GetWavPartPos(frame, wavDat);
                                    wavDat.LoadWavPart(thc_wp, wavPartPos);
                                    SpectrumGraph graph = new SpectrumGraph(hz => wavDat.GetSpectrum(thc_wp, hz));
                                    CsvUtils.WriteRow(writer, graph);
                                }
                            }
                        });
                    }

                    Ground.I.Logger.Info("MakeSpectrumFile.4");
                    mtx.RelayThrow();
                    Ground.I.Logger.Info("MakeSpectrumFile.5");

                    using (CsvFileWriter writer = new CsvFileWriter(this.SpectrumFile))
                    {
                        for (int c = 0; c < THREAD_NUM; c++)
                        {
                            string rFile = wd.GetPath(SP_CSV_LOCAL_FILE_BASE + c);

                            using (CsvFileReader reader = new CsvFileReader(rFile))
                            {
                                for (; ;)
                                {
                                    string[] row = reader.ReadRow();

                                    if (row == null)
                                    {
                                        break;
                                    }

                                    writer.WriteRow(row);
                                }
                            }
                        }
                    }

                    Ground.I.Logger.Info("MakeSpectrumFile.6");
                }
#else // old
            using (CsvFileWriter writer = new CsvFileWriter(this.SpectrumFile))
            //using (CsvFileWriter writer_L = new CsvFileWriter(this.SpectrumFile_L)) // 不使用
            //using (CsvFileWriter writer_R = new CsvFileWriter(this.SpectrumFile_R)) // 不使用
            {
                for (int frame = 0; ; frame++)
                {
                    int wavPartPos = MPF_GetWavPartPos(frame, wavDat);
                    //int wavPartPos = (int)((frame * 1.0 / Consts.FPS + Consts.AUDIO_DELAY_SEC) * wavDat.WavHz);

                    if (wavDat.Length <= wavPartPos)
                    {
                        break;
                    }

                    if (frame % 200 == 0)
                    {
                        Ground.I.Logger.Info("MSF_frame: " + frame);

                        this.CheckCancel();
                    }

                    wavDat.SetWavPart(wavPartPos);

                    SpectrumGraph graph = new SpectrumGraph(hz => wavDat.GetSpectrum(hz));
                    //SpectrumGraph graph_L = new SpectrumGraph(hz => wavDat.GetSpectrum_L(hz)); // 不使用
                    //SpectrumGraph graph_R = new SpectrumGraph(hz => wavDat.GetSpectrum_R(hz)); // 不使用

                    CsvUtils.WriteRow(writer, graph);
                    //CsvUtils.WriteRow(writer_L, graph_L); // 不使用
                    //CsvUtils.WriteRow(writer_R, graph_R); // 不使用
                }
            }
            Ground.I.Logger.Info("MakeSpectrumFile.3");
#endif
        }
コード例 #15
0
        private int VideoStreamIndex     = -1;     // -1 == no video stream

        public FFmpegMediaInfo(string file)
        {
            string[] lines;

            using (WorkingDir wd = new WorkingDir())
            {
                ProcessTools.Batch(new string[]
                {
                    string.Format(@"{0}ffprobe.exe {1} 2> stderr.tmp",
                                  AudioPicMP4Props.FFmpegPathBase,
                                  file
                                  ),
                },
                                   wd.GetPath(".")
                                   );

                string text = File.ReadAllText(wd.GetPath("stderr.tmp"), Encoding.UTF8);

                lines = FileTools.TextToLines(text);
            }

            foreach (string fLine in lines)
            {
                string line = fLine.Trim();

                if (Regex.IsMatch(line, "^Duration: [0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{2},"))
                {
                    int h = int.Parse(line.Substring(10, 2));
                    int m = int.Parse(line.Substring(13, 2));
                    int s = int.Parse(line.Substring(16, 2));
                    int c = int.Parse(line.Substring(19, 2));

                    int t = h;
                    t *= 60;
                    t += m;
                    t *= 60;
                    t += s;
                    t *= 100;
                    t += c;

                    this.TotalTimeCentisecond = t;
                }
                else if (Regex.IsMatch(line, "^Stream.*Audio:"))
                {
                    string[] tokens  = StringTools.Tokenize(line, StringTools.DECIMAL, true, true);
                    int      strmIdx = int.Parse(tokens[1]);

                    if (strmIdx < 0 || IntTools.IMAX < strmIdx)
                    {
                        throw new Exception("Bad strmIdx: " + strmIdx);
                    }

                    this.AudioStreamIndex = strmIdx;
                }
                else if (Regex.IsMatch(line, "^Stream.*Video:"))
                {
                    string[] tokens  = StringTools.Tokenize(line, StringTools.DECIMAL, true, true);
                    int      strmIdx = int.Parse(tokens[1]);

                    if (strmIdx < 0 || IntTools.IMAX < strmIdx)
                    {
                        throw new Exception("Bad strmIdx: " + strmIdx);
                    }

                    this.VideoStreamIndex = strmIdx;
                }
            }

            if (this.TotalTimeCentisecond < 0 || IntTools.IMAX < this.TotalTimeCentisecond)
            {
                throw new Exception("Bad TotalTimeCentisecond: " + this.TotalTimeCentisecond);
            }
        }