//キューをクリア public void Clear() { lock (list) { list.Clear(); SleepState.SetSleepStop(false); } }
//■ダミー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); } }
//チューナで使用可能なサービスを取り出す 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); } } } } }
//録画開始 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"]が存在しなかった } }