diff --git a/SLAM/App.config b/SLAM/App.config index 09d8aa8..cdb693c 100644 --- a/SLAM/App.config +++ b/SLAM/App.config @@ -52,6 +52,9 @@ False + + True + \ No newline at end of file diff --git a/SLAM/Form1.vb b/SLAM/Form1.vb index f3d4bef..99c52ce 100644 --- a/SLAM/Form1.vb +++ b/SLAM/Form1.vb @@ -7,6 +7,7 @@ Imports SLAM.XmlSerialization Imports SLAM.SourceGame Imports System.Management Imports System.Net.Http +Imports NReco.VideoConverter Public Class Form1 @@ -152,6 +153,22 @@ Public Class Form1 resampler.Dispose() End Sub + Private Sub FFMPEG_WaveCreator(File As String, outputFile As String, Game As SourceGame) + Dim convert As New FFMpegConverter() + convert.ExtractFFmpeg() + + Dim command As String = String.Format("-i ""{0}"" -f wav -flags bitexact -vn -acodec pcm_s16le -ar {1} -ac {2} ""{3}""", Path.GetFullPath(File), Game.samplerate, Game.channels, Path.GetFullPath(outputFile)) + convert.Invoke(command) + End Sub + + Private Sub FFMPEG_ConvertAndTrim(inpath As String, outpath As String, samplerate As Integer, channels As Integer, starttrim As Double, length As Double, volume As Double) + Dim convert As New FFMpegConverter() + convert.ExtractFFmpeg() + + Dim command As String = String.Format("-i ""{0}"" -f wav -flags bitexact -vn -acodec pcm_s16le -ar {1} -ac {2} -ss {3} -t {4} -af ""volume={5}"" ""{6}""", Path.GetFullPath(inpath), samplerate, channels, starttrim, length, volume, Path.GetFullPath(outpath)) + convert.Invoke(command) + End Sub + Private Sub GameSelector_SelectedIndexChanged(sender As Object, e As EventArgs) Handles GameSelector.SelectedIndexChanged ReloadTracks(GetCurrentGame) RefreshTrackList() @@ -160,7 +177,7 @@ Public Class Form1 End Sub Private Sub ImportButton_Click(sender As Object, e As EventArgs) Handles ImportButton.Click - If File.Exists("NAudio.dll") Then + If (My.Settings.UseFFMPEG = True And File.Exists("NReco.VideoConverter.dll")) Or (My.Settings.UseFFMPEG = False And File.Exists("NAudio.dll")) Then DisableInterface() If ImportDialog.ShowDialog() = DialogResult.OK Then ProgressBar1.Maximum = ImportDialog.FileNames.Count @@ -171,12 +188,12 @@ Public Class Form1 End If Else - MessageBox.Show("You are missing NAudio.dll! Cannot import without it!", "Missing File", MessageBoxButtons.OK, MessageBoxIcon.Error) + MessageBox.Show("You are missing NAudio.dll or NReco.VideoConverter.dll! Cannot import without it!", "Missing File", MessageBoxButtons.OK, MessageBoxIcon.Error) End If End Sub Private Sub YTButton_Click(sender As Object, e As EventArgs) Handles YTButton.Click - If File.Exists("NAudio.dll") AndAlso File.Exists("Newtonsoft.Json.dll") AndAlso File.Exists("YoutubeExtractor.dll") Then + If File.Exists("NAudio.dll") AndAlso File.Exists("Newtonsoft.Json.dll") AndAlso File.Exists("NReco.VideoConverter.dll") AndAlso File.Exists("YoutubeExtractor.dll") Then DisableInterface() Dim YTImporter As New YTImport If YTImporter.ShowDialog() = DialogResult.OK Then @@ -188,7 +205,7 @@ Public Class Form1 End If Else - MessageBox.Show("You are missing either NAudio.dll, Newtonsoft.Json.dll, or YoutubeExtractor.dll! Cannot import from YouTube without them!", "Missing File(s)", MessageBoxButtons.OK, MessageBoxIcon.Error) + MessageBox.Show("You are missing either NAudio.dll, Newtonsoft.Json.dll, NReco.VideoConverter.dll, or YoutubeExtractor.dll! Cannot import from YouTube without them!", "Missing File(s)", MessageBoxButtons.OK, MessageBoxIcon.Error) End If End Sub @@ -202,7 +219,13 @@ Public Class Form1 Try Dim OutFile As String = Path.Combine(Game.libraryname, Path.GetFileNameWithoutExtension(File) & ".wav") - WaveCreator(File, OutFile, Game) + + If My.Settings.UseFFMPEG Then + FFMPEG_WaveCreator(File, OutFile, Game) + Else + WaveCreator(File, OutFile, Game) + End If + If DeleteSource Then IO.File.Delete(File) @@ -415,33 +438,41 @@ Public Class Form1 Dim trackfile As String = Game.libraryname & Track.name & Game.FileExtension If File.Exists(trackfile) Then - If Track.volume = 100 And Track.startpos = -1 And Track.endpos = -1 Then + If Track.volume = 100 And Track.startpos <= 0 And Track.endpos <= 0 Then File.Copy(trackfile, voicefile) Else - Dim WaveFloat As New WaveChannel32(New WaveFileReader(trackfile)) + If My.Settings.UseFFMPEG Then - If Not Track.volume = 100 Then - WaveFloat.Volume = (Track.volume / 100) ^ 6 - End If + FFMPEG_ConvertAndTrim(trackfile, voicefile, Game.samplerate, Game.channels, Track.startpos / Game.samplerate / 2, (Track.endpos - Track.startpos) / Game.samplerate / 2, (Track.volume / 100) ^ 6) ' /2 because SLAM stores Track.startpos and Track.endpos as # of bytes not sample. With 16-bit audio, there are 2 bytes per sample. + + Else - If Not Track.startpos = Track.endpos And Track.endpos > 0 Then - Dim bytes((Track.endpos - Track.startpos) * 4) As Byte + Dim WaveFloat As New WaveChannel32(New WaveFileReader(trackfile)) - WaveFloat.Position = Track.startpos * 4 - WaveFloat.Read(bytes, 0, (Track.endpos - Track.startpos) * 4) + If Not Track.volume = 100 Then + WaveFloat.Volume = (Track.volume / 100) ^ 6 + End If - WaveFloat = New WaveChannel32(New RawSourceWaveStream(New MemoryStream(bytes), WaveFloat.WaveFormat)) - End If + If Not Track.startpos = Track.endpos And Track.endpos > 0 Then + Dim bytes((Track.endpos - Track.startpos) * 4) As Byte - WaveFloat.PadWithZeroes = False - Dim outFormat = New WaveFormat(Game.samplerate, Game.bits, Game.channels) - Dim resampler = New MediaFoundationResampler(WaveFloat, outFormat) - resampler.ResamplerQuality = 60 - WaveFileWriter.CreateWaveFile(voicefile, resampler) + WaveFloat.Position = Track.startpos * 4 + WaveFloat.Read(bytes, 0, (Track.endpos - Track.startpos) * 4) - resampler.Dispose() - WaveFloat.Dispose() + WaveFloat = New WaveChannel32(New RawSourceWaveStream(New MemoryStream(bytes), WaveFloat.WaveFormat)) + End If + + WaveFloat.PadWithZeroes = False + Dim outFormat = New WaveFormat(Game.samplerate, Game.bits, Game.channels) + Dim resampler = New MediaFoundationResampler(WaveFloat, outFormat) + resampler.ResamplerQuality = 60 + WaveFileWriter.CreateWaveFile(voicefile, resampler) 'wav + + resampler.Dispose() + WaveFloat.Dispose() + + End If End If @@ -893,20 +924,26 @@ Public Class Form1 End Sub Private Sub TrimToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles TrimToolStripMenuItem.Click - Dim Game As SourceGame = GetCurrentGame() - Dim TrimDialog As New TrimForm + If File.Exists("NAudio.dll") Then - TrimDialog.WavFile = Path.Combine(Game.libraryname, Game.tracks(TrackList.SelectedIndices(0)).name & Game.FileExtension) - TrimDialog.startpos = Game.tracks(TrackList.SelectedIndices(0)).startpos - TrimDialog.endpos = Game.tracks(TrackList.SelectedIndices(0)).endpos + Dim Game As SourceGame = GetCurrentGame() + Dim TrimDialog As New TrimForm + TrimDialog.WavFile = Path.Combine(Game.libraryname, Game.tracks(TrackList.SelectedIndices(0)).name & Game.FileExtension) + TrimDialog.startpos = Game.tracks(TrackList.SelectedIndices(0)).startpos + TrimDialog.endpos = Game.tracks(TrackList.SelectedIndices(0)).endpos - If TrimDialog.ShowDialog = Windows.Forms.DialogResult.OK Then - Game.tracks(TrackList.SelectedIndices(0)).startpos = TrimDialog.startpos - Game.tracks(TrackList.SelectedIndices(0)).endpos = TrimDialog.endpos - SaveTrackKeys(GetCurrentGame) - ReloadTracks(GetCurrentGame) - RefreshTrackList() + + If TrimDialog.ShowDialog = Windows.Forms.DialogResult.OK Then + Game.tracks(TrackList.SelectedIndices(0)).startpos = TrimDialog.startpos + Game.tracks(TrackList.SelectedIndices(0)).endpos = TrimDialog.endpos + SaveTrackKeys(GetCurrentGame) + ReloadTracks(GetCurrentGame) + RefreshTrackList() + End If + + Else + MessageBox.Show("You are missing NAudio.dll! Cannot trim without it!", "Missing File", MessageBoxButtons.OK, MessageBoxIcon.Error) End If End Sub diff --git a/SLAM/My Project/Application.Designer.vb b/SLAM/My Project/Application.Designer.vb index 7770024..7e711c0 100644 --- a/SLAM/My Project/Application.Designer.vb +++ b/SLAM/My Project/Application.Designer.vb @@ -24,7 +24,7 @@ Namespace My _ Public Sub New() MyBase.New(Global.Microsoft.VisualBasic.ApplicationServices.AuthenticationMode.Windows) - Me.IsSingleInstance = false + Me.IsSingleInstance = true Me.EnableVisualStyles = true Me.SaveMySettingsOnExit = true Me.ShutDownStyle = Global.Microsoft.VisualBasic.ApplicationServices.ShutdownMode.AfterMainFormCloses diff --git a/SLAM/My Project/Application.myapp b/SLAM/My Project/Application.myapp index 0f12f32..66a2a23 100644 --- a/SLAM/My Project/Application.myapp +++ b/SLAM/My Project/Application.myapp @@ -2,7 +2,7 @@ true Form1 - false + true 0 true 0 diff --git a/SLAM/My Project/AssemblyInfo.vb b/SLAM/My Project/AssemblyInfo.vb index 1f15b6e..783b61b 100644 --- a/SLAM/My Project/AssemblyInfo.vb +++ b/SLAM/My Project/AssemblyInfo.vb @@ -31,5 +31,5 @@ Imports System.Runtime.InteropServices ' by using the '*' as shown below: ' - - + + diff --git a/SLAM/My Project/Settings.Designer.vb b/SLAM/My Project/Settings.Designer.vb index cde8857..11498d4 100644 --- a/SLAM/My Project/Settings.Designer.vb +++ b/SLAM/My Project/Settings.Designer.vb @@ -15,7 +15,7 @@ Option Explicit On Namespace My _ Partial Friend NotInheritable Class MySettings Inherits Global.System.Configuration.ApplicationSettingsBase @@ -29,7 +29,7 @@ Namespace My Private Shared addedHandlerLockObject As New Object _ - Private Shared Sub AutoSaveSettings(sender As Global.System.Object, e As Global.System.EventArgs) + Private Shared Sub AutoSaveSettings(ByVal sender As Global.System.Object, ByVal e As Global.System.EventArgs) If My.Application.SaveMySettingsOnExit Then My.Settings.Save() End If @@ -221,6 +221,18 @@ Namespace My Me("StartMinimized") = value End Set End Property + + _ + Public Property UseFFMPEG() As Boolean + Get + Return CType(Me("UseFFMPEG"),Boolean) + End Get + Set + Me("UseFFMPEG") = value + End Set + End Property End Class End Namespace diff --git a/SLAM/My Project/Settings.settings b/SLAM/My Project/Settings.settings index 891d451..44c3190 100644 --- a/SLAM/My Project/Settings.settings +++ b/SLAM/My Project/Settings.settings @@ -44,5 +44,8 @@ False + + True + \ No newline at end of file diff --git a/SLAM/SLAM.vbproj b/SLAM/SLAM.vbproj index 5950221..542c0c3 100644 --- a/SLAM/SLAM.vbproj +++ b/SLAM/SLAM.vbproj @@ -74,6 +74,9 @@ lib\Newtonsoft.Json.dll + + lib\NReco.VideoConverter.dll + diff --git a/SLAM/SettingsForm.Designer.vb b/SLAM/SettingsForm.Designer.vb index c2c42d1..aede5cb 100644 --- a/SLAM/SettingsForm.Designer.vb +++ b/SLAM/SettingsForm.Designer.vb @@ -27,6 +27,8 @@ Partial Class SettingsForm Me.VersionLabel = New System.Windows.Forms.ToolStripStatusLabel() Me.DonateLabel = New System.Windows.Forms.ToolStripStatusLabel() Me.TabPage2 = New System.Windows.Forms.TabPage() + Me.NAudioRadio = New System.Windows.Forms.RadioButton() + Me.FFMPEGRadio = New System.Windows.Forms.RadioButton() Me.OverrideGroup = New System.Windows.Forms.GroupBox() Me.Label2 = New System.Windows.Forms.Label() Me.FinduserdataButton = New System.Windows.Forms.Button() @@ -89,6 +91,8 @@ Partial Class SettingsForm ' 'TabPage2 ' + Me.TabPage2.Controls.Add(Me.NAudioRadio) + Me.TabPage2.Controls.Add(Me.FFMPEGRadio) Me.TabPage2.Controls.Add(Me.OverrideGroup) Me.TabPage2.Controls.Add(Me.GroupBox3) Me.TabPage2.Location = New System.Drawing.Point(4, 22) @@ -99,6 +103,28 @@ Partial Class SettingsForm Me.TabPage2.Text = "Advanced" Me.TabPage2.UseVisualStyleBackColor = True ' + 'NAudioRadio + ' + Me.NAudioRadio.AutoSize = True + Me.NAudioRadio.Location = New System.Drawing.Point(125, 166) + Me.NAudioRadio.Name = "NAudioRadio" + Me.NAudioRadio.Size = New System.Drawing.Size(126, 17) + Me.NAudioRadio.TabIndex = 5 + Me.NAudioRadio.TabStop = True + Me.NAudioRadio.Text = "Use NAudio (Legacy)" + Me.NAudioRadio.UseVisualStyleBackColor = True + ' + 'FFMPEGRadio + ' + Me.FFMPEGRadio.AutoSize = True + Me.FFMPEGRadio.Location = New System.Drawing.Point(29, 166) + Me.FFMPEGRadio.Name = "FFMPEGRadio" + Me.FFMPEGRadio.Size = New System.Drawing.Size(90, 17) + Me.FFMPEGRadio.TabIndex = 4 + Me.FFMPEGRadio.TabStop = True + Me.FFMPEGRadio.Text = "Use FFMPEG" + Me.FFMPEGRadio.UseVisualStyleBackColor = True + ' 'OverrideGroup ' Me.OverrideGroup.Controls.Add(Me.Label2) @@ -335,6 +361,7 @@ Partial Class SettingsForm Me.StatusStrip1.ResumeLayout(False) Me.StatusStrip1.PerformLayout() Me.TabPage2.ResumeLayout(False) + Me.TabPage2.PerformLayout() Me.OverrideGroup.ResumeLayout(False) Me.OverrideGroup.PerformLayout() Me.GroupBox3.ResumeLayout(False) @@ -372,4 +399,6 @@ Partial Class SettingsForm Friend WithEvents userdatatext As TextBox Friend WithEvents MinimizeToSysTrayCheckBox As CheckBox Friend WithEvents StartMinimizedCheckBox As CheckBox + Friend WithEvents NAudioRadio As RadioButton + Friend WithEvents FFMPEGRadio As RadioButton End Class diff --git a/SLAM/SettingsForm.vb b/SLAM/SettingsForm.vb index 2ebc1d9..2c34952 100644 --- a/SLAM/SettingsForm.vb +++ b/SLAM/SettingsForm.vb @@ -14,6 +14,8 @@ EnableOverrideBox.Checked = My.Settings.OverrideFolders MinimizeToSysTrayCheckBox.Checked = My.Settings.MinimizeToSysTray StartMinimizedCheckBox.Checked = My.Settings.StartMinimized + FFMPEGRadio.Checked = My.Settings.UseFFMPEG + NAudioRadio.Checked = Not My.Settings.UseFFMPEG End Sub Private Sub UpdateCheckBox_CheckedChanged(sender As Object, e As EventArgs) Handles UpdateCheckBox.CheckedChanged @@ -104,4 +106,9 @@ My.Settings.StartMinimized = StartMinimizedCheckBox.Checked My.Settings.Save() End Sub + + Private Sub FFMPEGRadio_CheckedChanged(sender As Object, e As EventArgs) Handles FFMPEGRadio.CheckedChanged + My.Settings.UseFFMPEG = FFMPEGRadio.Checked + My.Settings.Save() + End Sub End Class \ No newline at end of file diff --git a/SLAM/lib/NReco.VideoConverter.XML b/SLAM/lib/NReco.VideoConverter.XML new file mode 100644 index 0000000..5f01fcc --- /dev/null +++ b/SLAM/lib/NReco.VideoConverter.XML @@ -0,0 +1,634 @@ + + + + NReco.VideoConverter + + + + + Represents async live media conversion task. + + + + + Start live stream conversion + + + + + Write input data into conversion stream + + + + + Stop live stream conversion process + + + + + Stop live stream conversion process and optionally force ffmpeg to quit + + force FFMpeg to quit by sending 'q' command to stdin. + + + + Wait until live stream conversion is finished (input stream ended) + + + Do not call "Wait" when input stream is not used and input data is provided using Write method + + + + + Abort live stream conversions process + + + + + Media conversion setting + + NReco.VideoConverter.OutputSettings + + + + Explicit sample rate for audio stream. Usual rates are: 44100, 22050, 11025 + + + + + Audio codec (complete list of audio codecs: ffmpeg -codecs) + + + + + Explicit video rate for video stream. Usual rates are: 30, 25 + + + + + Number of video frames to record + + + + + Video frame size (common video sizes are listed in VideoSizes + + + + + Video codec (complete list of video codecs: ffmpeg -codecs) + + + + + Get or set max duration (in seconds) + + + + + Extra custom FFMpeg parameters for 'output' + + + FFMpeg command line arguments inserted after input file parameter (-i) but before output file + + + + + Add silent audio stream to output + + + + + Seek to position (in seconds) before converting + + + + + Extra custom FFMpeg parameters for 'input' + + + FFMpeg command line arguments inserted before input file parameter (-i) + + + + + Media concatenation setting + + NReco.VideoConverter.OutputSettings + + + + Determine whether audio stream + + + + + Seek to position (in seconds) before converting + + + + + The exception that is thrown when FFMpeg process retruns non-zero error exit code + + + + + FFMpeg input (filename, URL or demuxer parameter) + + + + + Input media stream format (if null ffmpeg tries to automatically detect format). + + + + + Extra custom FFMpeg parameters for this input. + + + These FFMpeg command line arguments inserted before input specifier (-i). + + + + + Represents user credential used when starting FFMpeg process. + + + + + Gets the user name to be used when starting FFMpeg process. + + + + + Gets a secure string that contains the user password to use when starting FFMpeg process. + + + + + Gets a value that identifies the domain to use when starting FFMpeg process. + + + + + The exception that is thrown when FFMpeg process retruns non-zero error exit code + + + + + Get FFMpeg process error code + + + + + Represents common video frame sizes + + + + + QVGA: 320x200 + + + + + VGA: 640x480 + + + + + SVGA: 640x480 + + + + + XGA: 1024x768 + + + + + SXGA: 1280x1024 + + + + + WXGA: 1366x768 + + + + + WSXGA: 1600x1024 + + + + + UXGA: 1600x1200 + + + + + HD480: 852x480 + + + + + HD720: 1280x720 + + + + + HD1080: 1920x1080 + + + + + Represents common media format strings + + + Complete list of formats supported by FFMpeg: ffmpeg.exe -formats + + + + + AC-3 - encode and decode + + + + + Audio IFF (AIFF) - encode and decode + + + + + raw PCM A-law - encode and decode + + + + + ASF - encode and decode + + + + + WMV file (alias for ASF format) - encode and decode + + + + + AST (Audio format used on the Nintendo Wii.) - encode and decode + + + + + Sun AU - encode and decode + + + + + AVI (Audio Video Interleaved) - encode and decode + + + + + Apple CAF (Core Audio Format) - encode and decode + + + + + raw DTS + + + + + raw E-AC-3 - encode and decode + + + + + FFM (FFserver live feed) - encode and decode + + + + + raw FLAC - encode and decode + + + + + FLV (Flash Video) - encode and decode + + + + + raw H.261 - encode and decode + + + + + raw H.263 - encode and decode + + + + + raw H.264 - encode and decode + + + + + raw H.265 - only decode + + + + + Matroska - encode and decode + + + + + raw MPEG-4 video - encode and decode + + + + + raw MJPEG video - encode and decode + + + + + QuickTime / MOV - encode and decode + + + + + MP4 (MPEG-4 Part 14) - encode and decode + + + MP4 container cannot be used with live streams! + + + + + MPEG-1 Systems / MPEG program stream - encode and decode + + + + + PCM mu-law - encode and decode + + + + + Ogg - encode and decode + + + + + Sony OpenMG audio - encode and decode + + + + + WebM - encode and decode + + + + + Video converter component (wrapper to FFMpeg process) + + + + + Initializes a new instance of the FFMpegConverter class. + + + FFMpegConverter is NOT thread-safe. Separate instance should be used for each thread. + + + + + Converts media represented by local file and writes result to specified local file + + local path to input media file + local path to ouput media file + desired output format (like "mp4" or "flv") + + + + Converts media represented by local file and writes result to specified local file with specified settings. + + local path to input media file + input format (null for automatic format suggestion) + local path to output media file + output media format + explicit convert settings + + + + Converts media represented by local file and writes result to specified stream + + local path to input media file + output stream + output media format + + + + Converts media represented by local file and writes result to specified stream with specified convert settings. + + local path to input media file + input format (null for automatic format suggestion) + output stream + output media format + convert settings + + + + Converts several input files into one resulting output file. + + one or more FFMpeg input specifiers + output file name + output file format (optional, can be null) + output settings + + + + Create a task for live stream conversion (real-time) without input source. Input data should be passed with Write method. + + input stream media format + output media stream + output media format + convert settings + instance of + + + + Create a task for live stream conversion (real-time) that reads data from FFMpeg input source and write conversion result to output stream + + input source string identifier (file path, UDP or TCP source, local video device name) + input stream media format + output media stream + output media format + convert settings + instance of + + + + Create a task for live stream conversion (real-time) that reads data from stream and writes conversion result to the file + + input live stream (null if data is provided by calling "Write" method) + input stream media format + output file path + output media format + convert settings + instance of + + + + Create a task for live stream conversion (real-time) that reads data from input stream and write conversion result to output stream + + input live stream (null if data is provided by calling "Write" method) + input stream media format + output media stream + output media format + convert settings + instance of + + + + Extract video thumbnail (first frame) from local video file + + path to local video file + output stream for thumbnail in jpeg format + + + + Extract video thumbnail (first frame) from local video file + + path to local video file + path to thumbnail jpeg file + + + + Extract video frame from local video file at specified position + + path to local video file + output stream for thumbnail in jpeg format + video position (in seconds) + + + + Extract video frame from local video file at specified position + + path to local video file + path to thumbnail jpeg file + video position (in seconds) + + + + Concatenate several video files + + list of local video files + path to contactenation result file + desired output format + convert settings + + Note: all video files should have the same video frame size and audio stream. + + + + + Invoke FFMpeg process with custom command line arguments + + string with arguments + + + + Extracts ffmpeg binaries (if needed) to the location specified by . + + If missed ffmpeg is extracted automatically before starting conversion process. + In some cases it is better to do that explicetily on the application start by calling method. + This method is not available in LT version (without embedded ffmpeg binaries). + + + + Abort FFMpeg process started by ConvertMedia or ConcatMedia methods + + This method IMMEDIATELY stops FFMpeg by killing the process. Resulting file may be inconsistent. + + + + Stop FFMpeg process "softly" by sending 'q' command to FFMpeg console. + This method doesn't stop FFMpeg process immediately and may take some time. + + true if 'q' command was sent sucessfully and FFPeg process has exited. If this method returns false FFMpeg process should be stopped with Abort method. + + + + Gets or sets path where FFMpeg tool is located + + + By default this property points to the folder where application assemblies are located. + If WkHtmlToPdf tool files are not present PdfConverter expands them from DLL resources. + + + + + Gets or sets FFMpeg tool EXE file name ('ffmpeg.exe' by default) + + + + + Gets or sets maximum execution time for conversion process (null is by default - means no timeout) + + + + + Occurs when FFMpeg outputs media info (total duration, convert progress) + + + + + Occurs when log line is received from FFMpeg process + + + + + Gets or sets FFMpeg process priority (Normal by default) + + + + + Gets or sets user credential used for starting FFMpeg process. + + By default this property is null and FFMpeg process uses credential of parent process (application pool in case of ASP.NET). + + + + Gets or sets ffmpeg loglevel option (by default is "info"). + + + + + Provides data for ConvertProgress event + + + + + Total media stream duration + + + + + Processed media stream duration + + + + + Provides data for log received event + + + + + Log line + + + + diff --git a/SLAM/lib/NReco.VideoConverter.dll b/SLAM/lib/NReco.VideoConverter.dll new file mode 100644 index 0000000..4337a6d Binary files /dev/null and b/SLAM/lib/NReco.VideoConverter.dll differ