private void LoadJobs() { lock (Util.JobFileLock) { List <IVideoJob> jobs = new List <IVideoJob>(); try { XmlDocument doc = new XmlDocument(); using (FileStream fs = System.IO.File.OpenRead(Util.VodXmlPath)) { if (fs.PeekUInt16() == 0x8B1F) { using (System.IO.Compression.GZipStream gzs = new System.IO.Compression.GZipStream(fs, System.IO.Compression.CompressionMode.Decompress)) { doc.Load(gzs); } } else { doc.Load(fs); } } foreach (XmlNode node in doc.SelectNodes("//root/Job")) { IVideoJob job = IVideoJob.Deserialize(node); if (job != null) { if (job.JobStatus == VideoJobStatus.Running) { job.JobStatus = VideoJobStatus.NotStarted; job.StatusUpdater = new StatusUpdate.NullStatusUpdate(); job.Status = "Interrupted during: " + job.Status; } job.StatusUpdater = new StatusUpdate.ObjectListViewStatusUpdate(ObjectListViewUpdater, job); jobs.Add(job); } } } catch (System.Runtime.Serialization.SerializationException) { } catch (FileNotFoundException) { } foreach (IVideoJob job in jobs) { job.Index = ++IndexCounter; } objectListViewDownloads.AddObjects(jobs); foreach (IVideoJob job in jobs) { JobSet.Add(job); } for (int i = 0; i < objectListViewDownloads.Items.Count; ++i) { if (i % 2 == 1) { objectListViewDownloads.Items[i].BackColor = objectListViewDownloads.AlternateRowBackColorOrDefault; } } } }
private void EnqueueAll(StreamService?service = null) { foreach (var item in objectListViewDownloads.Objects) { IVideoJob job = item as IVideoJob; if (job != null && job.JobStatus == VideoJobStatus.NotStarted) { if (service == null || service.Value == job.VideoInfo.Service) { VideoTaskGroups[job.VideoInfo.Service].Add(new WaitingVideoJob(job)); } } } }
private async void SanityCheckTwitch() { List <string> paths = new List <string>(); foreach (string path in paths) { foreach (string file in Directory.EnumerateFiles(path, "twitch_*.mp4", SearchOption.AllDirectories)) { try { string filepart = Path.GetFileNameWithoutExtension(file); long tmp; string id = filepart.Split('_').Where(x => x.StartsWith("v") && long.TryParse(x.Substring(1), out tmp)).First(); List <IVideoJob> jobs = new List <IVideoJob>(); foreach (var item in objectListViewDownloads.Objects) { IVideoJob job = item as IVideoJob; if (job != null) { if (job.VideoInfo.Service == StreamService.Twitch && job.VideoInfo.VideoId == id && job.JobStatus == VideoJobStatus.Finished) { try { // sanity check TimeSpan actualVideoLength = (await FFMpegUtil.Probe(file)).Duration; TimeSpan expectedVideoLength = job.VideoInfo.VideoLength; if (actualVideoLength.Subtract(expectedVideoLength).Duration() > TimeSpan.FromSeconds(5)) { // if difference is bigger than 5 seconds something is off, report job.Status = "Large time difference between expected (" + expectedVideoLength.ToString() + ") and actual (" + actualVideoLength.ToString() + "), reenqueueing. (" + file + ")"; job.JobStatus = VideoJobStatus.NotStarted; } else { job.Status = "Sane."; } } catch (Exception ex) { job.Status = "Exception while sanity checking: " + ex.ToString(); job.JobStatus = VideoJobStatus.NotStarted; } } } } } catch (Exception) { } } } }
private void buttonSettings_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { List <IVideoJob> jobs = new List <IVideoJob>(); lock (Util.JobFileLock) { foreach (var item in objectListViewDownloads.Objects) { IVideoJob job = item as IVideoJob; if (job != null) { jobs.Add(job); } } } new AutoRenameWindow(jobs).ShowDialog(); } }
private void SaveJobs() { lock (Util.JobFileLock) { using (MemoryStream memoryStream = new MemoryStream()) { Invoke((MethodInvoker)(() => { lock ( SaveJobTimerLock ) { if (SaveJobTimer != null) { SaveJobTimer.Stop(); } } List <IVideoJob> jobs = new List <IVideoJob>(); foreach (var item in objectListViewDownloads.Objects) { IVideoJob job = item as IVideoJob; if (job != null) { jobs.Add(job); } } SaveJobsInternal(memoryStream, jobs); })); long count = memoryStream.Position; memoryStream.Position = 0; using (FileStream fs = System.IO.File.Create(Util.VodXmlTempPath)) using (System.IO.Compression.GZipStream gzs = new System.IO.Compression.GZipStream(fs, System.IO.Compression.CompressionLevel.Optimal)) { Util.CopyStream(memoryStream, gzs, count); } if (System.IO.File.Exists(Util.VodXmlPath)) { Thread.Sleep(100); System.IO.File.Delete(Util.VodXmlPath); Thread.Sleep(100); } System.IO.File.Move(Util.VodXmlTempPath, Util.VodXmlPath); Thread.Sleep(100); } } }
public bool EnqueueJob(IVideoJob job) { if (JobSet.Contains(job)) { return(false); } job.StatusUpdater = new StatusUpdate.ObjectListViewStatusUpdate(ObjectListViewUpdater, job); job.Index = ++IndexCounter; objectListViewDownloads.AddObject(job); JobSet.Add(job); job.Status = "Waiting..."; if (VideoTaskGroups[job.VideoInfo.Service].AutoEnqueue) { VideoTaskGroups[job.VideoInfo.Service].Add(new WaitingVideoJob(job)); } InvokeSaveJobs(); return(true); }
public WaitingVideoJob(IVideoJob job, DateTime allowedStartTime, bool startImmediately = false) { Job = job; StartImmediately = startImmediately; EarliestPossibleStartTime = allowedStartTime; }
public WaitingVideoJob(IVideoJob job, bool startImmediately = false) : this(job, DateTime.UtcNow, startImmediately) { }
private ContextMenuStrip CreateItemMenu(object model, BrightIdeasSoftware.OLVColumn column) { if (model != null && model as IVideoJob != null) { IVideoJob job = model as IVideoJob; ContextMenuStrip menu = new ContextMenuStrip(); { IUserInputRequest uir = job.UserInputRequest; if (uir != null) { ToolStripMenuItem item = new ToolStripMenuItem(uir.GetQuestion()); foreach (string option in uir.GetOptions()) { item.DropDownItems.Add(option).Click += (sender, e) => { if (uir != null) { uir.SelectOption(option); } }; } menu.Items.Add(item); menu.Items.Add(new ToolStripSeparator()); } } bool queueOptionsAvailable = false; if ((job.JobStatus == VideoJobStatus.NotStarted || job.JobStatus == VideoJobStatus.Dead) && !VideoTaskGroups[job.VideoInfo.Service].IsInQueue(job)) { queueOptionsAvailable = true; ToolStripItem item = menu.Items.Add("Enqueue"); item.Click += (sender, e) => { VideoTaskGroups[job.VideoInfo.Service].Add(new WaitingVideoJob(job)); }; } if ((job.JobStatus == VideoJobStatus.NotStarted || job.JobStatus == VideoJobStatus.Dead) && VideoTaskGroups[job.VideoInfo.Service].IsInQueue(job)) { queueOptionsAvailable = true; ToolStripItem item = menu.Items.Add("Dequeue"); item.Click += (sender, e) => { VideoTaskGroups[job.VideoInfo.Service].Dequeue(job); }; } if (job.JobStatus == VideoJobStatus.NotStarted || job.JobStatus == VideoJobStatus.Dead) { queueOptionsAvailable = true; ToolStripItem item = menu.Items.Add("Download now"); item.Click += (sender, e) => { if (job.JobStatus == VideoJobStatus.NotStarted || job.JobStatus == VideoJobStatus.Dead) { VideoTaskGroups[job.VideoInfo.Service].Add(new WaitingVideoJob(job, true)); } }; } if (queueOptionsAvailable) { menu.Items.Add(new ToolStripSeparator()); } { ToolStripItem item = menu.Items.Add("Copy Video ID"); item.Click += (sender, e) => { string id = job?.VideoInfo?.VideoId; if (id != null) { Clipboard.SetText(id); } }; } { ToolStripItem item = menu.Items.Add("Copy Output Filename"); item.Click += (sender, e) => { string fn = job?.GenerateOutputFilename(); if (fn != null) { Clipboard.SetText(fn); } }; } menu.Items.Add(new ToolStripSeparator()); if (job.JobStatus == VideoJobStatus.Running) { ToolStripItem item = menu.Items.Add("Stop"); item.Click += (sender, e) => { if (job.JobStatus == VideoJobStatus.Running) { VideoTaskGroups[job.VideoInfo.Service].CancelJob(job); } }; } if (job.JobStatus == VideoJobStatus.NotStarted) { ToolStripItem item = menu.Items.Add("Kill"); item.Click += (sender, e) => { if (job.JobStatus == VideoJobStatus.NotStarted) { job.JobStatus = VideoJobStatus.Dead; job.Status = "[Manually killed] " + job.Status; } }; } if (job.JobStatus != VideoJobStatus.Running) { ToolStripItem item = menu.Items.Add("Remove"); item.Click += (sender, e) => { if (job.JobStatus != VideoJobStatus.Running) { objectListViewDownloads.RemoveObject(job); JobSet.Remove(job); } }; } return(menu.Items.Count > 0 ? menu : null); } return(null); }