/// <summary> /// To use: Prepare Windows Media Writer and other objects, construct, call the Encode method, /// use properties and other methods to get results, release, close Windows Media Writer. /// </summary> /// <param name="segment">Batch params for this segment. We assume all fields have already been validated.</param> /// <param name="jobStart">Absolute start time of the first segment of the job in ticks</param> /// <param name="offset">The total timespan in ticks of all previous segments in this job</param> /// <param name="wmWriter">Windows Media Writer object to write to. We assume it has been preconfigured and started.</param> /// <param name="progressTracker">Where to put UI status updates</param> /// <param name="logMgr">Where to put log messages</param> /// <param name="profileData">compressed media types we are writing to in the norecompression case</param> public WMSegment(ArchiveTranscoderJob job, ArchiveTranscoderJobSegment segment, long jobStart, long offset, WMWriter wmWriter, ProgressTracker progressTracker, LogMgr logMgr, ProfileData profileData, bool norecompression, WMSegment previousSegment) { cancel = false; this.logMgr = logMgr; this.job = job; this.segment = segment; this.offset = offset; this.jobStart = jobStart; this.progressTracker = progressTracker; this.profileData = profileData; this.norecompression = norecompression; this.m_PreviousSegment = previousSegment; videoStream = null; slideStream = null; audioStreams = null; presentationMgr = null; writer = wmWriter; startTime = endTime = DateTime.MinValue; startTime = DateTime.Parse(segment.StartTime); endTime = DateTime.Parse(segment.EndTime); useSlideStream = false; if (Utility.SegmentFlagIsSet(segment, SegmentFlags.SlidesReplaceVideo)) { useSlideStream = true; } }
/// <summary> /// For the case where we are handed an existing segment to edit, we want to find out which conference /// it belongs to. Assume the tree view has already been filled in from the database. Just walk the tree until we find /// a match, or until we get to the end. An alternative approach would be to store this information with /// the segment, but we currently don't because I believe it is relevant only in this form. /// </summary> /// <param name="segment"></param> /// <returns></returns> private String GetCurrentConfString(ArchiveTranscoderJobSegment segment) { DateTime start = DateTime.MinValue; DateTime end = DateTime.MinValue; try { start = DateTime.Parse(segment.StartTime); end = DateTime.Parse(segment.EndTime); } catch { return(""); } //consider it a match if the time is within range and at least one cname matches. String cname = ""; if ((segment.VideoDescriptor != null) && (segment.VideoDescriptor.VideoCname != null) && (segment.VideoDescriptor.VideoCname != "")) { cname = segment.VideoDescriptor.VideoCname; } else if ((segment.AudioDescriptor != null) && (segment.AudioDescriptor.Length > 0)) { cname = segment.AudioDescriptor[0].AudioCname; } if ((cname == null) || (cname == "")) { return(""); } foreach (TreeNode node in this.treeViewSources.Nodes) { if (node.Tag is Conference) { Conference c = (Conference)node.Tag; //Require that either the start or the end be within the range of the conference. if (((c.Start <= start) && (c.End >= start)) || ((c.Start <= end) && (c.End >= end))) { foreach (TreeNode pnode in node.Nodes) { if (pnode.Tag is Participant) { if (((Participant)(pnode.Tag)).CName == cname) { return(c.Start.ToString() + " - " + c.Description); } } } } } } return(""); }
public PreviewForm(ArchiveTranscoderJobSegment segment, String sqlHost, String dbName) { InitializeComponent(); this.sqlHost = sqlHost; this.dbName = dbName; this.segment = segment; this.textBoxStartTime.Text = segment.StartTime; this.textBoxDuration.Text = "300"; useSlideStream = false; Debug.WriteLine("WMP Version: " + this.axWindowsMediaPlayer1.versionInfo); if (segment.VideoDescriptor != null) { this.videoStreamGroup = new StreamGroup(segment.VideoDescriptor); this.labelVideoSource.Text = videoStreamGroup.ToString(); } else { if (Utility.SegmentFlagIsSet(segment, SegmentFlags.SlidesReplaceVideo)) { this.videoStreamGroup = new StreamGroup(segment.PresentationDescriptor.PresentationCname, "Presentation Slides", "dynamicVideo"); useSlideStream = true; } else { Debug.Assert(false); } this.labelVideoSource.Text = "[Presentation] " + videoStreamGroup.Cname; } bool itemChecked = false; closing = false; //We prefer to default to an audio cname that matches the video cname if possible. for (int i = 0; i < segment.AudioDescriptor.Length; i++) { if (segment.AudioDescriptor[i].AudioCname == videoStreamGroup.Cname) { this.checkedListBoxAudioSources.Items.Add(new StreamGroup(segment.AudioDescriptor[i]), CheckState.Checked); itemChecked = true; } else { this.checkedListBoxAudioSources.Items.Add(new StreamGroup(segment.AudioDescriptor[i]), CheckState.Unchecked); } } //..otherwise just use the first one. if (!itemChecked) { if (this.checkedListBoxAudioSources.Items.Count > 0) { this.checkedListBoxAudioSources.SetItemCheckState(0, CheckState.Checked); } } this.setToolTips(); }
public SegmentForm(ConferenceDataCache confDataCache) { InitializeComponent(); this.setToolTips(); segment = null; slideDecks = null; this.confDataCache = confDataCache; this.sqlHost = confDataCache.SqlServer; this.dbName = confDataCache.DbName; }
/// <summary> /// Construct and return a ProfileData instance /// containing media type and codec private data for audio and video as /// determined using the first audio and video frames referenced by the segment. /// Audio sources in the segment other than the first will be ignored. /// </summary> /// <param name="segment"></param> /// <returns></returns> public static ProfileData SegmentToProfileData(ArchiveTranscoderJobSegment segment) { DateTime startDt = DateTime.Parse(segment.StartTime); DateTime endDt = DateTime.Parse(segment.EndTime); byte[] aframe = DatabaseUtility.GetFirstFrame(PayloadType.dynamicAudio, segment.AudioDescriptor[0].AudioCname, segment.AudioDescriptor[0].AudioName, startDt.Ticks, endDt.Ticks); if (Utility.SegmentFlagIsSet(segment, SegmentFlags.SlidesReplaceVideo)) { return(AudioFrameToProfileData(aframe)); } else { byte[] vframe = DatabaseUtility.GetFirstFrame(PayloadType.dynamicVideo, segment.VideoDescriptor.VideoCname, segment.VideoDescriptor.VideoName, startDt.Ticks, endDt.Ticks); return(FramesToProfileData(aframe, vframe)); } }
/// <summary> /// If the segment has the specified flag set, return true. /// </summary> /// <param name="segment"></param> /// <param name="flag"></param> /// <returns></returns> public static bool SegmentFlagIsSet(ArchiveTranscoderJobSegment segment, SegmentFlags flag) { if (segment != null) { if (segment.Flags != null) { foreach (string s in segment.Flags) { if (s != null) { if (Enum.GetName(typeof(SegmentFlags), flag).ToLower() == s.Trim().ToLower()) { return(true); } } } } } return(false); }
/// <summary> /// Add the specified flag to segment flags. If the flag is already set, do nothing. /// </summary> /// <param name="segment"></param> /// <param name="flag"></param> public static void SetSegmentFlag(ArchiveTranscoderJobSegment segment, SegmentFlags flag) { if (segment != null) { if (segment.Flags == null) { segment.Flags = new String[1]; segment.Flags[0] = Enum.GetName(typeof(SegmentFlags), flag); } else { if (SegmentFlagIsSet(segment, flag)) { return; } String[] newFlags = new String[segment.Flags.Length + 1]; segment.Flags.CopyTo(newFlags, 0); newFlags[newFlags.Length - 1] = Enum.GetName(typeof(SegmentFlags), flag); segment.Flags = newFlags; } } }
public SegmentWrapper(ArchiveTranscoderJobSegment segment) { this.segment = segment; starttime = DateTime.Parse(segment.StartTime); }
public SlideStreamMgr(ArchiveTranscoderJob job, ArchiveTranscoderJobSegment segment, LogMgr logMgr, double fps, int width, int height) { this.job = job; this.segment = segment; this.logMgr = logMgr; if (width > 0 && height > 0) { this.outputWidth = width; this.outputHeight = height; } this.ticksBetweenFrames = (long)((double)Constants.TicksPerSec / fps); uncompressedMT = getUncompressedMT(this.outputWidth, this.outputHeight, fps); cancel = false; initialized = false; pptInstalled = Utility.CheckPptIsInstalled(); if ((!DateTime.TryParse(segment.StartTime, out start)) || (!DateTime.TryParse(segment.EndTime, out end))) { throw(new System.Exception("Failed to parse start/end time")); } this.nextFrameTime = start.Ticks; format = Utility.StringToPresenterWireFormatType(segment.PresentationDescriptor.PresentationFormat); payload = Utility.formatToPayload(format); cname = segment.PresentationDescriptor.PresentationCname; slideImageMgr = new SlideImageMgr(format, this.outputWidth, this.outputHeight); //Get the start time for the entire conference and use that to get streams. long confStart = DatabaseUtility.GetConferenceStartTime(payload, cname, start.Ticks, end.Ticks); if (confStart <= 0) { logMgr.WriteLine("Warning: No conference exists in the database that matches this presentation: " + cname + " with PresentationFormat " + format.ToString()); logMgr.ErrorLevel = 7; confStart = start.Ticks; } //Get the relevant stream_id's and create DBStreamPlayers for each. streamIDs = DatabaseUtility.GetStreams(payload, segment.PresentationDescriptor.PresentationCname, null, confStart, end.Ticks); DateTime sdt = new DateTime(confStart); Debug.WriteLine("***Conference start: " + sdt.ToString() + " end: " + end.ToString()); if ((streamIDs == null) || (streamIDs.Length == 0)) { Debug.WriteLine("No presentation data found."); logMgr.WriteLine("Warning: No presentation data was found for the given time range for " + cname + " with PresentationFormat " + format.ToString()); logMgr.ErrorLevel = 7; streamPlayers = null; return; } streamPlayers = new DBStreamPlayer[streamIDs.Length]; for (int i = 0; i < streamIDs.Length; i++) { streamPlayers[i] = new DBStreamPlayer(streamIDs[i], confStart, end.Ticks, payload); } lookBehindDuration = 0; if (streamPlayers[0].Start < start) { lookBehindDuration = ((TimeSpan)(start - streamPlayers[0].Start)).TotalSeconds; } }
private void buttonPreview_Click(object sender, System.EventArgs e) { //This button should not be enabled unless there is at least one audio, one video, and a time range. DateTime start = DateTime.MinValue; DateTime end = DateTime.MinValue; if (!validate(out start, out end)) { return; } segment = new ArchiveTranscoderJobSegment(); //segment.StartTime = start.ToString(Constants.dtformat); //segment.EndTime = end.ToString(Constants.dtformat); segment.StartTime = Utility.GetLocalizedDateTimeString(start, Constants.timeformat); segment.EndTime = Utility.GetLocalizedDateTimeString(end, Constants.timeformat); if (this.listBoxVideoSource.Items[0] is StreamGroup) { segment.VideoDescriptor = ((StreamGroup)this.listBoxVideoSource.Items[0]).ToVideoDescriptor(); } segment.AudioDescriptor = new ArchiveTranscoderJobSegmentAudioDescriptor[this.listBoxAudioSources.Items.Count]; for (int i = 0; i < this.listBoxAudioSources.Items.Count; i++) { segment.AudioDescriptor[i] = ((StreamGroup)this.listBoxAudioSources.Items[i]).ToAudioDescriptor(); } if ((this.listBoxPresentationSource.Items.Count == 1) && (checkBoxSlidesReplaceVideo.Checked)) { if (!validateDecks(sender, e)) { return; } segment.PresentationDescriptor = ((StreamGroup)this.listBoxPresentationSource.Items[0]).ToPresentationDescriptor(); if (slideDecks != null) { segment.SlideDecks = new ArchiveTranscoderJobSlideDeck[slideDecks.Length]; for (int i = 0; i < slideDecks.Length; i++) { segment.SlideDecks[i] = new ArchiveTranscoderJobSlideDeck(); segment.SlideDecks[i].DeckGuid = slideDecks[i].DeckGuid.ToString(); segment.SlideDecks[i].Title = slideDecks[i].FileName; if (slideDecks[i].Matched) { segment.SlideDecks[i].Path = slideDecks[i].Path; } } } Utility.SetSegmentFlag(segment, SegmentFlags.SlidesReplaceVideo); } this.Cursor = Cursors.WaitCursor; PreviewForm previewForm = new PreviewForm(segment, sqlHost, dbName); this.Cursor = Cursors.Default; if (DialogResult.OK == previewForm.ShowDialog(this)) { if (previewForm.MarkIn != DateTime.MinValue) { //this.textBoxStart.Text = previewForm.MarkIn.ToString(Constants.dtformat); this.textBoxStart.Text = Utility.GetLocalizedDateTimeString(previewForm.MarkIn, Constants.timeformat); } if (previewForm.MarkOut != DateTime.MinValue) { //this.textBoxEnd.Text = previewForm.MarkOut.ToString(Constants.dtformat); this.textBoxEnd.Text = Utility.GetLocalizedDateTimeString(previewForm.MarkOut, Constants.timeformat); } } }
private void buttonOk_Click(object sender, System.EventArgs e) { DateTime start = DateTime.MinValue; DateTime end = DateTime.MinValue; if (!validate(out start, out end)) { return; } //Warn if slide decks don't exist or are not matched. if (!validateDecks(sender, e)) { return; } segment = new ArchiveTranscoderJobSegment(); //segment.StartTime = start.ToString(Constants.dtformat); segment.StartTime = Utility.GetLocalizedDateTimeString(start, Constants.timeformat); //segment.EndTime = end.ToString(Constants.dtformat); segment.EndTime = Utility.GetLocalizedDateTimeString(end, Constants.timeformat); if (this.listBoxVideoSource.Items.Count == 1) { if (this.listBoxVideoSource.Items[0] is StreamGroup) { segment.VideoDescriptor = ((StreamGroup)this.listBoxVideoSource.Items[0]).ToVideoDescriptor(); } else { segment.VideoDescriptor = null; } } segment.AudioDescriptor = new ArchiveTranscoderJobSegmentAudioDescriptor[this.listBoxAudioSources.Items.Count]; for (int i = 0; i < this.listBoxAudioSources.Items.Count; i++) { segment.AudioDescriptor[i] = ((StreamGroup)this.listBoxAudioSources.Items[i]).ToAudioDescriptor(); } if (this.listBoxPresentationSource.Items.Count == 1) { segment.PresentationDescriptor = ((StreamGroup)this.listBoxPresentationSource.Items[0]).ToPresentationDescriptor(); if (slideDecks != null) { segment.SlideDecks = new ArchiveTranscoderJobSlideDeck[slideDecks.Length]; for (int i = 0; i < slideDecks.Length; i++) { segment.SlideDecks[i] = new ArchiveTranscoderJobSlideDeck(); segment.SlideDecks[i].DeckGuid = slideDecks[i].DeckGuid.ToString(); segment.SlideDecks[i].Title = slideDecks[i].FileName; if (slideDecks[i].Matched) { segment.SlideDecks[i].Path = slideDecks[i].Path; } } } if (checkBoxSlidesReplaceVideo.Checked) { Utility.SetSegmentFlag(segment, SegmentFlags.SlidesReplaceVideo); } } this.DialogResult = DialogResult.OK; this.Close(); }
/// <summary> /// Load an existing segment for editing. /// Return true if the segment appears to match a conference in the database. /// </summary> /// <param name="segment"></param> public bool LoadSegment(ArchiveTranscoderJobSegment segment) { //fill in the form controls with existing data this.segment = segment; if ((segment.VideoDescriptor != null) && (segment.VideoDescriptor.VideoCname != null) && (segment.VideoDescriptor.VideoCname != "")) { this.listBoxVideoSource.Items.Add(new StreamGroup(segment.VideoDescriptor)); } if ((segment.PresentationDescriptor != null) && (segment.PresentationDescriptor.PresentationCname != null) && (segment.PresentationDescriptor.PresentationCname != "")) { if (segment.PresentationDescriptor.VideoDescriptor == null) { this.listBoxPresentationSource.Items.Add(new StreamGroup(segment.PresentationDescriptor)); this.buttonRemovePresentation.Enabled = true; this.buttonDeckMatcher.Enabled = true; if (segment.SlideDecks != null) { slideDecks = new Deck[segment.SlideDecks.Length]; for (int i = 0; i < segment.SlideDecks.Length; i++) { slideDecks[i] = new Deck(segment.SlideDecks[i]); } } this.checkBoxSlidesReplaceVideo.Enabled = true; if (Utility.SegmentFlagIsSet(segment, SegmentFlags.SlidesReplaceVideo)) { this.checkBoxSlidesReplaceVideo.Checked = true; //Other config is done by the check changed handler. } } else { //This is for building presentation from video stills. this.listBoxPresentationSource.Items.Add(new StreamGroup(segment.PresentationDescriptor.VideoDescriptor)); this.buttonRemovePresentation.Enabled = false; this.buttonDeckMatcher.Enabled = false; this.checkBoxSlidesReplaceVideo.Enabled = false; this.buttonRemovePresentation.Enabled = true; } } else { this.checkBoxSlidesReplaceVideo.Enabled = false; } if ((segment.AudioDescriptor != null) && (segment.AudioDescriptor.Length > 0)) { for (int i = 0; i < segment.AudioDescriptor.Length; i++) { if ((segment.AudioDescriptor[i].AudioCname != null) && (segment.AudioDescriptor[i].AudioCname != "")) { this.listBoxAudioSources.Items.Add(new StreamGroup(segment.AudioDescriptor[i])); } } } this.textBoxStart.Text = segment.StartTime; this.textBoxEnd.Text = segment.EndTime; String confStr = GetCurrentConfString(segment); if (confStr != "") { this.listBoxConference.Items.Add(confStr); } else { this.listBoxConference.Items.Add("Unavailable Conference!"); } if ((this.listBoxAudioSources.Items.Count > 0) && (this.listBoxVideoSource.Items.Count > 0)) { this.buttonPreview.Enabled = true; this.buttonOk.Enabled = true; } if (confStr == "") { return(false); } return(true); }