public bool AppendHobbVLCEpisode() { BRBEpisode episode = BRBManager.GetRandomBRBEpisode(Config.HobbVLCIgnoreMaxDurationAfterTries == -1 || Program.PlayerForm.HobbVLCsTriggered < Config.HobbVLCIgnoreMaxDurationAfterTries ? new TimeSpan(Config.HobbVLCMaxDuration * TimeSpan.TicksPerMinute + TimeSpan.TicksPerMinute / 2) : (TimeSpan?)null, true, Program.PlayerForm.BRBPlaylist); if (episode == null) { episode = BRBManager.GetRandomBRBEpisode(Config.HobbVLCIgnoreMaxDurationAfterTries == -1 || Program.PlayerForm.HobbVLCsTriggered < Config.HobbVLCIgnoreMaxDurationAfterTries ? new TimeSpan(Config.HobbVLCMaxDuration * TimeSpan.TicksPerMinute + TimeSpan.TicksPerMinute / 2) : (TimeSpan?)null, false, Program.PlayerForm.BRBPlaylist); } if (episode == null) { episode = BRBManager.GetRandomBRBEpisode(Config.HobbVLCIgnoreMaxDurationAfterTries == -1 || Program.PlayerForm.HobbVLCsTriggered < Config.HobbVLCIgnoreMaxDurationAfterTries ? new TimeSpan(Config.HobbVLCMaxDuration * TimeSpan.TicksPerMinute + TimeSpan.TicksPerMinute / 2) : (TimeSpan?)null, false); } if (episode != null) { ListViewItem item = new ListViewItem(new string[] { episode.Filename, BRBManager.TimeSpanToMMSS(episode.Duration), episode.GetWeight().ToString(), "hobbVLC" }); lstBRBPlaylist.Items.Add(item); UpdateBRBPlaylistRunningTime(); Program.PlayerForm.AppendBRB(episode); return(true); } else { return(false); } }
// Set up the BRB manager and analyze all files in the BRB directory private void AnalyzeBRBFiles() { // BRBManager.BRBEpisodes should be an empty list right now, even if brbepisodes.json already exists, since it shouldn't get loaded if Initial Setup is triggered List <string> paths = new List <string>(Directory.GetFiles(txtBRBDirectory.Text)); BRBEpisode episode; foreach (string path in paths) { episode = new BRBEpisode(Path.GetFileName(path), false); // Create BRB episode, but do not treat as a new episode if (episode.Duration.Ticks == 0) // Make sure the app understands all BRB files { MessageBox.Show("Could not register the BRB file \"" + Path.GetFileName(path) + "\". Make sure it is a valid video file (in a format compatible with VLC) " + "and the application has read permissions on it. If it is not supposed to be a BRB episode, please move it out of the BRB directory.", "Registering BRB failed", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { BRBManager.BRBEpisodes.Add(episode); } } BRBManager.BRBEpisodes.Sort(); BRBManager.RefreshAvailableList(); // Try saving BRB data to disk. If this fails, do not proceed if (!BRBManager.SaveEpisodes()) { MessageBox.Show("Could not write to file brbepisodes.json. BRB data could not be created; the application will now exit.\r\n\r\n" + "Please make sure the application has write permissions in its directory and try again.", "Writing BRB data to disk failed", MessageBoxButtons.OK, MessageBoxIcon.Error); Program.ExitApplication(); } }
public FormAutoMuteData(BRBEpisode episode) { InitializeComponent(); this.episode = episode; this.Text = "Displaying AutoMute Data of " + episode.Filename; if (episode.AutoMutes.Count == 0) { txtBegin.Text = ""; txtEnd.Text = ""; txtInfo.Text = ""; } else { foreach (BRBEpisode.AutoMuteSpan span in episode.AutoMutes) { drpAutoMuteTrigger.Items.Add((!span.Enabled ? "[Disabled] " : "") + BRBManager.TimeSpanToMMSS(span.Begin) + " \u2013 " + BRBManager.TimeSpanToMMSS(span.End) + " / " + span.Info); } drpAutoMuteTrigger.SelectedIndex = 0; UpdateAutoMuteData(); } }
public FormRenameBRB(BRBEpisode episode) { InitializeComponent(); txtOldFilename.Text = episode.Filename; episodeToRename = episode; }
public FormUpdateBRB(BRBEpisode episode) { InitializeComponent(); txtOldFilename.Text = episode.Filename; episodeToUpdate = episode; List <string> availableFilenames = new List <string>(); BRBEpisode dirEpisode; foreach (string path in Directory.GetFiles(Config.BRBDirectory)) { // Only allow files that aren't yet in the system or at least haven't been played yet, since their data will be overwritten if they are in the system dirEpisode = BRBManager.GetEpisode(Path.GetFileName(path)); if (dirEpisode == null || dirEpisode.PlaybackChapters.Count == 0) { availableFilenames.Add(Path.GetFileName(path)); } } drpUpdatedFilename.Items.AddRange(availableFilenames.ToArray()); if (!drpUpdatedFilename.Items.Contains(episode.Filename)) { drpUpdatedFilename.Items.Add(episode.Filename); // Can be useful when the duration of a BRB file changes, for instance } if (drpUpdatedFilename.Items.Count == 0) // Should never happen { drpUpdatedFilename.Items.Add("(No filenames available)"); btnReplace.Enabled = false; } drpUpdatedFilename.SelectedIndex = 0; }
// Adds a playback to the episode data public static void OnPlayedBack(BRBEpisode episode) { if (Config.TestMode) { // In Test Mode, save no playback data return; } episode.PlaybackChapters.Add(Config.Chapter); if (episode.GuaranteedPlays > 0) { episode.GuaranteedPlays--; } else if (episode.PriorityPlays > 0) { episode.PriorityPlays--; } else { episode.IsNew = false; // Non-priority playback, the episode is no longer "new" } SaveEpisodes(); // Suppress warnings/errors here. A last save is performed on exiting the player window; if saving still doesn't work there, then the user is informed Program.MainForm.UpdateBRBData(); }
public static bool RegisterNewBRB(string filename) { // Failsafe so BRB episodes do not get into the system twice, but this should never trigger foreach (BRBEpisode ep in BRBEpisodes) { if (ep.Filename == filename) { return(false); } } try { BRBEpisode newEpisode = new BRBEpisode(filename); if (newEpisode.Duration.Ticks > 0) { BRBEpisodes.Add(new BRBEpisode(filename)); BRBEpisodes.Sort(); RefreshAvailableList(); return(true); } else { return(false); } } catch (IOException) { return(false); } catch (VLCException) { return(false); } }
// Called by control form if a new episode is added during playback (which may be done manually or triggered by HobbVLC) public void AppendBRB(BRBEpisode episode) { BRBPlaylist.Add(episode); if (PlayerState == BRBPlayerState‌.EndOfBreak) { // Episode was added at end of break. Automatically play this new BRB ChangePlayerState(BRBPlayerState.InBetweenBRBs); UnpauseAndHideControls(); } }
// This just fetches data from the BRB Manager (and checks for new files) private void UpdateBRBList(bool considerNewFiles) { selectedBRB = null; if (considerNewFiles) { CheckAndAddNewFiles(); } lstAllBRBs.BeginUpdate(); lstAllBRBs.Items.Clear(); List <ListViewItem> newItems = new List <ListViewItem>(BRBManager.BRBEpisodes.Count); foreach (BRBEpisode episode in BRBManager.BRBEpisodes) { if (txtSearch.Text == "" || episode.ContainsTextAtField(txtSearch.Text, drpSearchWhere.SelectedIndex)) { ListViewItem item = new ListViewItem(episode.Filename); if (!BRBManager.AvailableBRBEpisodes.Contains(episode)) { item.ForeColor = Color.Red; } else if (episode.IsNew) { item.ForeColor = Color.Blue; } if (episode.Favourite) { item.Font = new Font(item.Font.FontFamily, 9.75f, FontStyle.Bold); } newItems.Add(item); } } lstAllBRBs.Items.AddRange(newItems.ToArray()); lstAllBRBs.EndUpdate(); if (txtSearch.Text == "") { lblAvailableBRBs.Text = "BRB Episodes (" + BRBManager.BRBEpisodes.Count + "):"; } else { lblAvailableBRBs.Text = "BRB Episodes (filtered, " + lstAllBRBs.Items.Count + " / " + BRBManager.BRBEpisodes.Count + "):"; } UpdateBRBData(); if (lstAllBRBs.Items.Count > 0) { lstAllBRBs.Items[0].Selected = true; } }
private void lstAllBRBs_SelectedIndexChanged(object sender, EventArgs e) { if (lstAllBRBs.SelectedItems.Count == 0) { selectedBRB = null; } else { selectedBRB = BRBManager.GetEpisode(lstAllBRBs.SelectedItems[0].Text); } UpdateBRBData(); }
private List <BRBEpisode> GetCurrentPlaylist() { List <BRBEpisode> playlist = new List <BRBEpisode>(); foreach (ListViewItem playlistItem in lstBRBPlaylist.Items) { BRBEpisode ep = BRBManager.GetEpisode(playlistItem.Text); if (ep != null) { playlist.Add(ep); } } return(playlist); }
// Called every time the playlist is updated private void UpdateBRBPlaylistRunningTime() { TimeSpan runningTime = new TimeSpan(0); foreach (ListViewItem playlistItem in lstBRBPlaylist.Items) { BRBEpisode ep = BRBManager.GetEpisode(playlistItem.Text); if (ep != null) { runningTime += new TimeSpan(Config.InterBRBCountdown * TimeSpan.TicksPerSecond); runningTime += ep.Duration; } } // The end screen is not counted here, since it happens after the last actual "playback" dispTotalBRBRunningTime.Text = BRBManager.TimeSpanToMMSS(runningTime); }
// Update the filename of a BRB episode, without considering anything else (for instance, when user updates a BRB to its new filename) public static bool TransferToNewFilename(BRBEpisode episode, string newFilename, bool removeOldEpisode) { BRBEpisode newEpisodeVersion = new BRBEpisode(newFilename, episode.Duration, episode.Favourite, episode.Title, episode.Description, episode.Credits, episode.IsNew, episode.PlaybackChapters, episode.GuaranteedPlays, episode.PriorityPlays, episode.AutoMutes, episode.AutoMuteEnabled); newEpisodeVersion.RefreshDuration(); // Make sure the episode's video file is understood by the application if (newEpisodeVersion.Duration.Ticks == 0) { return(false); } if (removeOldEpisode) { BRBEpisodes.Remove(episode); } BRBEpisodes.Add(newEpisodeVersion); BRBEpisodes.Sort(); return(true); }
private void btnReplace_Click(object sender, EventArgs e) { string newFilename = (string)drpUpdatedFilename.SelectedItem; BRBEpisode newVersionEpisode = BRBManager.GetEpisode(newFilename); // Old file doesn't exist anymore. Possible scenario: User has renamed or replaced a BRB file outside of the application if (!BRBManager.AvailableBRBEpisodes.Contains(episodeToUpdate)) { if (newVersionEpisode != null) { if (episodeToUpdate.Filename == newFilename) { // Cannot happen } else { if (MessageBox.Show("All BRB data from the old file will be copied over to the new video version in the system. This will overwrite any existing data of the new video.\r\n\r\n" + "Since the old file cannot be found on disk anymore, it will subsequently be removed from the system.\r\n\r\n" + "Do you want to proceed?", "Please confirm BRB video update", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) { return; } BRBManager.BRBEpisodes.Remove(newVersionEpisode); } } else { if (MessageBox.Show("The video file you specified is not registered in the system yet. This will be done now and all BRB data from the old file will be copied over.\r\n\r\n" + "Since the old file cannot be found on disk anymore, it will subsequently be removed from the system.\r\n\r\n" + "Do you want to proceed?", "Please confirm BRB video update", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) { return; } } // Copy data over and remove old BRB if (!BRBManager.TransferToNewFilename(episodeToUpdate, newFilename, true)) { MessageBox.Show("Could not register the new BRB file. Make sure it is a valid video file (in a format compatible with VLC) and the application has read permissions on it." + "\r\n\r\nThe updating process was aborted. If the new file was already in the system, it has been removed. No other data was changed.", "Adding new BRB failed", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } // Old file still exists. Possible scenario: User has added a newer version of the BRB and did not remove the old version from the directory else { if (newVersionEpisode != null) { if (episodeToUpdate.Filename == newFilename) { if (MessageBox.Show("This will reload the video file in question and update the duration shown in the application. Proceed?", "Please confirm BRB video update", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes) { episodeToUpdate.RefreshDuration(); if (!BRBManager.SaveEpisodes()) { MessageBox.Show("Could not write to file brbepisodes.json. Replacing the BRB file with a new version was successful, but this could not be saved to disk.\r\n\r\n" + "It is recommended you investigate this problem as soon as possible, since playback data is difficult to replace if lost.", "Writing BRB data to disk failed", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.Close(); return; // Make sure the file doesn't end up in the system twice } } else { if (MessageBox.Show("All BRB data from the old file will be copied over to the new video version in the system. This will overwrite any existing data of the new video.\r\n\r\n" + "Note that since the old video file is still present on disk, it will remain in the system. " + "If you do not wish this, please cancel the operation and remove it from the directory on disk first.\r\n\r\n" + "Do you want to proceed?", "Please confirm BRB video update", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) { return; } BRBManager.BRBEpisodes.Remove(newVersionEpisode); } } else { if (MessageBox.Show("The video file you specified is not registered in the system yet. This will be done now and all BRB data from the old file will be copied over.\r\n\r\n" + "Note that since the old video file is still present on disk, it will remain in the system. " + "If you do not wish this, please cancel the operation and remove it from the directory on disk first.\r\n\r\n" + "Do you want to proceed?", "Please confirm BRB video update", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No) { return; } } // Copy data over, but do not remove old BRB if (!BRBManager.TransferToNewFilename(episodeToUpdate, newFilename, false)) { MessageBox.Show("Could not register the new BRB file. Make sure it is a valid video file (in a format compatible with VLC) and the application has read permissions on it." + "\r\n\r\nThe updating process was aborted. If the new file was already in the system, it has been removed. No other data was changed.", "Adding new BRB failed", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } BRBManager.RefreshAvailableList(); if (!BRBManager.SaveEpisodes()) { MessageBox.Show("Could not write to file brbepisodes.json. Replacing the BRB file with a new version was successful, but this could not be saved to disk.\r\n\r\n" + "It is recommended you investigate this problem as soon as possible, since playback data is difficult to replace if lost.", "Writing BRB data to disk failed", MessageBoxButtons.OK, MessageBoxIcon.Error); } this.Close(); }
private static List <BRBEpisode> GeneratePlaylist(TimeSpan minDuration, TimeSpan targetDuration, TimeSpan maxDuration, bool replayAvoidance, ref List <string> refAddReason) { List <BRBEpisode> playlist = new List <BRBEpisode>(); TimeSpan duration = new TimeSpan(0); TimeSpan constInterBRBTimeSpan = new TimeSpan((long)((Config.InterBRBCountdown + 0.1) * TimeSpan.TicksPerSecond)); List <BRBEpisode> remDataset = new List <BRBEpisode>(BRBEpisodes); // First, consider BRBs marked "Guaranteed" (that is, "play ASAP"). Fill as much of the playlist with them as possible, ignoring Replay Avoidance List <BRBEpisode> guaranteedEpisodes = remDataset.FindAll(e => e.GuaranteedPlays > 0 && e.Duration + constInterBRBTimeSpan <= maxDuration - duration); while (guaranteedEpisodes.Count > 0 && duration < targetDuration) { BRBEpisode episode = GetWeightedRandomBRBFrom(guaranteedEpisodes); playlist.Add(episode); refAddReason.Add("Guaranteed"); duration += episode.Duration + constInterBRBTimeSpan; remDataset.Remove(episode); guaranteedEpisodes.Remove(episode); guaranteedEpisodes = guaranteedEpisodes.FindAll(e => e.GuaranteedPlays > 0 && e.Duration + constInterBRBTimeSpan <= maxDuration - duration); } remDataset = remDataset.FindAll(e => e.Duration + constInterBRBTimeSpan <= maxDuration - duration); // From now on, ignore all BRBs affected by Replay Avoidance if (replayAvoidance) { remDataset = remDataset.FindAll(e => Config.Chapter - e.LatestPlaybackChapter > Config.AvoidForChaptersAfterPlay); } // Choose one BRB that hasn't been played in forever, if there are any List <BRBEpisode> preferredEpisodes = remDataset.FindAll(e => e.LatestPlaybackChapter <= Config.Chapter - Config.PreferredPlayAfterChapters); if (preferredEpisodes.Count > 0 && duration < targetDuration) { BRBEpisode episode = GetWeightedRandomBRBFrom(preferredEpisodes); playlist.Add(episode); refAddReason.Add("Distance"); duration += episode.Duration + constInterBRBTimeSpan; remDataset.Remove(episode); remDataset = remDataset.FindAll(e => e.Duration + constInterBRBTimeSpan <= maxDuration - duration); } // Now, fill up the rest of the playlist. Use the minimum chance from the config for Priority BRBs List <BRBEpisode> remPriorityEpisodes; while (remDataset.Count > 0 && duration < targetDuration) { remPriorityEpisodes = remDataset.FindAll(e => e.PriorityPlays > 0); BRBEpisode episode; // Since the Priority chance is an integer percentage, one can use a random integer here if (remPriorityEpisodes.Count > 0 && Program.Rand.Next(1, 100) <= Config.ReservedChanceForPriorityBRBs) { episode = GetWeightedRandomBRBFrom(remPriorityEpisodes); refAddReason.Add("Priority"); } else { episode = GetWeightedRandomBRBFrom(remDataset); refAddReason.Add("Random"); } playlist.Add(episode); duration += episode.Duration + constInterBRBTimeSpan; remDataset.Remove(episode); remDataset = remDataset.FindAll(e => e.Duration + constInterBRBTimeSpan <= maxDuration - duration); } // Check whether minimum duration is satisfied. If yes, finding a playlist was successful. If not, the algorithm failed if (duration < minDuration) { return(null); } playlist = SortPlaylist(playlist, ref refAddReason); return(playlist); }