11using FFMpegCore ;
2+ using FFMpegCore . Arguments ;
3+ using System . Diagnostics ;
24using System . Drawing . Drawing2D ;
35using System . IO ;
46using System . IO . Enumeration ;
@@ -56,6 +58,28 @@ private void FormMain_Load(object sender, EventArgs e)
5658 radioButtonExtractFiles . Checked = Properties . Settings . Default . CreateSeparateFilesChecked ;
5759 radioButtonInjectToVideo . Checked = Properties . Settings . Default . InjectToVideo ;
5860 textBoxOutputFolder . Text = Properties . Settings . Default . OutputFolder ;
61+ checkBoxClearFormating . Checked = Properties . Settings . Default . ClearFormating ;
62+ checkBoxReplaceLastTopRowLanguageTrackIfNotFirst . Checked = Properties . Settings . Default . ReplaceLastTopLanguageTrackExceptFirst ;
63+ textBoxTopRowFontSize . Text = Properties . Settings . Default . TopRowFontSize ;
64+ textBoxButtomRowFontSize . Text = Properties . Settings . Default . BottomRowFontSize ;
65+
66+ textBoxReplaceTrackLanguage . Text = Properties . Settings . Default . ReplaceTrackLanguage ;
67+
68+ if ( Properties . Settings . Default . RestoreBoundsSize . Width > 0
69+ && Properties . Settings . Default . RestoreBoundsSize . Height > 0 )
70+ {
71+ var restoreBounds = new System . Drawing . Rectangle (
72+ Properties . Settings . Default . RestoreBoundsTopLeft , Properties . Settings . Default . RestoreBoundsSize ) ;
73+ if ( Screen . AllScreens . Any ( screen => screen . WorkingArea . IntersectsWith ( restoreBounds ) ) )
74+ {
75+ StartPosition = FormStartPosition . Manual ;
76+ DesktopBounds = restoreBounds ;
77+ WindowState = FormWindowState . Normal ;
78+ }
79+ }
80+ if ( Properties . Settings . Default . Maximized )
81+ WindowState = FormWindowState . Maximized ;
82+
5983 }
6084
6185 private void FormMain_FormClosing ( object sender , FormClosingEventArgs e )
@@ -69,13 +93,24 @@ private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
6993 Properties . Settings . Default . CreateSeparateFilesChecked = radioButtonExtractFiles . Checked ;
7094 Properties . Settings . Default . InjectToVideo = radioButtonInjectToVideo . Checked ;
7195 Properties . Settings . Default . OutputFolder = textBoxOutputFolder . Text ;
96+
97+ Properties . Settings . Default . ClearFormating = checkBoxClearFormating . Checked ;
98+
99+ Properties . Settings . Default . Maximized = ( WindowState == FormWindowState . Maximized ) ;
100+
101+ Properties . Settings . Default . RestoreBoundsTopLeft = new Point ( DesktopBounds . Left , DesktopBounds . Top ) ;
102+ Properties . Settings . Default . RestoreBoundsSize = DesktopBounds . Size ;
103+ Properties . Settings . Default . ReplaceLastTopLanguageTrackExceptFirst = checkBoxReplaceLastTopRowLanguageTrackIfNotFirst . Checked ;
104+ Properties . Settings . Default . TopRowFontSize = textBoxTopRowFontSize . Text ;
105+ Properties . Settings . Default . BottomRowFontSize = textBoxButtomRowFontSize . Text ;
106+ Properties . Settings . Default . ReplaceTrackLanguage = textBoxReplaceTrackLanguage . Text ;
72107 Properties . Settings . Default . Save ( ) ;
73108 }
74109
75110 private void toolStripButtonStart_Click ( object sender , EventArgs e )
76111 {
77112 if ( backgroundWorker1 . IsBusy ) return ;
78- if ( ! Directory . Exists ( textBoxFFMPEGPath . Text ) )
113+ if ( ! Directory . Exists ( textBoxFFMPEGPath . Text ) )
79114 {
80115 MessageBox . Show ( "Specified video folder does not exist" ) ;
81116 return ;
@@ -95,7 +130,21 @@ private void toolStripButtonStart_Click(object sender, EventArgs e)
95130 MessageBox . Show ( "ffmpeg.exe not found in specified folder" ) ;
96131 return ;
97132 }
98-
133+ int topRowFontSize = 0 ;
134+ if ( ! int . TryParse ( textBoxTopRowFontSize . Text , out topRowFontSize ) )
135+ {
136+ if ( ! int . TryParse ( textBoxTopRowFontSize . Text . Replace ( "px" , string . Empty ) , out topRowFontSize ) )
137+ MessageBox . Show ( "Invalid font size, expect something like 14 or 14px" ) ;
138+ return ;
139+ }
140+ int bottomRowFontSize = 0 ;
141+ if ( ! int . TryParse ( textBoxButtomRowFontSize . Text , out bottomRowFontSize ) )
142+ {
143+ if ( ! int . TryParse ( textBoxButtomRowFontSize . Text . Replace ( "px" , string . Empty ) , out bottomRowFontSize ) )
144+ MessageBox . Show ( "Invalid font size, expect something like 14 or 14px" ) ;
145+ return ;
146+ }
147+
99148 GlobalFFOptions . Configure ( new FFOptions { BinaryFolder = textBoxFFMPEGPath . Text , TemporaryFilesFolder = Path . GetTempPath ( ) } ) ;
100149
101150 backgroundWorker1 . RunWorkerAsync ( new BackgroundWorkerArguments (
@@ -107,12 +156,17 @@ private void toolStripButtonStart_Click(object sender, EventArgs e)
107156 radioButtonExtractFiles . Checked ? BackgroundWorkerWorkMode . ExtractSubtitle
108157 : BackgroundWorkerWorkMode . InjectToVideo
109158 , checkBoxSetAsDefault . Checked
159+ , checkBoxClearFormating . Checked
160+ , checkBoxReplaceLastTopRowLanguageTrackIfNotFirst . Checked
161+ , textBoxTopRowFontSize . Text
162+ , textBoxButtomRowFontSize . Text
163+ , textBoxReplaceTrackLanguage . Text
110164 ) ) ;
111165 }
112166
113167 private void toolStripButtonStop_Click ( object sender , EventArgs e )
114168 {
115- if ( backgroundWorker1 . IsBusy )
169+ if ( backgroundWorker1 . IsBusy )
116170 backgroundWorker1 . CancelAsync ( ) ;
117171 }
118172 private void backgroundWorker1_DoWork ( object sender , System . ComponentModel . DoWorkEventArgs e )
@@ -124,16 +178,16 @@ private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWor
124178 int fileCount = files . Count ( ) ;
125179 if ( fileCount == 0 )
126180 throw new FileNotFoundException ( "No mp4 file under specified folder" ) ;
127- List < Exception > exceptions = new List < Exception > ( ) ;
181+ List < Exception > exceptions = new List < Exception > ( ) ;
128182 int filesProcessed = 0 ;
129- foreach ( var file in files )
183+ foreach ( var file in files )
130184 {
131185 if ( backgroundWorker1 . CancellationPending ) break ;
132186 backgroundWorker1 . ReportProgress (
133187 ( filesProcessed ) * 100 / fileCount ,
134188 string . Format ( "Processing file {0} of {1} :{2}" , filesProcessed + 1 , fileCount , file )
135189 ) ;
136-
190+
137191 try
138192 {
139193 ProcessFile ( file , arguments ) ;
@@ -143,16 +197,16 @@ private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWor
143197 {
144198 exceptions . Add ( ex ) ;
145199 }
146-
200+
147201 filesProcessed ++ ;
148202 }
149203 backgroundWorker1 . ReportProgress (
150204 0 ,
151205 string . Format ( "Processed file {0} of {1}" , filesProcessed , fileCount )
152206 ) ;
153207 if ( exceptions . Any ( ) )
154- {
155- throw new AggregateException ( exceptions . ToArray ( ) ) ;
208+ {
209+ throw new AggregateException ( exceptions . ToArray ( ) ) ;
156210 }
157211 }
158212 private void backgroundWorker1_ProgressChanged ( object sender , System . ComponentModel . ProgressChangedEventArgs e )
@@ -181,7 +235,7 @@ static void ProcessFile(string file, BackgroundWorkerArguments arguments)
181235 if ( parentFolder != null )
182236 Directory . CreateDirectory ( parentFolder ) ;
183237 var tempFolder = Path . GetTempPath ( ) ;
184-
238+
185239 var mediaInfo = FFProbe . Analyse ( file ) ;
186240
187241 if ( mediaInfo != null && mediaInfo . SubtitleStreams != null )
@@ -192,19 +246,19 @@ static void ProcessFile(string file, BackgroundWorkerArguments arguments)
192246 }
193247 var topRowSubtitleStream = mediaInfo . SubtitleStreams . Where (
194248 s => s . Language == arguments . TopRowLanguage
195- && s . CodecName != "dvd_subtitle" ) . FirstOrDefault ( ) ;
249+ && s . CodecName != "dvd_subtitle" ) . FirstOrDefault ( ) ;
196250 var buttonRowSubtitleStream = mediaInfo . SubtitleStreams . Where (
197251 s => s . Language == arguments . BottomRowLanguage && s . CodecName != "dvd_subtitle" ) . FirstOrDefault ( ) ;
198252 SubtitleInfo ? higherSubtitle = SubtitleInfo . FFMPEGReadSubtitleFromFile ( file , topRowSubtitleStream ) ;
199253 SubtitleInfo ? lowerSubtitle = SubtitleInfo . FFMPEGReadSubtitleFromFile ( file , buttonRowSubtitleStream ) ;
200- var mergedSubtitle = SubtitleInfo . Merge ( higherSubtitle , lowerSubtitle ) ;
254+ var mergedSubtitle = SubtitleInfo . Merge ( higherSubtitle , lowerSubtitle , arguments ) ;
201255 SubtitleInfo ? mergedSubtitleInfo ;
202256 if ( mergedSubtitle != null )
203257 {
204258 mergedSubtitleInfo = new SubtitleInfo ( mergedSubtitle ) ;
205259 string ? mergedSubtitleText ;
206260 if ( mergedSubtitleInfo != null )
207- mergedSubtitleText = mergedSubtitleInfo . ToText ( ) ;
261+ mergedSubtitleText = mergedSubtitleInfo . ToText ( arguments . ClearFormating ) ;
208262 switch ( arguments . WorkMode )
209263 {
210264 case BackgroundWorkerWorkMode . ExtractSubtitle :
@@ -235,23 +289,34 @@ static void ProcessFile(string file, BackgroundWorkerArguments arguments)
235289 //check if already injected
236290 if ( subtitleInfos . Any ( s => subtitleInfoToBeInjected . RawData . SequenceEqual ( s . RawData ) ) )
237291 break ;
292+ if ( arguments . ReplaceLastTopRowLanguageTrackIfNotFirst )
293+ {
294+ if ( mediaInfo . SubtitleStreams . Where ( s => s . CodecName != "dvd_subtitle"
295+ && s . Language == arguments . ReplaceTrackLanguage ) . Count ( ) < 2 )
296+ {
297+ throw new FileNotFoundException (
298+ string . Format ( "The specified file {0} does not have more than one of the required subtitle track in the specified replacement language and in text format." , file ) ) ;
299+ }
300+ }
238301 SubtitleInfo . FFMPEGInjectToFile ( file , arguments ,
239- relativePathToRoot , outputVideoFileName , tempSubtitleTargetFile , arguments . TopRowLanguage , mediaInfo ) ;
302+ relativePathToRoot , outputVideoFileName , tempSubtitleTargetFile , arguments . ReplaceTrackLanguage ,
303+ mediaInfo ) ;
240304 break ;
241305 default :
242306 break ;
243307 }
244308 }
245309 else
246310 throw new FileNotFoundException (
247- string . Format ( "The specified file {0} does not have one of the required subtitle track in text format." , file ) ) ;
311+ string . Format ( "The specified file {0} does not have one of the required subtitle track in text format." , file ) ) ;
248312 }
249313 }
250314
251315
252316 static void ExtractSubtitles ( string file , BackgroundWorkerArguments arguments ,
253- string relativePathToRoot , string outputVideoFileName ,
254- IMediaAnalysis mediaInfo , SubtitleStream ? topRowSubtitleStream , SubtitleStream ? buttonRowSubtitleStream , List < MergedSubtitle > ? mergedSubtitle ,
317+ string relativePathToRoot , string outputVideoFileName ,
318+ IMediaAnalysis mediaInfo , SubtitleStream ? topRowSubtitleStream ,
319+ SubtitleStream ? buttonRowSubtitleStream , List < MergedSubtitle > ? mergedSubtitle ,
255320 SubtitleInfo ? mergedSubtitleInfo )
256321 {
257322 foreach ( var subtitleStream in mediaInfo . SubtitleStreams )
@@ -263,7 +328,7 @@ static void ExtractSubtitles(string file, BackgroundWorkerArguments arguments,
263328 var subtitleFileName =
264329 string . Format ( "{0}.{1}.{2}.srt" , outputVideoFileName ,
265330 subtitleStream . Index , subtitleStream . Language ) ;
266- File . WriteAllText ( subtitleFileName , subtitleInfo . ToText ( ) ) ;
331+ File . WriteAllText ( subtitleFileName , subtitleInfo . ToText ( arguments . ClearFormating ) ) ;
267332 }
268333 }
269334
@@ -275,10 +340,35 @@ static void ExtractSubtitles(string file, BackgroundWorkerArguments arguments,
275340 topRowSubtitleStream . Language ,
276341 buttonRowSubtitleStream . Language ) ;
277342 if ( mergedSubtitleInfo != null )
278- File . WriteAllText ( mergeSubtitleFileName , mergedSubtitleInfo . ToText ( ) ) ;
343+ File . WriteAllText ( mergeSubtitleFileName , mergedSubtitleInfo . ToText ( arguments . ClearFormating ) ) ;
279344 }
280345 }
281346
347+ private void buttonFFMPEGPath_Click ( object sender , EventArgs e )
348+ {
349+ BrowseForFolder ( this . textBoxFFMPEGPath , this . textBoxFFMPEGPath . Text , "Select FFMPEG Path" ) ;
350+ }
351+ void BrowseForFolder ( TextBox textBox , string initialFolder , string dialogTitle )
352+ {
353+ using ( FolderBrowserDialog fb = new FolderBrowserDialog ( ) )
354+ {
355+ fb . Description = dialogTitle ;
356+ fb . InitialDirectory = initialFolder ;
357+ if ( fb . ShowDialog ( ) == DialogResult . OK )
358+ {
359+ textBox . Text = fb . SelectedPath ;
360+ }
361+ }
362+ }
282363
364+ private void buttonVideoPath_Click ( object sender , EventArgs e )
365+ {
366+ BrowseForFolder ( this . textBoxVideoPath , this . textBoxVideoPath . Text , "Select Input Video Path" ) ;
367+ }
368+
369+ private void buttonOutputFolder_Click ( object sender , EventArgs e )
370+ {
371+ BrowseForFolder ( this . textBoxOutputFolder , this . textBoxOutputFolder . Text , "Select Output Video Path" ) ;
372+ }
283373 }
284374}
0 commit comments