Example #1
0
        public void ParseSections(string edlFilePath, string outputFilePath, Predicate <IEdlEntry> predicate)
        {
            var edlFileContents = File.ReadAllText(edlFilePath);
            var edl             = new CMX3600Deserializer().Read(edlFileContents);

            List <Section> sections = new();

            foreach (var entry in edl)
            {
                if (predicate == null || predicate(entry))
                {
                    var outTC   = new TimeCode(entry.RecordOut, SmpteFrameRate.Smpte25);
                    var outTC2  = TimeCode.FromFrames(outTC.TotalFrames - 1, outTC.FrameRate);
                    var section = new Section()
                    {
                        In  = new TimeCode(entry.RecordIn, SmpteFrameRate.Smpte25),
                        Out = outTC2
                    };

                    sections.Add(section);
                }
            }

            var sw = new SectionWriter();

            sw.WriteToFile(outputFilePath, sections);
        }
Example #2
0
        private void SyncVideoCursor()
        {
            var projectData     = this.ServiceProvider.GetRequiredService <IVideoPlayerProjectData>();
            var projectSettings = this.ServiceProvider.GetRequiredService <IProjectSettings>();
            var currentTCStr    = "UNKNOWN";
            var currentSubStr   = string.Empty;
            ITimeCodeDocumentItem <string> currentSub = null;

            if (projectData.CursorMs.HasValue)
            {
                var fr       = projectSettings.FrameRate;
                var offsetTC = TimeCode.FromFrames(projectSettings.OffsetFrames, fr);
                var cursorTC = offsetTC.Add(TimeCode.FromSeconds(projectData.CursorMs.Value / 1000.0, fr));
                currentTCStr = cursorTC.ToString();

                //TODO Get current subtitle
                //if (this.SubtitleItems != null && this.SubtitleItems.Any())
                //{
                //    currentSub = this.SubtitleItems.FirstOrDefault(p => cursorTC.TotalFrames >= p.RecordIn.TotalFrames && cursorTC.TotalFrames <= p.RecordOut.TotalFrames);
                //}
            }

            //if (currentSub != null)
            //{
            //    currentSubStr = currentSub.Content;
            //    this.x_TextBox.StartHighlight(currentSub.TextSpan, WrappedTextBox.HighlightKind.VideoCursor, true);
            //}
            //else
            //{
            //    this.x_TextBox.ClearHighlights(p => p.Kind == WrappedTextBox.HighlightKind.VideoCursor);
            //}

            //this.x_TextBlock_TimeCode.Text = currentTCStr;
            //this.x_TextBlock_CurrentSubtitle.Text = currentSubStr;
        }
        /// <summary>
        /// Handles the Tick event of the Timer control.
        /// It handles the forward/rewind of the media.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void Timer_Tick(object sender, EventArgs e)
        {
            if (this.currentSkipDirection == 0)
            {
                return;
            }

            bool add = this.currentSkipDirection > 0;
            long newSkipDirection = 1;

            TimeCode currentTimeCode    = TimeCode.FromTimeSpan(this.Player.Position, this.currentSmpteFrameRate);
            long     currentTotalFrames = currentTimeCode.TotalFrames;

            TimeCode frameTimeCode = TimeCode.FromFrames(newSkipDirection, this.currentSmpteFrameRate);

            currentTimeCode = add ? currentTimeCode.Add(frameTimeCode) : currentTimeCode.Subtract(frameTimeCode);
            newSkipDirection++;

            while (currentTimeCode.TotalFrames == currentTotalFrames)
            {
                frameTimeCode   = TimeCode.FromFrames(newSkipDirection, this.currentSmpteFrameRate);
                currentTimeCode = add ? currentTimeCode.Add(frameTimeCode) : currentTimeCode.Subtract(frameTimeCode);
                newSkipDirection++;
            }

            this.Player.Position = TimeSpan.FromSeconds(Math.Max(0, currentTimeCode.TotalSeconds));
            this.SetCurrentTime(this.Player.Position);
        }
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jsonObject  = JObject.Load(reader);
            var     properties  = jsonObject.Properties().ToList();
            var     totalFrames = jsonObject.Property("totalFrames").Value <long>();
            var     frameRate   = jsonObject.Property("frameRate").Value <SmpteFrameRate>();

            return(TimeCode.FromFrames(totalFrames, frameRate));
        }
        public void SplitCurrentSubtitle()
        {
            var textBox      = this.ServiceProvider.GetRequiredService <WrappedTextBox>();
            var fps          = this.ServiceProvider.GetRequiredService <IProjectSettings>().FrameRate;
            var subtitleView = this.ServiceProvider.GetRequiredService <ISubtitleView>();

            if (subtitleView.SubtitleItems == null)
            {
                return;
            }

            var caretIndex      = textBox.CaretIndex;
            var currentSubtitle = subtitleView.SubtitleItems.FirstOrDefault(p => p.TextSpan.Start <= caretIndex && (p.TextSpan.Start + p.TextSpan.Length) >= caretIndex);

            if (currentSubtitle == null)
            {
                return;
            }

            var prefix = currentSubtitle.TextSpan.Document.Substring(currentSubtitle.ContentTextSpan.Start, caretIndex - currentSubtitle.ContentTextSpan.Start);
            var suffix = currentSubtitle.TextSpan.Document.Substring(caretIndex, currentSubtitle.ContentTextSpan.Start + currentSubtitle.ContentTextSpan.Length - caretIndex);

            if (string.IsNullOrWhiteSpace(prefix) || string.IsNullOrWhiteSpace(suffix))
            {
                return;
            }
            prefix = prefix.Trim('\r', '\n');
            suffix = suffix.Trim('\r', '\n');

            var totalDurationFrames = currentSubtitle.RecordOut.TotalFrames - currentSubtitle.RecordIn.TotalFrames;

            if (totalDurationFrames < 3)
            {
                return;
            }
            var splitProprtion = (double)prefix.Length / (double)(prefix.Length + suffix.Length);
            var splitFrame     = (int)Math.Floor(splitProprtion * (double)totalDurationFrames);
            var outTC1         = TimeCode.FromFrames(currentSubtitle.RecordIn.TotalFrames + splitFrame - 1, fps);
            var intTC2         = TimeCode.FromFrames(currentSubtitle.RecordIn.TotalFrames + splitFrame + 1, fps);
            var outTC2         = TimeCode.FromFrames(currentSubtitle.RecordOut.TotalFrames, fps);

            StringBuilder replacements = new StringBuilder();

            replacements.AppendLine($"{currentSubtitle.RecordIn} {outTC1}");
            replacements.AppendLine(prefix);
            replacements.AppendLine();
            replacements.AppendLine($"{intTC2} {outTC2}");
            replacements.AppendLine(suffix);
            replacements.AppendLine();

            textBox.TextEditor.Document.Replace((int)currentSubtitle.TextSpan.Start, (int)currentSubtitle.TextSpan.Length, replacements.ToString());
        }
