// 失敗するとIOExceptionが飛ぶ public async Task Analyze(string filepath, int serviceid, string workpath, Point pt, Size sz, int thy, int maxFrames) { int pid = System.Diagnostics.Process.GetCurrentProcess().Id; string workfile = workpath + "\\logotmp" + pid + ".dat"; string tmppath = workpath + "\\logotmp" + pid + ".lgd"; // 2の倍数にする int imgx = (int)Math.Floor(pt.X / 2) * 2; int imgy = (int)Math.Floor(pt.Y / 2) * 2; int w = (int)Math.Ceiling(sz.Width / 2) * 2; int h = (int)Math.Ceiling(sz.Height / 2) * 2; NowScanning = true; CancelScanning = false; ClearLogo(); try { await Task.Run(() => LogoFile.ScanLogo( context, filepath, serviceid, workfile, tmppath, imgx, imgy, w, h, thy, maxFrames, LogoScanCallback)); // TsInfoでサービス名を取得する using (var info = new TsInfo(context)) { if (info.ReadFile(filepath) == false) { MessageBox.Show("TS情報取得に失敗: " + context.GetError()); } else { // 名前を修正して保存し直す using (var logo = new LogoFile(context, tmppath)) { if (info.HasServiceInfo) { int serviceId = logo.ServiceId; string serviceName = info.GetServiceList().First(s => s.ServiceId == serviceId).ServiceName; string date = info.GetTime().ToString("yyyy-MM-dd"); logo.Name = serviceName + "(" + date + ")"; } else { logo.Name = "情報なし"; } logopath = workpath + "\\logo" + pid + ".lgd"; logo.Save(logopath); } Logo = new LogoFile(context, logopath); UpdateLogoImage(); } } } finally { if (File.Exists(workfile)) { File.Delete(workfile); } if (File.Exists(tmppath)) { File.Delete(tmppath); } NowScanning = false; } }
public async Task AddQueue(AddQueueRequest req) { List <Task> waits = new List <Task>(); addQueueCanceled = false; // ユーザ操作でない場合はログを記録する bool enableLog = (req.Mode == ProcMode.AutoBatch); if (req.Outputs.Count == 0) { await server.NotifyError("出力が1つもありません", enableLog); return; } // 既に追加されているファイルは除外する // バッチのときは全ファイルが対象だが、バッチじゃなければバッチのみが対象 var ignores = req.IsBatch ? Queue : Queue.Where(t => t.IsBatch); var ignoreSet = new HashSet <string>( ignores.Where(item => item.IsActive) .Select(item => item.SrcPath)); var items = ((req.Targets != null) ? req.Targets : Directory.GetFiles(req.DirPath) .Where(s => { string lower = s.ToLower(); return(lower.EndsWith(".ts") || lower.EndsWith(".m2t")); }) .Select(f => new AddQueueItem() { Path = f })) .Where(f => !ignoreSet.Contains(f.Path)).ToList(); waits.Add(WriteLine("" + items.Count + "件を追加処理します")); var map = server.ServiceMap; var numItems = 0; var progress = 0; // TSファイル情報を読む foreach (var additem in items) { waits.Add(WriteLine("(" + (++progress) + "/" + items.Count + ") " + Path.GetFileName(additem.Path) + " を処理中")); using (var info = new TsInfo(amtcontext)) { var failReason = ""; var addItems = new List <QueueItem>(); if (await Task.Run(() => info.ReadFile(additem.Path)) == false) { failReason = "TS情報取得に失敗: " + amtcontext.GetError(); } else { failReason = "TSファイルに映像が見つかりませんでした"; var list = info.GetProgramList(); var videopids = new List <int>(); int numFiles = 0; for (int i = 0; i < list.Length; ++i) { var prog = list[i]; if (prog.HasVideo && videopids.Contains(prog.VideoPid) == false) { videopids.Add(prog.VideoPid); var serviceName = "不明"; var tsTime = DateTime.MinValue; if (info.HasServiceInfo) { var service = info.GetServiceList().Where(s => s.ServiceId == prog.ServiceId).FirstOrDefault(); if (service.ServiceId != 0) { serviceName = service.ServiceName; } tsTime = info.GetTime(); } var outname = Path.GetFileNameWithoutExtension(additem.Path); if (numFiles > 0) { outname += "-マルチ" + numFiles; } Debug.Print("解析完了: " + additem.Path); foreach (var outitem in req.Outputs) { var genre = prog.Content.Select(s => ServerSupport.GetGenre(s)).ToList(); var item = new QueueItem() { Id = nextItemId++, Mode = req.Mode, SrcPath = additem.Path, Hash = additem.Hash, DstPath = outitem.DstPath + "\\" + outname, ServiceId = prog.ServiceId, ImageWidth = prog.Width, ImageHeight = prog.Height, TsTime = tsTime, ServiceName = serviceName, EventName = prog.EventName, State = QueueState.LogoPending, Priority = outitem.Priority, AddTime = DateTime.Now, ProfileName = outitem.Profile, Genre = genre, Tags = new List <string>() }; if (item.IsOneSeg) { item.State = QueueState.PreFailed; item.FailReason = "映像が小さすぎます(" + prog.Width + "," + prog.Height + ")"; } else { // ロゴファイルを探す if (req.Mode != ProcMode.DrcsCheck && map.ContainsKey(item.ServiceId) == false) { // 新しいサービスを登録 waits.Add(server.AddService(new ServiceSettingElement() { ServiceId = item.ServiceId, ServiceName = item.ServiceName, LogoSettings = new List <LogoSetting>() })); } // 追加時バッチ if (string.IsNullOrEmpty(req.AddQueueBat) == false) { waits.Add(WriteLine("追加時バッチ起動")); using (var scriptExecuter = new UserScriptExecuter() { Server = server, Phase = ScriptPhase.OnAdd, ScriptPath = server.GetBatDirectoryPath() + "\\" + req.AddQueueBat, Item = item, Prog = prog, OnOutput = WriteTextBytes }) { process = scriptExecuter; await scriptExecuter.Execute(); process = null; } if (addQueueCanceled) { break; } } ++numFiles; } addItems.Add(item); } } } } if (addQueueCanceled) { break; } if (addItems.Count == 0) { // アイテムが1つもないときはエラー項目として追加 foreach (var outitem in req.Outputs) { bool isAuto = false; var profileName = ServerSupport.ParseProfileName(outitem.Profile, out isAuto); var profile = isAuto ? null : ServerSupport.DeepCopy(server.GetProfile(profileName)); var item = new QueueItem() { Id = nextItemId++, Mode = req.Mode, Profile = profile, SrcPath = additem.Path, Hash = additem.Hash, DstPath = "", ServiceId = -1, ImageWidth = -1, ImageHeight = -1, TsTime = DateTime.MinValue, ServiceName = "不明", State = QueueState.PreFailed, FailReason = failReason, AddTime = DateTime.Now, ProfileName = outitem.Profile, Tags = new List <string>() }; addItems.Add(item); } } // 1ソースファイルに対するaddはatomicに実行したいので、 // このループではawaitしないこと foreach (var item in addItems) { if (item.State != QueueState.PreFailed) { // プロファイルを設定 UpdateProfileItem(item, null); } // 追加 item.Order = Queue.Count; Queue.Add(item); // まずは内部だけで状態を更新 UpdateQueueItem(item, null); // 状態が決まったらクライアント側に追加通知 waits.Add(ClientQueueUpdate(new QueueUpdate() { Type = UpdateType.Add, Item = item })); } numItems += addItems.Count; UpdateProgress(); waits.Add(server.RequestState()); } if (addQueueCanceled) { break; } } if (addQueueCanceled) { waits.Add(WriteLine("キャンセルされました")); } waits.Add(WriteLine("" + numItems + "件追加しました")); if (addQueueCanceled == false && numItems == 0) { waits.Add(server.NotifyError( "エンコード対象ファイルがありませんでした。パス:" + req.DirPath, enableLog)); await Task.WhenAll(waits); return; } else { waits.Add(server.NotifyMessage("" + numItems + "件追加しました", false)); } if (req.Mode != ProcMode.AutoBatch) { // 最後に使った設定を記憶しておく server.LastUsedProfile = req.Outputs[0].Profile; server.AddOutPathHistory(req.Outputs[0].DstPath); server.LastAddQueueBat = req.AddQueueBat; waits.Add(server.RequestUIState()); } waits.Add(server.RequestFreeSpace()); await Task.WhenAll(waits); }