private async Task Send(RPCMethodId id, AddQueueRequest obj) { if (client != null) { var data = new List <byte[]>(); var ms = new MemoryStream(); var serializer = new DataContractSerializer(typeof(AddQueueRequest)); serializer.WriteObject(ms, obj); data.Add(ms.ToArray()); var objbyes = RPCData.CombineChunks(data); byte[] bytes = RPCData.Combine( BitConverter.GetBytes((short)id), BitConverter.GetBytes(objbyes.Length), objbyes); await client.GetStream().WriteAsync(bytes, 0, bytes.Length); } }
public Task AddQueue(AddQueueRequest dir) { return(Send(RPCMethodId.AddQueue, dir)); }
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); }
public Task AddQueue(AddQueueRequest dir) { return(Server.AddQueue(Copy(dir))); }