Example #6
0
 public void CreateFailingTest()
 {
     Assert.Throws <ArgumentException>(
         "isDropFrame",
         () => TimeCode.FromFrames(0, FrameRate.fps23_98, true));
     Assert.Throws <ArgumentException>(
         "isDropFrame",
         () => TimeCode.FromString("DROPFRAME", FrameRate.fps23_98, true));
     Assert.Throws <ArgumentNullException>(
         "input",
         () => TimeCode.FromString(string.Empty, FrameRate.fps23_98, false));
     Assert.Throws <ArgumentException>(
         "input",
         () => TimeCode.FromString("NOTVALID", FrameRate.fps23_98, false));
 }
        private void AddRubberBandingPoints(TimelineElement element, CompositeManifestInfo compositeManifestInfo)
        {
            const ulong Timescale = 10000000;

            List <Point> elementVolumeCollection = element.VolumeNodeCollection;

            foreach (Point point in elementVolumeCollection)
            {
                double volume       = 1 - point.Y;
                long   frames       = (long)point.X;
                double totalSeconds = TimeCode.FromFrames(frames, this.sequenceRegistry.CurrentSequenceModel.CurrentPosition.FrameRate).TotalSeconds + element.Position.TotalSeconds;

                long ticks = (long)(totalSeconds * Timescale);

                compositeManifestInfo.AddRubberBandingPoint(ticks, volume);
            }
        }
        /// <summary>
        /// Handles the Rewind/Forward of the <see cref="IAggregateMediaModel"/>.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void FrameRewindForwardTimerTick(object sender, EventArgs e)
        {
            if (this.currentSkipDirection == 0)
            {
                return;
            }

            bool add = this.currentSkipDirection > 0;
            long newSkipDirection = 1;

            TimeCode currentTimeCode    = TimeCode.FromTimeSpan(this.manifestMediaModel.Position, this.sequenceRegistry.CurrentSequenceModel.Duration.FrameRate);
            long     currentTotalFrames = currentTimeCode.TotalFrames;

            TimeCode frameTimeCode = TimeCode.FromFrames(newSkipDirection, this.sequenceRegistry.CurrentSequenceModel.Duration.FrameRate);

            currentTimeCode = add ? currentTimeCode.Add(frameTimeCode) : currentTimeCode.Subtract(frameTimeCode);
            newSkipDirection++;

            while (currentTimeCode.TotalFrames == currentTotalFrames)
            {
                frameTimeCode   = TimeCode.FromFrames(newSkipDirection, this.sequenceRegistry.CurrentSequenceModel.Duration.FrameRate);
                currentTimeCode = add ? currentTimeCode.Add(frameTimeCode) : currentTimeCode.Subtract(frameTimeCode);
                newSkipDirection++;
            }

            TimeSpan position = TimeSpan.FromSeconds(Math.Max(0, currentTimeCode.TotalSeconds));

            // Check if the playing mode is comment. If yes then don't allow to go forwar/backwar
            // beyond the comment Markin and MarkOut position.
            if (this.PlayerMode == PlayerMode.Comment && this.currentPlayingComment != null)
            {
                if (position.TotalSeconds < this.currentPlayingComment.MarkIn)
                {
                    position = TimeSpan.FromMilliseconds(this.currentPlayingComment.MarkIn.GetValueOrDefault() * 1000);
                }
                else if (position.TotalSeconds > this.currentPlayingComment.MarkOut)
                {
                    position = TimeSpan.FromMilliseconds(this.currentPlayingComment.MarkOut.GetValueOrDefault() * 1000);
                }
            }

            this.manifestMediaModel.Position = position;
            this.OnPositionUpdated(this, new PositionPayloadEventArgs(position));
        }
        protected override Size MeasureOverride(Size availableSize)
        {
            const double heightProp = 1.0;
            var          baseVal    = base.MeasureOverride(availableSize);

            var tc = TimeCode.FromFrames(this.OffsetFrames, this.FrameRate);

            foreach (var elem in this.SubtitleElements)
            {
                var subtitle   = elem.Item;
                var subStartMs = (subtitle.RecordIn.TotalSeconds - tc.TotalSeconds) * 1000.0;
                var subEndMs   = (subtitle.RecordOut.TotalSeconds - tc.TotalSeconds) * 1000.0;
                var inRange    = subStartMs >= this.StartMs && subStartMs <= this.EndMs || subEndMs >= this.StartMs && subEndMs <= this.EndMs || subStartMs <this.StartMs && subEndMs> this.EndMs;
                if (!inRange)
                {
                    continue;
                }
                var uspan     = UVWavHelpers.GetUSpan(this.StartMs, this.EndMs);
                var subStartU = (double)subStartMs / (double)UVWavHelpers.FullRangeProjection.Width;
                var leftPix   = this.ActualWidth * (subStartU - uspan.Value) / uspan.Width;
                var subEndU   = (double)subEndMs / (double)UVWavHelpers.FullRangeProjection.Width;
                var subEndX   = this.ActualWidth * (subEndU - uspan.Value) / uspan.Width;

                var pen = new Pen(Brushes.Purple, 1.0);
                pen = null;
                //var top = this.ActualHeight * ((1.0 - heightProp) / 2.0);
                var topPix    = this.ActualHeight * ((1.0 - heightProp));
                var bottomPix = topPix + this.ActualHeight * heightProp;
                var rightPix  = leftPix + subEndX - leftPix;

                elem.Element.HasCroppedLeft  = leftPix < 0;
                elem.Element.HasCroppedRight = rightPix > this.ActualWidth;

                leftPix   = leftPix < 0 ? 0 : leftPix;
                rightPix  = rightPix > this.ActualWidth ? this.ActualWidth : rightPix;
                topPix    = topPix < 0 ? 0 : topPix;
                bottomPix = bottomPix > this.ActualHeight ? this.ActualHeight : bottomPix;

                var rect = new Rect(leftPix, topPix, rightPix - leftPix, bottomPix - topPix);
                elem.Rect = rect;
                elem.Element.Measure(rect.Size);
            }
            return(baseVal);
        }
        private void AddRubberBandingPoints(Shot shot, CompositeManifestInfo compositeManifestInfo)
        {
            const ulong Timescale = 10000000;

            List <VolumeLevelNode> volumeNodes = shot.VolumeNodeCollection;

            foreach (VolumeLevelNode volumeNode in volumeNodes)
            {
                double         volume = volumeNode.Volume;
                long           frames = (long)volumeNode.Position;
                SmpteFrameRate frameRate;
                SmpteFrameRate.TryParse(this.project.SmpteFrameRate, true, out frameRate);
                double totalSeconds = TimeCode.FromFrames(frames, frameRate).TotalSeconds + shot.TrackAnchor.MarkIn.Value;

                long ticks = (long)(totalSeconds * Timescale);

                compositeManifestInfo.AddRubberBandingPoint(ticks, volume);
            }
        }
        public IEnumerable <Section> Convert(string avidDSFilePath, SmpteFrameRate smpteFrameRate)
        {
            var dsText = File.ReadAllText(avidDSFilePath);
            var avidDSDocumentReader = new AvidDSDocumentReader();
            var avidDSDocument       = avidDSDocumentReader.Read(dsText);

            var retval = new List <Section>();

            foreach (var dsComponent in avidDSDocument.Components)
            {
                var outTC1 = new TimeCode(dsComponent.Out, smpteFrameRate);
                var outTC  = TimeCode.FromFrames(outTC1.TotalFrames - 1, smpteFrameRate);
                retval.Add(new Section
                {
                    In  = new TimeCode(dsComponent.In, smpteFrameRate),
                    Out = outTC
                });
            }
            return(retval.ToArray());
        }
