public void Run() { try { SleepState.Stop(true); this.sql = new Sql(true); this.tuner.Open(false); bool flag = false; while (!flag) { Service service = this.epgQueue.Dequeue(this.tuner); if (service == null) { Log.Write(this.tuner.Name + ": このチューナの番組表取得完了。"); break; } int wait = EpgWait.GetInstance().GetWait(service.Nid); Log.Write("{4}: 番組表を取得しています... {1} ({0}/{3}/{2}s)".Formatex(new object[] { this.epgQueue.Count, service.Name, wait, service.EpgBasic ? "基本" : "詳細", this.tuner.Name })); this.tuner.SetService(service); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); while (stopwatch.ElapsedMilliseconds < (long)(wait * 1000)) { Record nextRecord = Record.GetNextRecord(this.tuner, this.sql); flag = (this.StoppdApp() || !this.epgQueue.Enable || nextRecord != null); if (flag) { Log.Write(this.tuner.Name + ": 中断しました。" + service.Name); break; } Thread.Sleep(1000); } this.GetEvents(service); } } catch (Exception ex) { Log.Write(this.tuner.Name + ": 番組表取得に失敗しました。" + ex.Message); Log.Write(1, ex.StackTrace); } finally { try { this.sql.Dispose(); this.tuner.Close(); } catch { } SleepState.Stop(false); } }
//キューをクリア public void Clear() { lock (list) { list.Clear(); SleepState.SetSleepStop(false); } }
private static void SetState(bool stop) { if (stop) { SleepState.SetThreadExecutionState((SleepState.ExecutionState) 2147483649u); return; } SleepState.SetThreadExecutionState((SleepState.ExecutionState) 2147483648u); }
//■ダミーTVTest起動&終了 void StartRec_pre(Sql sql, Record rec, Tuner tuner) { var result = new Result(); var tsStatus = new TsStatus(); try { Log.Write(tuner.Name + ": ダミーTVTestを起動します。" + rec.Title); SleepState.SetSleepStop(true); tuner.Open(); var service = new Service(sql, rec.Fsid); tuner.SetService(service); Thread.Sleep(1000 * 12); //12秒視聴 } catch (Exception e) { result.Code = 1; result.Message = e.Message; throw; } finally { try { if (tuner != null) { tuner.Close(); } } catch (Exception e) { Log.Write("ダミーTVTest終了中エラーが発生しました。[詳細] " + e.Message); TVTest_ForceStop(); //エラーが起こった場合は強制終了 } try { SleepState.SetSleepStop(false); } catch (Exception e) { Log.Write("ダミーTVTest終了中エラーが発生しました2。[詳細] " + e.Message); } Log.Write(tuner.Name + ": ダミーTVTestを終了しました。" + rec.Title); } }
private void Tick(object sender, EventArgs e) { if (SleepState.IsStop()) { return; } EpgQueue epgQueue = RecTimer.GetInstance().GetEpgQueue(); if (epgQueue.Enable && epgQueue.Count > 0) { return; } if (this.GetNextTime() - DateTime.Now > new TimeSpan(0, 10, 0)) { this.Sleep(); } }
//チューナで使用可能なサービスを取り出す public Service Dequ(Tuner tuner) { lock (list) { if (list.Count == 0) { return(null); } //ドライバで検索 Service service = null; foreach (var s in list) { if (s.Driver == tuner.Driver) { service = s; break; } else if (s.Driver == tuner.DriverId) //番兵かどうか { //番兵を削除する list.RemoveAll(sv => sv.Driver == tuner.DriverId); break; } } //取り出したサービスをキューから削除 if (service != null) { //チューナが複数ある場合、同じサービスが複数含まれているためRemoveAll list.RemoveAll(s => s.Fsid == service.Fsid); } //削除の結果キューが0になったらスリープ抑止を解除 if (list.Count == 0) { SleepState.SetSleepStop(false); } return(service); } }
//キューにサービスリストを入れる public void Enqu() { lock (list) { if (list.Count > 0) { return; } SleepState.SetSleepStop(true); //スリープを抑止 using (var sql = new Sql(true)) { sql.Text = "select * from service id order by id"; using (var t = sql.GetTable()) { while (t.Read()) { list.Add(new Service(t)); } } //番兵をチューナ毎に入れる //番組表取得終了を確認するために使用(番兵が全て取り出されたら終了と判断) //Service.DriverにDriverIdを入れる sql.Text = "select * from tuner"; using (var t = sql.GetTable()) { while (t.Read()) { var tuner = new Tuner(t); var s = new Service(); s.Id = -1; s.Fsid = 0; s.Driver = tuner.DriverId; list.Add(s); } } } } }
public static void SetSleepStop(bool stop) { lock (lockObj) { if (stop) { sleepStopCount++; if (sleepStopCount == 1) { //Log.Write("スリープ抑止をセット"); SleepState.SetState(true); } } else { sleepStopCount--; if (sleepStopCount == 0) { SleepState.SetState(false); //Log.Write("スリープ抑止を解除"); } } } }
public static void Stop(bool flug) { object obj = SleepState.lockObj; lock (obj) { if (flug) { SleepState.count++; if (SleepState.count == 1) { SleepState.SetState(true); } } else { SleepState.count--; if (SleepState.count == 0) { SleepState.SetState(false); } } } }
public void Run() { try { SleepState.Stop(true); this.sql = new Sql(true); this.service = new Service(this.sql, this.record.Fsid); Log.Write(this.tuner.Name + ": 録画を開始します。" + this.record.Title); this.StartRec(); if (this.record.EndTime < DateTime.Now) { throw new Exception("終了時刻が過ぎています。"); } int @int = MainDef.GetInstance().GetInt("record.margin.end"); while (this.record.EndTime - new TimeSpan(0, 0, @int) > DateTime.Now) { if (this.StoppdApp()) { throw new Exception("アプリケーション終了のため、録画を中断します。"); } this.CheckCancel(); this.CheckEvent(); Thread.Sleep(1000); } } catch (Exception ex) { string text = "{0}: 録画に失敗しました。{1}".Formatex(new object[] { this.tuner.Name, ex.Message }); Log.Write(text + " - " + this.record.Title); Log.Write(1, ex.StackTrace); if (this.result != null) { this.result.Code = 1; this.result.Message = text; } } finally { try { this.StopRec(); } catch (Exception ex2) { Log.Write("{0}: 録画終了処理に失敗しました。{1}".Formatex(new object[] { this.tuner.Name, ex2.Message })); Log.Write(1, ex2.StackTrace); } SleepState.Stop(false); this.sql.Dispose(); Log.Write("{0}: 録画終了しました。 - {1}".Formatex(new object[] { this.tuner.Name, this.record.Title })); this.PostProcess(); } }
//録画開始 void StartRec(Sql sql, Record rec, Tuner tuner, long retry_times) //修正 { var result = new Result(); var tsStatus = new TsStatus(); var recContinue = false; //録画継続フラグ(録画時間変更に使用) var path = ""; //■追加 try { //Log.Write(tuner.Name + ": 録画を開始します。" + rec.Title); //■削除 Log.Write(tuner.Name + ": 録画準備をしています。" + rec.Title); //■追加 SleepState.SetSleepStop(true); rec.SetRecoding(sql, true); //■メモ ここで今録画中だとフラグをセットしている tuner.Open(); var service = new Service(sql, rec.Fsid); tuner.SetService(service); //string file = ConvertFileMacro(rec, Program.UserDef["record.file"]); //■削除 string file = ConvertFileMacro(rec, Program.UserDef["record.file"], service.Name); //■追加 //var path = System.IO.Path.Combine(Program.UserDef["record.folder"], file); //■削除 path = System.IO.Path.Combine(Program.UserDef["record.folder"], file); //■追加 path = CheckFilePath(path); //■追加 きっちり時間が来るまで待機 int seconds_prev = Program.UserDef["record.margin.start"].ToInt(); while (DateTime.Now < rec.StartTime + new TimeSpan(0, 0, seconds_prev)) { Thread.Sleep(0); } Log.Write(tuner.Name + ": 録画を開始します。" + rec.Title); tuner.StartRec(path); result.Title = rec.Title; result.ServiceName = service.Name; result.File = Path.GetFileName(path); result.SchStart = rec.StartTime; result.SchEnd = rec.EndTime; result.Start = DateTime.Now; var eventTimeError = false; //番組時間取得エラーフラグ int margin = Program.UserDef["record.margin.end"].ToInt(); while (DateTime.Now < rec.EndTime + new TimeSpan(0, 0, margin)) { if (stop) { throw new AppException(tuner.Name + ": アプリケーション終了のため、録画を中断します。"); } //現在の予約が有効かどうか確認 sql.Text = "select status from record where id = " + rec.Id; object status = sql.GetData(); if (status == null) //予約が取り消された { throw new AppException(tuner.Name + ": 予約が取り消されたため、録画を中断します。"); } else if (((int)(long)status & (int)Record.RecStatus.Enable) == 0) //予約が無効にされた { throw new AppException(tuner.Name + ": 予約が無効にされたため、録画を中断します。"); } //追従モード if ((rec.Status & (int)Record.RecStatus.EventMode) > 0) { //番組の時間に変更がないか確認 Event ev = null; try { ev = tuner.GetEventTime(service, rec.Eid); eventTimeError = false; //エラーフラグをリセット } catch { if (eventTimeError == false) //何度もエラーが表示されないようにする { Log.Write(tuner.Name + ": 番組時間の取得に失敗しました。番組がなくなった可能性があります。録画は続行します。" + rec.Title); eventTimeError = true; } } if (ev != null) { if (ev.Start != rec.StartTime || ev.Duration != rec.Duration) { Log.Write(tuner.Name + ": 番組時間が変更されました。" + rec.Title); //予約を変更 rec.StartTime = ev.Start; rec.Duration = ev.Duration; tuner.GetEvents(sql, service); //番組表を更新する UpdateRecordTime(sql, service); //予約を更新 //番組開始が、現時刻より1分以上後に変更された場合、一旦録画を終了する if (rec.StartTime - DateTime.Now > TimeSpan.FromMinutes(1)) { recContinue = true; throw new AppException(tuner.Name + ": 番組の開始時間が遅れているため、録画を中断します。"); } } } } if (tuner.GetState() != Tuner.State.Recoding) { throw new AppException(tuner.Name + ": 録画が中断しました。"); } tsStatus = tuner.GetTsStatus(); Thread.Sleep(recSleep); } if (eventTimeError) { result.Code = 1; result.Message = "番組時間の取得に失敗しました。録画は続行しました。"; } } catch (Exception e) { result.Code = 1; result.Message = e.Message; throw; } finally { if (retry_times < 2 && result.Message.IndexOf("TVTestでエラーが発生しました。エラーコード: 6") >= 0) { //■チャンネル変更エラーで終了した場合(2回目まで) try { Log.Write(tuner.Name + ": チャンネル変更に失敗しました。リトライします。" + result.Message); //録画開始前の状態に戻す rec.SetRecoding(sql, false); //チューナーを閉じる try { if (tuner != null) { tuner.Close(); } } catch (Exception ex9) { Log.Write("チューナー終了中エラーが発生しました(6)。[詳細] " + ex9.Message); TVTest_ForceStop(); //強制終了 } SleepState.SetSleepStop(false); } catch (Exception e) { Log.Write("チャンネル変更失敗時のエラー処理中にエラーが発生しました。[詳細] " + e.Message); } } else { //■修正 録画を終了させる try { if (tuner != null) { tuner.StopRec(); //■削除 tuner.Close(); } } catch (Exception e) { Log.Write("録画終了中エラーが発生しました。[詳細] " + e.Message); } //■追加 チューナーを閉じる try { if (tuner != null) { tuner.Close(); } } catch (Exception ex9) { Log.Write("チューナー終了中エラーが発生しました。[詳細] " + ex9.Message); TVTest_ForceStop(); //強制終了 } try { if (recContinue) { rec.SetRecoding(sql, false); //■メモ 前番組の延長により放送時間が変更になった場合 } else { rec.SetComplete(sql); } SleepState.SetSleepStop(false); result.Error = tsStatus.Error; result.Drop = tsStatus.Drop; result.Scramble = tsStatus.Scramble; result.End = DateTime.Now; result.Add(sql); } catch (Exception e) { Log.Write("録画終了中エラーが発生しました。[詳細] " + e.Message); } Log.Write(tuner.Name + ": 録画が終了しました。" + rec.Title); } } //■録画後処理 録画が正常終了した場合のみ実行される try { if (Program.UserDef["exe1"].Length > 0) { Thread.Sleep(rec.Title.Length); //少々ばらつきを持たせるか・・ Thread t = new Thread(new ParameterizedThreadStart(Execute_exe)); string path2 = Path.GetDirectoryName(path); if (path2.Length > 0) { path2 = path2 + "\\"; } t.Start(path2 + result.File); } } catch { //実行するコマンドが無い。Program.UserDef["exe1"]が存在しなかった } }