예제 #1
0
 /// <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;
     }
 }
예제 #2
0
        /// <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("");
        }
예제 #3
0
        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();
        }
예제 #4
0
 public SegmentForm(ConferenceDataCache confDataCache)
 {
     InitializeComponent();
     this.setToolTips();
     segment            = null;
     slideDecks         = null;
     this.confDataCache = confDataCache;
     this.sqlHost       = confDataCache.SqlServer;
     this.dbName        = confDataCache.DbName;
 }
예제 #5
0
        /// <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));
            }
        }
예제 #6
0
 /// <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);
 }
예제 #7
0
        /// <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;
                }
            }
        }
예제 #8
0
 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;
            }
        }
예제 #10
0
        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);
                }
            }
        }
예제 #11
0
        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();
        }
예제 #12
0
        /// <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);
        }