Example #12
0
        public void CreateByFrameTest(int frames, FrameRate frameRate, bool isDropFrame, string expected)
        {
            var actual = TimeCode.FromFrames(frames, frameRate, isDropFrame);

            Assert.Equal(expected, actual.ToString());
        }
 /* #endregion Private Fields */
 /* #region Private Methods */
 private void InvalidateTimeCode()
 {
     this.TimeCode = TimeCode.FromFrames(this.Frames, this.FrameRate);
 }
        public static IEnumerable <Title> GetTitles(this Track track, XElement root, SmpteFrameRate framerate)
        {
            var retval       = new List <Title>();
            var trackItemIds = track.XElement.Descendants(XName.Get("TrackItem")).Select(p => p.Attribute(XName.Get("ObjectRef"))?.Value);
            var trackItems   = root.Elements(XName.Get("VideoClipTrackItem")).Where(
                p => trackItemIds.Any(q => p.Attribute(XName.Get("ObjectID"))?.Value == q));

            foreach (var trackItem in trackItems)
            {
                TimeCode             startTC, endTC;
                string               name;
                IEnumerable <string> titleLines = new string[0];
                /* #region Get titles */
                {
                    var start       = trackItem.Descendants(XName.Get("Start")).First().Value;
                    var startFrames = long.Parse(start) / PremiereHelpers.GetFramerateDivisor(framerate);
                    startTC = TimeCode.FromFrames(startFrames, framerate);
                    var end       = trackItem.Descendants(XName.Get("End")).First().Value;
                    var endFrames = long.Parse(end) / PremiereHelpers.GetFramerateDivisor(framerate);
                    endTC = TimeCode.FromFrames(endFrames, framerate);

                    var subclipId = trackItem.Descendants(XName.Get("SubClip")).FirstOrDefault()?.Attribute(XName.Get("ObjectRef"))?.Value;
                    var subclips  = root.Elements(XName.Get("SubClip"));
                    var subclip   = root.Elements(XName.Get("SubClip")).FirstOrDefault(p => p.Attribute(XName.Get("ObjectID"))?.Value == subclipId);

                    name = subclip.Element(XName.Get("Name"))?.Value;

                    var clipId     = subclip.Elements(XName.Get("Clip"))?.Attributes(XName.Get("ObjectRef")).FirstOrDefault()?.Value;
                    var videoClips = root.Elements(XName.Get("VideoClip"));
                    var videoClip  = videoClips.FirstOrDefault(p => p.Attribute(XName.Get("ObjectID"))?.Value == clipId);

                    var sourceId = videoClip.Element(XName.Get("Clip")).Element(XName.Get("Source"))?.Attribute(XName.Get("ObjectRef"))?.Value;

                    var videoMediaSources = root.Elements(XName.Get("VideoMediaSource"));
                    var videoMediaSource  = videoMediaSources.FirstOrDefault(p => p.Attribute(XName.Get("ObjectID"))?.Value == sourceId);

                    var mediaUID = videoMediaSource.Element(XName.Get("MediaSource")).Element(XName.Get("Media"))?.Attribute(XName.Get("ObjectURef"))?.Value;

                    var mediaNodes = root.Elements(XName.Get("Media"));
                    var media      = mediaNodes.FirstOrDefault(p => p.Attribute(XName.Get("ObjectUID"))?.Value == mediaUID);

                    var encoding = media.Element(XName.Get("ImporterPrefs"))?.Value;
                    if (string.IsNullOrEmpty(encoding))
                    {
                        continue;
                    }

                    byte[] data          = Convert.FromBase64String(encoding);
                    string decodedString = Encoding.UTF8.GetString(data);
                    if (decodedString.Contains("Compressed"))
                    {
                        titleLines = PremiereHelpers.DecodeCompressedTitleContent(data);
                    }
                    else
                    {
                        titleLines = PremiereHelpers.DecodeTitleContent(decodedString);
                    }
                }
                /* #endregion*/

                var title = new Title()
                {
                    Start   = startTC,
                    End     = endTC,
                    Content = string.Join(Environment.NewLine, titleLines)
                };
                retval.Add(title);
            }
            return(retval);
        }