//------------------------------------------------------------------------- // 開始 //------------------------------------------------------------------------- public static void Start(Dictionary<string, string> iParams) { // XSplit if (Properties.Settings.Default.use_xsplit) { XSplit.Start(); using (Bouyomi bm = new Bouyomi()) { bm.Talk("エックスプリット配信を開始します。"); } return; } // NLE if (Properties.Settings.Default.use_NLE) { NicoLiveEncoder.Start(); using (Bouyomi bm = new Bouyomi()) { bm.Talk("ニコニコライブエンコーダ配信を開始します。"); } return; } DeleteSessionfile(); if (Properties.Settings.Default.fme_gui) { Thread th = new Thread(delegate() { mFMEStarted = FMEGUI.Start(iParams); }); th.Start(); } else { if (hasFME()) return; // FMLECmdのパス string APP_PATH = Properties.Settings.Default.fmle_path; // プロファイルのパス string profile_path = Path.GetTempPath() + "nicovideo_fme.xml"; Thread th = new Thread(delegate() { // プロファイル作成 if (!MakeProfile(profile_path, iParams)) { mFMEStarted = false; return; } // FMLECmd起動 string args = " /p \"" + profile_path + "\""; if (Properties.Settings.Default.fme_dos) { Process.Start(APP_PATH, args); } else { ProcessStartInfo psInfo = new ProcessStartInfo(); psInfo.FileName = APP_PATH; psInfo.CreateNoWindow = true; psInfo.UseShellExecute = false; psInfo.Arguments = args; Process.Start(psInfo); } using (Bouyomi bm = new Bouyomi()) { bm.Talk("えふえむいー配信を開始しました"); } mFMEStarted = true; }); th.Start(); } }
// // この関数を定期的に呼ぶ // public static void HandlingStatus(string id, Form mf=null) { // 停止は、idなくても可能 if (require_status != XSplit_Status.XS_NEED_STOP) { if (id == null) return; if (id.Length < 2) return; } // XSplitのプロセスが無いときは、何も出来ない。 if (IsAlive) { if (require_status == XSplit_Status.XS_IDLE) return; string caption = Text; if (caption == null) return; // 過渡状態では、ダイアログのお掃除のみ if (caption.Contains("配信を初期化しています")) { SweepDialogs(); return; } switch (require_status) { case XSplit_Status.XS_NEED_START: if (caption.Contains("Streaming Live - NicoVideo - ")) { require_status = XSplit_Status.XS_IDLE; return; } if (caption.Contains("XSplit Broadcaster - 配信中")) { require_status = XSplit_Status.XS_IDLE; return; } StartNicoLive(mf); //SHIFT_CONTROL_ALT_A(); require_status = XSplit_Status.XS_NEED_CHECK_CLIPBOARD; break; case XSplit_Status.XS_NEED_CHECK_CLIPBOARD: if (caption.Equals("XSplit Broadcaster")) { using (Bouyomi bm = new Bouyomi()) { bm.Talk("エックスプリット、ニコ生接続失敗"); } require_status = XSplit_Status.XS_IDLE; return; } if (Clipboard.ContainsText()) { if (Clipboard.GetText().Contains(id)) { require_status = XSplit_Status.XS_IDLE; } else { require_status = XSplit_Status.XS_NEED_RESTART; } } break; case XSplit_Status.XS_NEED_RESTART: if (caption.Length == 0) { require_status = XSplit_Status.XS_NEED_START; return; } if (caption.Equals("XSplit Broadcaster")) { require_status = XSplit_Status.XS_NEED_START; return; } if (caption.Contains("Streaming Live - NicoVideo - ")) { StopNicoLive(); //SHIFT_CONTROL_ALT_A(); } break; case XSplit_Status.XS_NEED_STOP: if (caption.Length == 0) { require_status = XSplit_Status.XS_IDLE; return; } if (caption.Equals("XSplit Broadcaster")) { require_status = XSplit_Status.XS_IDLE; return; } if (caption.Contains("Streaming Live - NicoVideo - ")) { StartNicoLive(mf); //SHIFT_CONTROL_ALT_A(); } break; } } else { require_status = XSplit_Status.XS_IDLE; } }
public static void StartNicoLive(Form mainForm) { Clipboard.Clear(); const int padding = 3; const int padding2 = 3; FindXSplitMainWindow(); IntPtr hAfterWnd = IntPtr.Zero; // ウインドウが最小化状態だったか否か bool original_iconic = IsIconic(hXSplitWnd); if (!original_iconic) { hAfterWnd = GetWindow(hXSplitWnd, (uint)GetWindow_Cmd.GW_HWNDPREV); while (hAfterWnd != IntPtr.Zero && !IsWindowVisible(hAfterWnd)) { hAfterWnd = GetWindow(hAfterWnd, (uint)GetWindow_Cmd.GW_HWNDPREV); } } // クライアント領域のスクリーンをキャプチャする Bitmap bmp = null; //// ウィンドウを元に戻す ShowWindow(hXSplitWnd, SW_RESTORE); System.Threading.Thread.Sleep(500); //// ウインドウをフォアグラウンドに SetForegroundWindow(hXSplitWnd); // アクティブにする System.Threading.Thread.Sleep(500); //// ウインドウが表示されるまで待つ WINDOWPLACEMENT wndplace = new WINDOWPLACEMENT(); do { System.Threading.Thread.Sleep(500); GetWindowPlacement(hXSplitWnd, ref wndplace); } while ((wndplace.showCmd != SW_SHOWNORMAL)); bool bStartPushed = false; using (ScreenCapture scr = new ScreenCapture()) { // クライアント領域のサイズを取得 RECT clientrect = new RECT(); POINT p1, p2; Rectangle iRect; // クライアント領域の取得 GetClientRect(hXSplitWnd, ref clientrect); p1.x = clientrect.left; p1.y = clientrect.top; p2.x = clientrect.right; p2.y = clientrect.bottom; //クライアント領域座標をスクリーン座標に変換 ClientToScreen(hXSplitWnd, ref p1); ClientToScreen(hXSplitWnd, ref p2); //取り込む座標を矩形領域に設定 iRect = new Rectangle(p1.x, p1.y, p2.x - p1.x + 1, p2.y - p1.y + 1); Point outPos = new Point(); Point haishin_offs = new Point(125, 3); Point nico_offs = new Point(143, 25); int i; // 配信メニューを押す for (i = 0; i < 60; i++) { bmp = scr.Capture(iRect); //bmp.Save("D:\\start_wait.png"); if (ContainBitmap(mHaishinBmp, bmp, haishin_offs.X - padding2, haishin_offs.Y - padding, haishin_offs.X + padding2, haishin_offs.Y + padding, ref outPos, 5)) { using (Bouyomi bm = new Bouyomi()) { bm.Talk("配信メニュー選択"); } System.Threading.Thread.Sleep(500); // MouseClick(p1.x + 139, p1.y + 13); bStartPushed = true; // 立ち上がるのを待つ break; } bmp.Dispose(); bmp = null; //// ウィンドウを元に戻す ShowWindow(hXSplitWnd, SW_RESTORE); // アクティブにする SetForegroundWindow(hXSplitWnd); // ウエイト System.Threading.Thread.Sleep(500); // クライアント領域を再取得 GetClientRect(hXSplitWnd, ref clientrect); p1.x = clientrect.left; p1.y = clientrect.top; p2.x = clientrect.right; p2.y = clientrect.bottom; //クライアント領域座標をスクリーン座標に変換 ClientToScreen(hXSplitWnd, ref p1); ClientToScreen(hXSplitWnd, ref p2); //取り込む座標を矩形領域に設定 iRect = new Rectangle(p1.x, p1.y, p2.x - p1.x + 1, p2.y - p1.y + 1); } //// ニコ生を押す if (bStartPushed) { for (i = 0; i < 60; i++) { // ここでマウスクリック MouseClick(p1.x + 139, p1.y + 13); System.Threading.Thread.Sleep(500); // もはや、座標は変えられない bmp = scr.Capture(iRect); //bmp.Save("D:\\nico_wait.png"); if (ContainBitmap(mNicoBmp, bmp, nico_offs.X - padding2, nico_offs.Y - padding, nico_offs.X + padding2, nico_offs.Y + 64 + padding, ref outPos, 5)) { using (Bouyomi bm = new Bouyomi()) { bm.Talk("ニコ生プッシュ"); } MouseClick(p1.x + outPos.X + 8, p1.y + outPos.Y + 14); // MouseClick(p1.x + 151, p1.y + 38); break; // 押し下げ成功 } bmp.Dispose(); bmp = null; //// ウィンドウを元に戻す ShowWindow(hXSplitWnd, SW_RESTORE); // アクティブにする SetForegroundWindow(hXSplitWnd); System.Threading.Thread.Sleep(500); // クライアント領域を再取得 GetClientRect(hXSplitWnd, ref clientrect); p1.x = clientrect.left; p1.y = clientrect.top; p2.x = clientrect.right; p2.y = clientrect.bottom; //クライアント領域座標をスクリーン座標に変換 ClientToScreen(hXSplitWnd, ref p1); ClientToScreen(hXSplitWnd, ref p2); //取り込む座標を矩形領域に設定 iRect = new Rectangle(p1.x, p1.y, p2.x - p1.x + 1, p2.y - p1.y + 1); } } } System.Threading.Thread.Sleep(2000); // ウインドウを最小化する if (original_iconic) { ShowWindow(hXSplitWnd, SW_MINIMIZE); } else { Thread th = new Thread(delegate() { Thread.Sleep(5000); mainForm.Invoke((Action)delegate() { mainForm.Activate(); }); //if (hAfterWnd != null && hAfterWnd != (IntPtr)(-1) && hAfterWnd != (IntPtr)(-2)) //{ // SetWindowPos(hXSplitWnd, hAfterWnd, 0, 0, 0, 0, SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE); //} }); th.Start(); } }
//------------------------------------------------------------------------- // タイマー //------------------------------------------------------------------------- private void UITimer_Tick(object sender, EventArgs e) { Properties.Settings.Default.last_lv = this.mLiveID.Text; // フォントを設定しておく if (this.mCommentList.Font.Size != Properties.Settings.Default.font_size) { Utils.SetCommentFont(ref mCommentList); } // 色設定 if (mCommentList.RowsDefaultCellStyle.BackColor != Properties.Settings.Default.back_color) { mCommentList.RowsDefaultCellStyle.BackColor = Properties.Settings.Default.back_color; mCommentList.BackgroundColor = Properties.Settings.Default.back_color; } if (mCommentList.RowsDefaultCellStyle.ForeColor != Properties.Settings.Default.text_color) { mCommentList.RowsDefaultCellStyle.ForeColor = Properties.Settings.Default.text_color; } // ログイン状態更新 UpdateLogin(); // ユニークユーザー数更新 UpdateUniq(); // アクティブ数更新 UpdateActive(); // 外部コメントウィンド this.Invoke((Action)delegate() { // 経過時間 long resttime = 0; if (mNico != null && mNico.IsLogin && !mNico.WakutoriMode) { resttime = mLiveInfo.Time - mLiveInfo.StartTime + (Utils.GetUnixTime(DateTime.Now) - mLiveInfo.UnixTime); } if (resttime > 60 * 60 * 48) resttime = 0; long min = resttime / 60; long sec = resttime - min * 60; long hour = min / 60; min -= hour * 60; mCommentForm.RestTime = (hour > 0 ? hour + ":" : "") + ((hour > 0 && min < 10) ? "0" : "") + min + ":" + (sec < 10 ? ("0" + sec) : sec.ToString()); // 残り時間 resttime = 0; if (mNico != null && mNico.IsLogin && !mNico.WakutoriMode) { resttime = mLiveInfo.EndTime - mLiveInfo.Time - (Utils.GetUnixTime(DateTime.Now) - mLiveInfo.UnixTime); } if (resttime < 180) { mCommentForm.RestTimeForeColor = System.Drawing.Color.Red; } else { mCommentForm.RestTimeForeColor = System.Drawing.Color.Black; } mCommentForm.ActiveCnt = mActiveCnt.Text; mCommentForm.TotalCnt = mTotalCnt.Text; mCommentForm.UniqCnt = mUniqCnt.Text; mCommentForm.UpLink = mUpLink.Text; mCommentForm.UpLinkForColor = mUpLink.ForeColor; mCommentForm.Battery = mBattery.Text; mCommentForm.CpuInfo = mCpuInfo.Text; }); // FMEステータス更新 bool nowFME = FMLE.hasFME(); if (mLastFME != nowFME) { if (!nowFME) { using (Bouyomi bm = new Bouyomi()) { if (Properties.Settings.Default.use_xsplit) { bm.Talk("エックスプリット、停止を確認"); } else if (Properties.Settings.Default.use_NLE) { bm.Talk("にこにこライブエンコーダ、停止を確認"); } else { bm.Talk("えふえむいー停止を確認"); } } } else { using (Bouyomi bm = new Bouyomi()) { if (Properties.Settings.Default.use_NLE) { bm.Talk("にこにこライブエンコーダ、接続を確認"); } } } } mLastFME = nowFME; // コメントサーバーとの接続キープ用 if (mNico != null && mNico.IsLogin && !mDisconnect && !mNico.WakutoriMode) { TimeSpan ts = DateTime.Now - this.mLastChatTime; if (ts.Minutes > KEEP_ALIVE_TIME) { SendComment("/keepalive", true); mLastChatTime = DateTime.Now; } // FME 配信設定告知 if (FMLE.FMEsettingExist && FMLE.hasFME()) { if (Properties.Settings.Default.show_fme_setting) { SendComment(FMLE.FMEsetting, true); } FMLE.FMEsettingExist = false; } // FME ラグ対策 COMPACT_TIME = Properties.Settings.Default.sekigaeMinutes; ts = DateTime.Now - this.mLastCompctTime; // 席替え予告 if (!mCompactForcast && ts.Add(TimeSpan.FromSeconds(15)).Minutes >= COMPACT_TIME) { mCompactForcast = true; if (Properties.Settings.Default.fme_compact) { SendComment("ラグ対策のため,15秒後にリロードを実施します", true); } } // 席替え実施 if (ts.Minutes >= COMPACT_TIME) { if (Properties.Settings.Default.fme_compact) { SendComment("/reset", true); } mLastCompctTime = DateTime.Now; mCompactForcast = false; } } }
//------------------------------------------------------------------------- // ステータス更新 //------------------------------------------------------------------------- private void UpdateStatus() { this.mEnableLabel.Text = (this.mEnableBtn.Checked) ? "自動枠取り動作中" : "自動枠取り待機中"; this.mEnableLabel.ForeColor = (this.mEnableBtn.Checked) ? Color.Red : Color.Black; if (this.mBrowser.Url != null && this.mBrowser.Url.ToString().StartsWith(EDIT_URL)) { this.mEnableBtn.Enabled = true; } else { this.mEnableBtn.Enabled = false; } if (mBrowser.Url != null /*&& this.mEnableBtn.Checked*/ ) { string uri = mBrowser.Url.ToString(); if (uri.StartsWith(WATCH_URL)) { // 枠取り成功 SystemSounds.Beep.Play(); int idx = uri.IndexOf("lv"); uri = uri.Substring(idx); using (Bouyomi bm = new Bouyomi()) { bm.Talk(mMsg.GetMessage("枠が取れたよ")); } // 接続 this.Invoke((MethodInvoker)delegate() { this.mOwner.LiveID = uri; this.mOwner.Connect(false); }); this.mUITimer.Enabled = false; try { this.Hide(); this.Close(); } catch (Exception e) { Console.WriteLine("Close:"+e.Message); } } // 2012.05.12 順番待ちの表示に無理矢理移行するため。 else if (uri.StartsWith(MY_URL)) { HtmlElementCollection all = this.mBrowser.Document.All; foreach (HtmlElement elem in all) { // [番組情報を編集する]クリック if (elem.GetAttribute("title") == "番組情報を編集する" && mAutoWakumachi) { if (!mWakumachiClick) { elem.InvokeMember("click"); mWakumachiClick = true; } return; } // [生放送ページへ戻る]クリック else if (elem.GetAttribute("title") == "生放送ページへ戻る" && (this.mEnableBtn.Checked || mAutoWakumachi)) { if (!mWakumachiClick) { elem.InvokeMember("click"); mWakumachiClick = true; } return; } } } else if (uri.StartsWith(EDIT_URL)) { if (this.mBrowser.Document.GetElementById("res_done") != null) { HtmlElementCollection all = this.mBrowser.Document.All; HtmlElementCollection elem = all.GetElementsByName("blog_parts"); if (elem.Count > 0) { string val = elem[0].GetAttribute("value"); int idx1 = val.IndexOf("lv"); Debug.WriteLine(val); if (idx1 > 0) { int idx2 = val.IndexOf("\"", idx1); if (idx2 > 0) { string lv = val.Substring(idx1, idx2 - idx1); Debug.WriteLine(lv); this.Invoke((MethodInvoker)delegate() { this.mOwner.LiveID = lv; this.mOwner.Connect(false); }); this.mUITimer.Enabled = false; try { this.Hide(); this.Close(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } } } } } }
//------------------------------------------- // process をスタート //------------------------------------------- public static bool Start(Dictionary<string, string> iParams) { try { // 現在、動作しているプロセスをすべてコロ助 Kill(); // プロセスをスタートさせる // プロファイルのパス string profile_path = Path.GetTempPath() + "nicovideo_fme.xml"; // FlashMediaEncoderのパス string path = Properties.Settings.Default.fmle_path.Replace("FMLECmd", "FlashMediaLiveEncoder"); // プロファイル作成 if (!FMLE.MakeProfile(profile_path, iParams)) { mFMEStarted = false; return false; } // FMLECmd起動 string args = " /g /p \"" + profile_path + "\""; mFMEprocess = System.Diagnostics.Process.Start(path, args); // ウインドウハンドルが生成されるまで待つ mFMEprocess.WaitForInputIdle(); // 立ち上がるのを待つ using (Bouyomi bm = new Bouyomi()) { bm.Talk("えふえむいー起動中です"); } System.Threading.Thread.Sleep(8000); return PushStart(); } catch (Exception e) { Console.WriteLine(e.ToString()); return false; } }
//------------------------------------------- // PushStart //------------------------------------------- public static bool PushStart() { const int padding = 10; const int padding2 = 10; mFMEStarted = false; // プロセスが確保されていなければ、リターン if (mFMEprocess == null) { return false; } // プロセスが存在しても、終了していれば、リターン if (mFMEprocess.HasExited) { return false; } // ウインドウのサイズをあわせる FitWindowSize(); RECT clientrect = new RECT(); // クライアント領域のスクリーンをキャプチャする Bitmap bmp=null; bool bStartPushed = false; bool bStartComplete = false; using (ScreenCapture scr = new ScreenCapture()) { int i; Point outPos = new Point(); Point start_offs = new Point(417, 512); Point stop_offs = new Point(556, 512); Point ng_offs = new Point(489, 357); // スタートボタンを探して押す for (i = 0; i < 60; i++) { // ウインドウをフォアグラウンドに SetForegroundWindow(m_fme_hwnd); // アクティブにする // クライアント領域のサイズを取得 GetClientRect(m_fme_hwnd, ref clientrect); POINT p1, p2; p1.x = clientrect.left; p1.y = clientrect.top; p2.x = clientrect.right; p2.y = clientrect.bottom; //クライアント領域座標をスクリーン座標に変換 ClientToScreen(m_fme_hwnd, ref p1); ClientToScreen(m_fme_hwnd, ref p2); // クライアント領域のレクトアングルを設定 Rectangle iRect = new Rectangle(p1.x, p1.y, p2.x - p1.x + 1, p2.y - p1.y + 1); bmp = scr.Capture(iRect); if (ContainBitmap(mStartBmp, bmp, start_offs.X - padding2, start_offs.Y - padding, start_offs.X + padding2, start_offs.Y + padding, ref outPos, 5)) { MouseClick(p1.x + outPos.X + 18, p1.y + outPos.Y + 14); bStartPushed = true; // 立ち上がるのを待つ using (Bouyomi bm = new Bouyomi()) { bm.Talk("スタートボタン、プッシュ"); } break; } bmp.Dispose(); bmp = null; FitWindowSize(); // 0.5[s] wait System.Threading.Thread.Sleep(500); } // スタートボタンが押せなかった場合 if (!bStartPushed) { if (bmp != null) { bmp.Dispose(); bmp = null; } // 立ち上がるのを待つ using (Bouyomi bm = new Bouyomi()) { bm.Talk("スタートボタンを代わりに押してください"); } } // スタートできたかのチェック for (i = 0; i < 40; i++) { // ウインドウをフォアグラウンドに SetForegroundWindow(m_fme_hwnd); // アクティブにする GetClientRect(m_fme_hwnd, ref clientrect); POINT p1, p2; p1.x = clientrect.left; p1.y = clientrect.top; p2.x = clientrect.right; p2.y = clientrect.bottom; //クライアント領域座標をスクリーン座標に変換 ClientToScreen(m_fme_hwnd, ref p1); ClientToScreen(m_fme_hwnd, ref p2); Rectangle iRect = new Rectangle(p1.x, p1.y, p2.x - p1.x + 1, p2.y - p1.y + 1); bmp = scr.Capture(iRect); // Stop が押せるようになれば、とりあえず成功判定 if (ContainBitmap(mStopBmp, bmp, stop_offs.X - padding2, stop_offs.Y - padding, stop_offs.X + padding2, stop_offs.Y + padding, ref outPos, 5)) { // 立ち上がるのを待つ using (Bouyomi bm = new Bouyomi()) { bm.Talk("ストップボタン、点灯確認"); } bStartComplete = true; mFMEStarted = true; bmp.Dispose(); bmp = null; break; } // NGダイアログが出てきたら、NG判定 if (ContainBitmap(mNgBmp, bmp, ng_offs.X - padding2, ng_offs.Y - padding, ng_offs.X + padding2, ng_offs.Y + padding, ref outPos, 5)) { MouseClick(p1.x + outPos.X + 10, p1.y + outPos.Y + 10); if (bmp != null) { bmp.Dispose(); bmp = null; } // NG ダイアログが消えるのを待つ int j; for (j = 0; j < 10; j++) { GetClientRect(m_fme_hwnd, ref clientrect); p1.x = clientrect.left; p1.y = clientrect.top; p2.x = clientrect.right; p2.y = clientrect.bottom; //クライアント領域座標をスクリーン座標に変換 ClientToScreen(m_fme_hwnd, ref p1); ClientToScreen(m_fme_hwnd, ref p2); iRect = new Rectangle(p1.x, p1.y, p2.x - p1.x + 1, p2.y - p1.y + 1); bmp = scr.Capture(iRect); if (!ContainBitmap(mNgBmp, bmp, ng_offs.X - padding2, ng_offs.Y - padding, ng_offs.X + padding2, ng_offs.Y + padding, ref outPos, 5)) { if (bmp != null) { bmp.Dispose(); bmp = null; } break; } // 0.5[s] wait System.Threading.Thread.Sleep(500); } break; } if (bmp != null) { bmp.Dispose(); bmp = null; } // 0.5[s] wait FitWindowSize(); System.Threading.Thread.Sleep(500); } } //// Start領域 //iRect = new Rectangle(p1.x+417, p1.y+512, 36, 28); //bmp = scr.Capture(iRect); //filePath = @"F:\FMEstart.bmp"; //bmp.Save(filePath, ImageFormat.Bmp); //// Stop領域 //iRect = new Rectangle(p1.x + 556, p1.y + 512, 34, 28); //bmp = scr.Capture(iRect); //filePath = @"F:\FMEstop.bmp"; //bmp.Save(filePath, ImageFormat.Bmp); //// NG領域 //iRect = new Rectangle(p1.x + 489, p1.y + 357, 21, 19); //bmp = scr.Capture(iRect); //filePath = @"F:\FMEng.bmp"; //bmp.Save(filePath, ImageFormat.Bmp); //filePath = @"F:\screen.bmp"; //Process.Start(filePath); //一秒間(1000ミリ秒)停止する System.Threading.Thread.Sleep(2000); if (bStartComplete) { using (Bouyomi bm = new Bouyomi()) { bm.Talk("えふえむいー配信を開始しました"); } } else { using (Bouyomi bm = new Bouyomi()) { bm.Talk("えふえむいー起動失敗しました"); } FMEGUI.Kill(); } // ウインドウを最小化する ShowWindow(m_fme_hwnd, SW_MINIMIZE); return bStartComplete; }
//------------------------------------------------------------------------- // FMEをすべてコロ助 //------------------------------------------------------------------------- public static bool Kill() { Process[] ps = Process.GetProcessesByName("FlashMediaLiveEncoder"); if (ps.Length > 0) { foreach (System.Diagnostics.Process p in ps) { p.Kill(); } using (Bouyomi bm = new Bouyomi()) { bm.Talk("えふえむいー配信を停止しました"); } } // すべてのFMEがいなくなったことを確認する do { System.Threading.Thread.Sleep(1000); ps = Process.GetProcessesByName("FlashMediaLiveEncoder"); } while (ps.Length > 0); // セッションファイルを殺す FMLE.DeleteSessionfile(); if (mFMEprocess != null) { mFMEprocess.Close(); mFMEprocess = null; } mFMEStarted = false; return (ps.Length > 0); }