private void mediaPlayer_MediaOpened(object sender, RoutedEventArgs e) { ResetMediaOpenButton(); if (!mediaPlayer.NaturalDuration.HasTimeSpan) { MessageBox.Show(Localise.GetPhrase("Failed to read media duration"), Localise.GetPhrase("Media Read Error"), MessageBoxButton.OK, MessageBoxImage.Error); return; } _totalVideoTime = mediaPlayer.NaturalDuration.TimeSpan; // Total video time timeSlider.Maximum = _totalVideoTime.TotalMilliseconds; // Set the slider max value // NOTE: Update the timeStamp - don't fire event (simulate button) since it sets the mediaplayer to mode to manual and it fails to show the first frame of the video RoutedPropertyChangedEventArgs <double> newEventArgs = new RoutedPropertyChangedEventArgs <double>(1, 0); timeSlider_ValueChanged(sender, newEventArgs); // Enable button in the end after setting everything if (!_playing) { playStopCmd.IsEnabled = timeSlider.IsEnabled = cutStartCmd.IsEnabled = true; cutEndCmd.IsEnabled = false; mediaPlayer.LoadedBehavior = MediaState.Manual; // Set to manual and pause it so that the seek function works (otherwise it needs to be manually played for seek to work) mediaPlayer.Pause(); // Load and pause the video } // Load the EDL file if found if (edlCuts.Items.Count <= 0) // MediaOpened is called multiple times sometimes, only load it once { string edlFile = FilePaths.GetFullPathWithoutExtension(mediaPlayer.Source.LocalPath) + ".edl"; string vprjFile = FilePaths.GetFullPathWithoutExtension(mediaPlayer.Source.LocalPath) + ".vprj"; if (FileIO.FileSize(edlFile) > 0) // Check if it exists { ReadEDL(edlFile); } else if (FileIO.FileSize(vprjFile) > 0) // Check for VPRJ file { if (EDL.ConvertVPRJtoEDL(vprjFile, edlFile, new Log())) // Convert to EDL { if (FileIO.FileSize(edlFile) > 0) { ReadEDL(edlFile); } } } } }
public void CreateEDL() { var pool = new TextBlockPool(); TextBlock helloMyName = new TextBlock("hello my name"); pool.SaveTextBlock(helloMyName); TextBlock isSimon = new TextBlock(" is simon"); pool.SaveTextBlock(isSimon); var edl = new EDL(); edl.Add(helloMyName); edl.Add(isSimon); Assert.AreEqual("hello my name is simon", edl.GetText(pool)); }
public bool TrimSubtitle(string srtFile, string workingPath, int startTrim, int endTrim, float Duration, double offset) { string TempEDLFile = Path.Combine(workingPath, "TempSRTEDLTrimFile.edl"); // Temp EDL file to trim SRT if (String.IsNullOrWhiteSpace(srtFile)) { return(true); // Nothing to do } if ((startTrim <= 0) && (endTrim <= 0)) { return(true); // Nothing to do } if (Duration <= 0) { _jobLog.WriteEntry(this, ("Invalid video duration"), Log.LogEntryType.Error); return(false); } // Create a EDL file which trims beginning and ending List <KeyValuePair <float, float> > keepList = new List <KeyValuePair <float, float> >(); keepList.Add(new KeyValuePair <float, float>((startTrim > 0 ? startTrim : 0), (endTrim > 0 ? Duration - endTrim : Duration))); // Add Start and end trim to create EDL file EDL edl = new EDL(_profile, "", GlobalDefs.MAX_VIDEO_DURATION, TempEDLFile, 0, _jobStatus, _jobLog, true); // Ignore minimum segment since we are trimming subtitles if (!edl.CreateEDLFile(keepList)) // Create the EDL file { _jobLog.WriteEntry(this, ("Cannot trim SRT file"), Log.LogEntryType.Error); return(false); } // Now use the EDL file to trim the SRT file CutWithEDL(TempEDLFile, srtFile, offset, 0, true); // Ignore minimum cut since we are trimming here and not cutting commercials FileIO.TryFileDelete(TempEDLFile); // clean up temp edl file return(true); }
/// <summary> /// Adjust the Subtitle file to compensate for the cut segments represented in a EDL file /// </summary> /// <param name="edlFile">EDL file containing segment information</param> /// <param name="srtFile">Subtitle file</param> /// <param name="ccOffset">Offset to shift the timebase for all subtitles (+ve or -ve)</param> /// <param name="segmentOffset">Incremental offset to shift the timebase for subtitles AFTER each segment is cut (+ve or -ve). Used to compensate for progressive shifting in EDL cutting due to GOP boundary issues</param> /// <param name="ignoreMinimumCut">Ignore the mininum segment size for cutting (true when not cutting for an encoder, e.g. trimming)</param> /// <returns>True if successful</returns> public bool CutWithEDL(string edlFile, string srtFile, double ccOffset, double segmentOffset, bool ignoreMinimumCut = false) { _jobLog.WriteEntry(this, ("Syncing SRT file with EDL file"), Log.LogEntryType.Information); _jobLog.WriteEntry(this, "EDL File " + edlFile, Log.LogEntryType.Debug); _jobLog.WriteEntry(this, "SRT File " + srtFile, Log.LogEntryType.Debug); _jobLog.WriteEntry(this, "Offset : " + ccOffset.ToString(CultureInfo.InvariantCulture), Log.LogEntryType.Debug); _jobLog.WriteEntry(this, "Progressive Segment Cut Correction : " + segmentOffset.ToString(CultureInfo.InvariantCulture), Log.LogEntryType.Debug); if (String.IsNullOrEmpty(srtFile) || String.IsNullOrEmpty(edlFile)) { return(true); // nothing to do } if (!File.Exists(srtFile) || !File.Exists(edlFile) || FileIO.FileSize(srtFile) == 0 || FileIO.FileSize(edlFile) == 0) { _jobLog.WriteEntry(this, ("SRT/EDL file does not exist or is 0 bytes in size"), Log.LogEntryType.Warning); return(true); // nothing to do } // Taken from MACHYY1's srt_edl_cutter.ps1 (translated and enhanced from PS1 to C#) List <List <string> > srt_array = new List <List <string> >(); // Read the EDL File List <KeyValuePair <float, float> > edlKeepList = new List <KeyValuePair <float, float> >(); EDL edl = new EDL(_profile, "", GlobalDefs.MAX_VIDEO_DURATION, edlFile, 0, _jobStatus, _jobLog, ignoreMinimumCut); // assume infinite duration, Ignore minimum segment since we are trimming subtitles if (!edl.ParseEDLFile(ref edlKeepList)) { _jobLog.WriteEntry(this, ("Error processing EDL file"), Log.LogEntryType.Error); return(false); } if (edlKeepList.Count == 0) { return(true); // All done, nothing to adjust } // Read the SRT File try { System.IO.StreamReader srtS = new System.IO.StreamReader(srtFile); string line; int sequence = 1, temp; List <string> line_text = new List <string>(); double srt_start_time = 0, srt_end_time = 0; List <string> srt_line; string[] fields; while ((line = srtS.ReadLine()) != null) { if (line == "") //blank line - so write the info to an array (end of current entry) { if (sequence > 0) { int edl_segment = 0; // If the keep doesn't start at 0 then we have 1 segment already cut double total_time_cut = ccOffset; // Set to offset double last_keep = 0; foreach (KeyValuePair <float, float> keep in edlKeepList) { total_time_cut += keep.Key - last_keep; // Track how much time has been cut so far if (srt_start_time >= keep.Key && srt_start_time <= keep.Value) // record to keep { srt_line = new List <string>(); // Build the SRT entry string startTimeCode = (seconds_to_hhmmss(srt_start_time - total_time_cut + (edl_segment * segmentOffset))); // Compensate progressively for each segment if (srt_end_time > keep.Value) // SANITY CHECK: end time should not exceed the end of keep video/srt time (otherwise it looks like a burned in video with previous subtitle overlapping the next at the cut boundary) { srt_end_time = keep.Value; } string endTimeCode = (seconds_to_hhmmss(srt_end_time - total_time_cut + (edl_segment * segmentOffset))); // Compensate progressively for each segment. /* SRT FORMAT: * SubRip (SubRip Text) files are named with the extension .srt, and contain formatted plain text. * The time format used is hours:minutes:seconds,milliseconds. The decimal separator used is the comma, since the program was written in France. * The line break used is often the CR+LF pair. * Subtitles are numbered sequentially, starting at 1. * Subtitle number * Start time --> End time * Text of subtitle (one or more lines) * Blank line */ srt_line.Add(sequence.ToString()); // Subtitle No srt_line.Add(startTimeCode + " --> " + endTimeCode); // Start time --> End time foreach (string text in line_text) // Text of subtitle (one or more lines) { srt_line.Add(text); } srt_line.Add(""); // Blank line srt_array.Add(srt_line); // Build the SRT file sequence++; break; } edl_segment++; last_keep = keep.Value; } srt_start_time = srt_end_time = 0; line_text.Clear(); // Reset the content } } else if (int.TryParse(line, out temp)) // Line number { continue; // do nothing here } else if (line.Contains(" --> ")) // Timecodes { line = line.Replace(" --> ", "\t"); fields = line.Split('\t'); srt_start_time = hhmmss_to_seconds(fields[0]); srt_end_time = hhmmss_to_seconds(fields[1]); } else if (line != "") // Text Content { if (!String.IsNullOrWhiteSpace(line)) // don't add blank lines, it causes programs like MP4Box to choke { line_text.Add(line); } } else { throw new System.ArgumentException("Invalid SRT file format"); } } srtS.Close(); srtS.Dispose(); } catch (Exception e) { _jobLog.WriteEntry(this, ("Error processing SRT file") + " " + e.ToString(), Log.LogEntryType.Error); return(false); } // Delete the original SRT file FileIO.TryFileDelete(srtFile); try { // Write the new SRT file StreamWriter srtWrite = new System.IO.StreamWriter(srtFile); foreach (List <string> srt_line in srt_array) { foreach (string entry in srt_line) { srtWrite.WriteLine(entry); // Format is already prebuilt above, just dump into the file } } srtWrite.Flush(); srtWrite.Close(); srtWrite.Dispose(); } catch (Exception e) { _jobLog.WriteEntry(this, ("Error writing to SRT file") + " " + e.ToString(), Log.LogEntryType.Error); return(false); } return(true); }