{"id":1406,"date":"2013-02-21T19:14:29","date_gmt":"2013-02-22T03:14:29","guid":{"rendered":"https:\/\/surfrock66.com\/?p=1406"},"modified":"2013-02-26T11:49:08","modified_gmt":"2013-02-26T19:49:08","slug":"bash-script-to-clip-ripped-home-movies","status":"publish","type":"post","link":"https:\/\/surfrock66.com\/?p=1406","title":{"rendered":"Bash Script to Clip Ripped Home Movies"},"content":{"rendered":"<p>Bash script I wrote to assist in clipping home movies.  Still some more to do, but here's a summary.<\/p><p>Particularly useful was the code I used to find the difference under bash between start and end points using date...and keeping the result in a format ffmpeg could understand.<\/p>\n<p><code>#!\/bin\/bash<br \/>\n#&nbsp;<br \/>\n#&nbsp;Title:&nbsp;HomeMoviesClipper.sh<br \/>\n#&nbsp;Description:&nbsp;Use&nbsp;ffmpeg&nbsp;to&nbsp;split&nbsp;raw&nbsp;home&nbsp;movie&nbsp;captures&nbsp;into&nbsp;clips<br \/>\n#&nbsp;Original&nbsp;Author:&nbsp;Joseph&nbsp;Gullo&nbsp;(surfrock66)&nbsp;(surfrock66@surfrock66.com)<br \/>\n#<br \/>\n#&nbsp;This&nbsp;script&nbsp;works&nbsp;with&nbsp;a&nbsp;very&nbsp;specific&nbsp;set&nbsp;of&nbsp;constraints&nbsp;and&nbsp;formats&nbsp;to&nbsp;<br \/>\n#&nbsp;&nbsp;take&nbsp;raw&nbsp;video&nbsp;captures&nbsp;and&nbsp;split&nbsp;them&nbsp;into&nbsp;clips&nbsp;of&nbsp;events.&nbsp;&nbsp;Each&nbsp;of&nbsp;<br \/>\n#&nbsp;&nbsp;these&nbsp;movies&nbsp;was&nbsp;captured,&nbsp;using&nbsp;a&nbsp;Dazzle&nbsp;USB&nbsp;video&nbsp;capture&nbsp;device,&nbsp;<br \/>\n#&nbsp;&nbsp;into&nbsp;h264&nbsp;video&nbsp;and&nbsp;mp3&nbsp;audio,&nbsp;using&nbsp;VLC.&nbsp;&nbsp;These&nbsp;original&nbsp;tapes&nbsp;were&nbsp;<br \/>\n#&nbsp;&nbsp;typically&nbsp;close&nbsp;to&nbsp;2&nbsp;hours&nbsp;long,&nbsp;however&nbsp;capture&nbsp;was&nbsp;often&nbsp;left&nbsp;to&nbsp;run,&nbsp;<br \/>\n#&nbsp;&nbsp;creating&nbsp;videos&nbsp;that&nbsp;were&nbsp;8+&nbsp;hours&nbsp;long.&nbsp;&nbsp;The&nbsp;capture&nbsp;device&nbsp;produced&nbsp;<br \/>\n#&nbsp;&nbsp;video&nbsp;that&nbsp;was&nbsp;480x480&nbsp;and&nbsp;audio&nbsp;that&nbsp;only&nbsp;contains&nbsp;1&nbsp;channel&nbsp;(recorded&nbsp;<br \/>\n#&nbsp;&nbsp;through&nbsp;stereo),&nbsp;and&nbsp;the&nbsp;output&nbsp;video&nbsp;will&nbsp;retain&nbsp;this.&nbsp;&nbsp;The&nbsp;desired&nbsp;<br \/>\n#&nbsp;&nbsp;format&nbsp;is&nbsp;high-bitrate&nbsp;h264&nbsp;and&nbsp;aac&nbsp;audio,&nbsp;encapsulated&nbsp;in&nbsp;.mp4&nbsp;files.&nbsp;<br \/>\n#&nbsp;&nbsp;This&nbsp;script&nbsp;also&nbsp;works&nbsp;within&nbsp;a&nbsp;predictable&nbsp;directory&nbsp;environment&nbsp;<br \/>\n#&nbsp;&nbsp;because&nbsp;of&nbsp;how&nbsp;specific&nbsp;the&nbsp;task&nbsp;is,&nbsp;and&nbsp;because&nbsp;I'm&nbsp;a&nbsp;lazy&nbsp;bastard&nbsp;<br \/>\n#&nbsp;&nbsp;that&nbsp;doesn't&nbsp;want&nbsp;to&nbsp;code&nbsp;bunch&nbsp;of&nbsp;directory&nbsp;logic.&nbsp;&nbsp;The&nbsp;script&nbsp;first&nbsp;<br \/>\n#&nbsp;&nbsp;queries&nbsp;the&nbsp;input&nbsp;file,&nbsp;then&nbsp;works&nbsp;on&nbsp;this&nbsp;file&nbsp;recursing&nbsp;the&nbsp;steps&nbsp;<br \/>\n#&nbsp;&nbsp;for&nbsp;each&nbsp;clip.&nbsp;&nbsp;Each&nbsp;clip&nbsp;requires&nbsp;an&nbsp;output&nbsp;name,&nbsp;a&nbsp;start&nbsp;timecode&nbsp;<br \/>\n#&nbsp;&nbsp;(formatted&nbsp;hh:mm:ss.nnn)&nbsp;and&nbsp;an&nbsp;ending&nbsp;timecode.&nbsp;&nbsp;This&nbsp;is&nbsp;part&nbsp;of&nbsp;<br \/>\n#&nbsp;&nbsp;some&nbsp;of&nbsp;the&nbsp;headache,&nbsp;as&nbsp;ffmpeg&nbsp;processes&nbsp;clips&nbsp;with&nbsp;a&nbsp;start&nbsp;time&nbsp;<br \/>\n#&nbsp;&nbsp;and&nbsp;a&nbsp;duration,&nbsp;meaning&nbsp;you&nbsp;have&nbsp;to&nbsp;do&nbsp;the&nbsp;difference&nbsp;math&nbsp;yourself.&nbsp;&nbsp;<br \/>\n#&nbsp;&nbsp;I&nbsp;take&nbsp;care&nbsp;of&nbsp;this&nbsp;in&nbsp;there.&nbsp;&nbsp;After&nbsp;producing&nbsp;a&nbsp;clip,&nbsp;the&nbsp;script&nbsp;<br \/>\n#&nbsp;&nbsp;will&nbsp;ask&nbsp;the&nbsp;user&nbsp;if&nbsp;they&nbsp;want&nbsp;to&nbsp;create&nbsp;another&nbsp;clip&nbsp;from&nbsp;the&nbsp;same&nbsp;<br \/>\n#&nbsp;&nbsp;source&nbsp;file,&nbsp;at&nbsp;which&nbsp;it&nbsp;recurses&nbsp;through&nbsp;a&nbsp;prompting&nbsp;loop.&nbsp;&nbsp;The&nbsp;<br \/>\n#&nbsp;&nbsp;script&nbsp;also&nbsp;can&nbsp;be&nbsp;run&nbsp;from&nbsp;the&nbsp;command&nbsp;line...however&nbsp;in&nbsp;CLI&nbsp;mode,&nbsp;<br \/>\n#&nbsp;&nbsp;the&nbsp;intent&nbsp;is&nbsp;to&nbsp;NOT&nbsp;allow&nbsp;the&nbsp;script&nbsp;to&nbsp;re-prompt&nbsp;for&nbsp;additional&nbsp;cips&nbsp;<br \/>\n#&nbsp;&nbsp;from&nbsp;the&nbsp;same&nbsp;source&nbsp;video.<br \/>\n#&nbsp;<br \/>\n#&nbsp;The&nbsp;script&nbsp;can&nbsp;optionally&nbsp;take&nbsp;4&nbsp;command&nbsp;line&nbsp;arguments:<br \/>\n#&nbsp;&nbsp;1)&nbsp;The&nbsp;filename&nbsp;for&nbsp;the&nbsp;source&nbsp;video,&nbsp;without&nbsp;extension<br \/>\n#&nbsp;&nbsp;2)&nbsp;The&nbsp;desired&nbsp;resulting&nbsp;clip&nbsp;name,&nbsp;without&nbsp;extension<br \/>\n#&nbsp;&nbsp;3)&nbsp;The&nbsp;start&nbsp;timecode&nbsp;for&nbsp;the&nbsp;clip,&nbsp;format&nbsp;hh:mm:ss.nnn<br \/>\n#&nbsp;&nbsp;4)&nbsp;The&nbsp;end&nbsp;timecode&nbsp;for&nbsp;the&nbsp;clip,&nbsp;format&nbsp;hh:mm:ss.nnn<br \/>\n#<br \/>\n#&nbsp;Variables:<br \/>\n#&nbsp;&nbsp;INPUTFILE&nbsp;-&nbsp;Input&nbsp;video&nbsp;filename,&nbsp;without&nbsp;extension<br \/>\n#&nbsp;&nbsp;OUTPUTFILE&nbsp;-&nbsp;Clip&nbsp;output&nbsp;filename,&nbsp;without&nbsp;extension<br \/>\n#&nbsp;&nbsp;STARTTIME&nbsp;-&nbsp;Clip&nbsp;starting&nbsp;timecode,&nbsp;format&nbsp;hh:mm:ss.nnn<br \/>\n#&nbsp;&nbsp;ENDTIME&nbsp;-&nbsp;Clip&nbsp;ending&nbsp;timecode,&nbsp;format&nbsp;hh:mm:ss.nnn<br \/>\n#&nbsp;&nbsp;NANODIFF&nbsp;-&nbsp;Difference&nbsp;between&nbsp;start&nbsp;and&nbsp;end&nbsp;timecode,&nbsp;in&nbsp;milliseconds<br \/>\n#&nbsp;&nbsp;NUMSECS&nbsp;-&nbsp;Timecoe&nbsp;difference&nbsp;in&nbsp;whole&nbsp;seconds<br \/>\n#&nbsp;&nbsp;NUMNANO&nbsp;-&nbsp;Timecode&nbsp;difference&nbsp;remainder&nbsp;in&nbsp;milliseconds<br \/>\n#&nbsp;&nbsp;REPLY&nbsp;-&nbsp;Flag&nbsp;for&nbsp;checking&nbsp;if&nbsp;the&nbsp;script&nbsp;should&nbsp;create&nbsp;another&nbsp;clip<br \/>\n#&nbsp;&nbsp;CLIFLAG&nbsp;-&nbsp;Flag&nbsp;set&nbsp;if&nbsp;command&nbsp;line&nbsp;mode&nbsp;is&nbsp;detected,&nbsp;to&nbsp;prevent&nbsp;prompting<br \/>\n#<\/p>\n<p>#&nbsp;Prompt&nbsp;the&nbsp;user&nbsp;for&nbsp;all&nbsp;parameters,&nbsp;by&nbsp;asking&nbsp;for&nbsp;the&nbsp;source&nbsp;clip&nbsp;name,&nbsp;then&nbsp;calling<br \/>\n#&nbsp;&nbsp;the&nbsp;function&nbsp;which&nbsp;prompts&nbsp;for&nbsp;the&nbsp;clip&nbsp;info.&nbsp;&nbsp;This&nbsp;can&nbsp;safely&nbsp;call&nbsp;the&nbsp;clip-info&nbsp;<br \/>\n#&nbsp;&nbsp;prompting&nbsp;function,&nbsp;as&nbsp;this&nbsp;should&nbsp;only&nbsp;be&nbsp;used&nbsp;once&nbsp;per&nbsp;execution,&nbsp;if&nbsp;at&nbsp;all.<br \/>\nPROMPTFULL()&nbsp;{<br \/>\n&nbsp;&nbsp;echo&nbsp;\"---What&nbsp;is&nbsp;the&nbsp;source&nbsp;video&nbsp;name?&nbsp;(No&nbsp;Extension)&nbsp;(Inside&nbsp;\/home\/surfrock66\/Videos\/HomeMoviesRaw\/):\"<br \/>\n&nbsp;&nbsp;#&nbsp;First&nbsp;point&nbsp;of&nbsp;possible&nbsp;declaration&nbsp;for&nbsp;INPUTFILE<br \/>\n&nbsp;&nbsp;read&nbsp;INPUTFILE<br \/>\n&nbsp;&nbsp;#&nbsp;Execute&nbsp;the&nbsp;PROMPCLIP&nbsp;function<br \/>\n&nbsp;&nbsp;PROMPTCLIP<br \/>\n}<\/p>\n<p>#&nbsp;Prompt&nbsp;the&nbsp;user&nbsp;for&nbsp;the&nbsp;clip&nbsp;name,&nbsp;start&nbsp;time,&nbsp;and&nbsp;end&nbsp;time.&nbsp;&nbsp;<br \/>\nPROMPTCLIP()&nbsp;{<br \/>\n&nbsp;&nbsp;echo&nbsp;\"---What&nbsp;is&nbsp;the&nbsp;output&nbsp;filename&nbsp;for&nbsp;this&nbsp;clip?&nbsp;(No&nbsp;Extension):\"<br \/>\n&nbsp;&nbsp;#&nbsp;First&nbsp;point&nbsp;of&nbsp;possible&nbsp;declaration&nbsp;for&nbsp;OUTPUTFILE<br \/>\n&nbsp;&nbsp;read&nbsp;OUTPUTFILE<br \/>\n&nbsp;&nbsp;echo&nbsp;\"---What&nbsp;is&nbsp;the&nbsp;timecode&nbsp;for&nbsp;the&nbsp;start&nbsp;of&nbsp;this&nbsp;clip?&nbsp;(##:##:##.###):\"<br \/>\n&nbsp;&nbsp;#&nbsp;First&nbsp;point&nbsp;of&nbsp;possible&nbsp;declaration&nbsp;for&nbsp;STARTTIME<br \/>\n&nbsp;&nbsp;read&nbsp;STARTTIME<br \/>\n&nbsp;&nbsp;echo&nbsp;\"---What&nbsp;is&nbsp;the&nbsp;timecode&nbsp;for&nbsp;the&nbsp;end&nbsp;of&nbsp;this&nbsp;clip?&nbsp;(##:##:##.###):\"<br \/>\n&nbsp;&nbsp;#&nbsp;First&nbsp;point&nbsp;of&nbsp;possible&nbsp;declaration&nbsp;for&nbsp;ENDTIME<br \/>\n&nbsp;&nbsp;read&nbsp;ENDTIME<br \/>\n}<\/p>\n<p>#&nbsp;This&nbsp;function&nbsp;handles&nbsp;the&nbsp;timecode&nbsp;calculations&nbsp;to&nbsp;find&nbsp;the&nbsp;clip&nbsp;duration,&nbsp;<br \/>\n#&nbsp;&nbsp;then&nbsp;executes&nbsp;the&nbsp;actial&nbsp;ffmpeg&nbsp;command.<br \/>\nPROCESSVID()&nbsp;{<br \/>\n&nbsp;&nbsp;#&nbsp;Calculate&nbsp;the&nbsp;actuall&nbsp;difference,&nbsp;in&nbsp;milliseconds&nbsp;(but&nbsp;we'll&nbsp;call&nbsp;them&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;nanoseconds,&nbsp;because&nbsp;that's&nbsp;how&nbsp;the&nbsp;date&nbsp;command&nbsp;works)&nbsp;between&nbsp;the&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;start&nbsp;time&nbsp;and&nbsp;end&nbsp;time.&nbsp;&nbsp;This&nbsp;relies&nbsp;heavily&nbsp;on&nbsp;the&nbsp;\"date\"&nbsp;command.&nbsp;&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;It&nbsp;can&nbsp;convert&nbsp;formatted&nbsp;timecodes&nbsp;between&nbsp;different&nbsp;format&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;conventions,&nbsp;but&nbsp;to&nbsp;go&nbsp;from&nbsp;something&nbsp;resembling&nbsp;a&nbsp;standard&nbsp;video&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;editing&nbsp;timecode&nbsp;to&nbsp;a&nbsp;raw&nbsp;nanosecond&nbsp;count&nbsp;is&nbsp;a&nbsp;PAIN&nbsp;IN&nbsp;THE&nbsp;ASS.&nbsp;&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;This&nbsp;strips&nbsp;out&nbsp;the&nbsp;amount&nbsp;of&nbsp;hours&nbsp;in&nbsp;milliseconds,&nbsp;then&nbsp;the&nbsp;number&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;of&nbsp;minutes&nbsp;in&nbsp;milliseconds,&nbsp;then&nbsp;the&nbsp;number&nbsp;of&nbsp;seconds&nbsp;in&nbsp;milliseconds,&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;then&nbsp;the&nbsp;number&nbsp;of&nbsp;nanoseconds&nbsp;in&nbsp;milliseconds.&nbsp;&nbsp;It&nbsp;then&nbsp;adds&nbsp;them&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;together,&nbsp;creates&nbsp;a&nbsp;full&nbsp;millisecond&nbsp;count&nbsp;for&nbsp;the&nbsp;start&nbsp;an&nbsp;end&nbsp;time,&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;and&nbsp;then&nbsp;finds&nbsp;the&nbsp;difference,&nbsp;in&nbsp;milliseconds.<br \/>\n&nbsp;&nbsp;NANODIFF=$(($(($(($(date&nbsp;-d&nbsp;$ENDTIME&nbsp;+%-H)&nbsp;*&nbsp;3600000))&nbsp;+&nbsp;$(($(date&nbsp;-d&nbsp;$ENDTIME&nbsp;+%-M)&nbsp;*&nbsp;60000))&nbsp;+&nbsp;$(($(date&nbsp;-d&nbsp;$ENDTIME&nbsp;+%-S)&nbsp;*&nbsp;1000))&nbsp;+&nbsp;$(($(date&nbsp;-d&nbsp;$ENDTIME&nbsp;+%-N)&nbsp;\/&nbsp;1000000))))&nbsp;-&nbsp;$(($(($(date&nbsp;-d&nbsp;$STARTTIME&nbsp;+%-H)&nbsp;*&nbsp;3600000))&nbsp;+&nbsp;$(($(date&nbsp;-d&nbsp;$STARTTIME&nbsp;+%-M)&nbsp;*&nbsp;60000))&nbsp;+&nbsp;$(($(date&nbsp;-d&nbsp;$STARTTIME&nbsp;+%-S)&nbsp;*&nbsp;1000))&nbsp;+&nbsp;$(($(date&nbsp;-d&nbsp;$STARTTIME&nbsp;+%-N)&nbsp;\/&nbsp;1000000))))))<br \/>\n&nbsp;&nbsp;#&nbsp;Convert&nbsp;the&nbsp;resulting&nbsp;difference,&nbsp;in&nbsp;millisecodns,&nbsp;into&nbsp;seconds<br \/>\n&nbsp;&nbsp;NUMSECS=$(($NANODIFF&nbsp;\/&nbsp;1000))<br \/>\n&nbsp;&nbsp;#&nbsp;Convert&nbsp;the&nbsp;reaminder&nbsp;of&nbsp;the&nbsp;resulting&nbsp;difference,&nbsp;in&nbsp;milliseconds,<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;to&nbsp;milliseconds<br \/>\n&nbsp;&nbsp;NUMNANO=$(($NANODIFF&nbsp;%&nbsp;1000))<br \/>\n&nbsp;&nbsp;#&nbsp;Print&nbsp;out&nbsp;the&nbsp;ffmpeg&nbsp;command&nbsp;that&nbsp;is&nbsp;generated,&nbsp;mostly&nbsp;for&nbsp;debugging<br \/>\n&nbsp;&nbsp;echo&nbsp;\"\\nCommand:&nbsp;ffmpeg&nbsp;-i&nbsp;\\\"\/home\/surfrock66\/Videos\/HomeMoviesRaw\/$INPUTFILE.mp4\\\"&nbsp;-ss&nbsp;$STARTTIME&nbsp;-t&nbsp;$NUMSECS.$NUMNANO&nbsp;-vcodec&nbsp;libx264&nbsp;-b&nbsp;1500k&nbsp;-s&nbsp;480x480&nbsp;-acodec&nbsp;libfaac&nbsp;-ab&nbsp;192k&nbsp;-ac&nbsp;1&nbsp;-threads&nbsp;8&nbsp;\\\"\/home\/surfrock66\/Videos\/HomeMoviesRaw\/$INPUTFILE\/$OUTPUTFILE.mp4\\\"\\n\"<br \/>\n&nbsp;&nbsp;#&nbsp;Execute&nbsp;the&nbsp;ffmpeg&nbsp;command,&nbsp;this&nbsp;is&nbsp;the&nbsp;big&nbsp;kahuna.<br \/>\n&nbsp;&nbsp;ffmpeg&nbsp;-i&nbsp;\"\/home\/surfrock66\/Videos\/HomeMoviesRaw\/$INPUTFILE.mp4\"&nbsp;-ss&nbsp;$STARTTIME&nbsp;-t&nbsp;$NUMSECS.$NUMNANO&nbsp;-vcodec&nbsp;libx264&nbsp;-b&nbsp;1500k&nbsp;-s&nbsp;480x480&nbsp;-acodec&nbsp;libfaac&nbsp;-ab&nbsp;192k&nbsp;-ac&nbsp;1&nbsp;-threads&nbsp;8&nbsp;\"\/home\/surfrock66\/Videos\/HomeMoviesRaw\/$INPUTFILE\/$OUTPUTFILE.mp4\"<br \/>\n}<\/p>\n<p>#&nbsp;Start&nbsp;of&nbsp;the&nbsp;main&nbsp;script.&nbsp;&nbsp;Section&nbsp;1:&nbsp;Input&nbsp;validation<br \/>\n#&nbsp;&nbsp;Check&nbsp;that&nbsp;there&nbsp;is&nbsp;a&nbsp;first&nbsp;parameter.&nbsp;&nbsp;If&nbsp;not,&nbsp;Prompt&nbsp;the&nbsp;user&nbsp;for&nbsp;the<br \/>\n#&nbsp;&nbsp;&nbsp;parameters.&nbsp;&nbsp;If&nbsp;there&nbsp;is&nbsp;one,&nbsp;validate&nbsp;the&nbsp;rest&nbsp;of&nbsp;the&nbsp;params,&nbsp;then&nbsp;<br \/>\n#&nbsp;&nbsp;&nbsp;either&nbsp;prompt&nbsp;the&nbsp;user,&nbsp;or&nbsp;use&nbsp;the&nbsp;passed&nbsp;params.<br \/>\nif&nbsp;[&nbsp;-z&nbsp;\"$1\"&nbsp;]<br \/>\nthen<br \/>\n&nbsp;&nbsp;#&nbsp;Call&nbsp;the&nbsp;prompt&nbsp;function,&nbsp;including&nbsp;asking&nbsp;for&nbsp;the&nbsp;source&nbsp;video<br \/>\n&nbsp;&nbsp;PROMPTFULL<br \/>\nelse<br \/>\n&nbsp;&nbsp;#&nbsp;Assuming&nbsp;the&nbsp;first&nbsp;parameter&nbsp;exists,&nbsp;check&nbsp;for&nbsp;parameters&nbsp;2,3,&nbsp;and<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;4.&nbsp;&nbsp;I'm&nbsp;not&nbsp;validating&nbsp;these&nbsp;strings,&nbsp;mostly&nbsp;because&nbsp;ffmpeg&nbsp;will&nbsp;<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;flip&nbsp;out&nbsp;if&nbsp;there's&nbsp;something&nbsp;wrong&nbsp;with&nbsp;them...as&nbsp;you&nbsp;know,&nbsp;it's<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;quite&nbsp;verbose.<br \/>\n&nbsp;&nbsp;if&nbsp;[&nbsp;-z&nbsp;\"$2\"&nbsp;-o&nbsp;-z&nbsp;\"$3\"&nbsp;-o&nbsp;-z&nbsp;\"$4\"&nbsp;]<br \/>\n&nbsp;&nbsp;then<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;If&nbsp;any&nbsp;parameters&nbsp;are&nbsp;invalid,&nbsp;prompt&nbsp;for&nbsp;them&nbsp;all.&nbsp;Even&nbsp;if&nbsp;param&nbsp;1<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;is&nbsp;successfully&nbsp;detected,&nbsp;re-ask&nbsp;for&nbsp;it.&nbsp;&nbsp;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"--Parameters&nbsp;are&nbsp;incomplete,&nbsp;switching&nbsp;to&nbsp;prompt&nbsp;mode.\"<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;PROMPTFULL&nbsp;<br \/>\n&nbsp;&nbsp;else<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Pass&nbsp;all&nbsp;the&nbsp;command&nbsp;line&nbsp;parameters&nbsp;to&nbsp;the&nbsp;variables<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;INPUTFILE=\"$1\"<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;OUTPUTFILE=\"$2\"<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;STARTTIME=\"$3\"<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;ENDTIME=\"$4\"<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Change&nbsp;the&nbsp;flag&nbsp;to&nbsp;indicate&nbsp;later&nbsp;that&nbsp;this&nbsp;initiated&nbsp;by&nbsp;CLI<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;CLIFLAG=\"yes\"<br \/>\n&nbsp;&nbsp;fi<br \/>\nfi<\/p>\n<p>#&nbsp;Create&nbsp;the&nbsp;default&nbsp;output&nbsp;directory,&nbsp;if&nbsp;it's&nbsp;not&nbsp;already&nbsp;created<br \/>\nif&nbsp;[&nbsp;!&nbsp;-d&nbsp;\/home\/surfrock66\/Videos\/HomeMoviesRaw\/$INPUTFILE&nbsp;];&nbsp;then<br \/>\n&nbsp;&nbsp;mkdir&nbsp;\/home\/surfrock66\/Videos\/HomeMoviesRaw\/$INPUTFILE<br \/>\nfi<\/p>\n<p>#&nbsp;Now...initiate&nbsp;the&nbsp;final&nbsp;video&nbsp;processing<br \/>\n#&nbsp;&nbsp;Declare&nbsp;and&nbsp;initiate&nbsp;the&nbsp;REPLY&nbsp;flag...can&nbsp;be&nbsp;set&nbsp;to&nbsp;anything&nbsp;byt&nbsp;n\/N<br \/>\nREPLY=\"y\"<br \/>\n#&nbsp;As&nbsp;long&nbsp;as&nbsp;the&nbsp;REPLY&nbsp;flag&nbsp;isn't&nbsp;n&nbsp;or&nbsp;N,&nbsp;repeat&nbsp;the&nbsp;loop<br \/>\nwhile&nbsp;[&nbsp;\"$REPLY\"&nbsp;!=&nbsp;\"n\"&nbsp;]&nbsp;&&&nbsp;[&nbsp;\"$REPLY\"&nbsp;!=&nbsp;\"N\"&nbsp;]<br \/>\ndo<br \/>\n&nbsp;&nbsp;#&nbsp;Call&nbsp;the&nbsp;function&nbsp;PROCESSVID<br \/>\n&nbsp;&nbsp;PROCESSVID<br \/>\n&nbsp;&nbsp;#&nbsp;Check&nbsp;to&nbsp;see&nbsp;if&nbsp;the&nbsp;script&nbsp;was&nbsp;run&nbsp;with&nbsp;command&nbsp;line&nbsp;parameters,<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;If&nbsp;not,&nbsp;issue&nbsp;a&nbsp;bunch&nbsp;of&nbsp;logic&nbsp;to&nbsp;see&nbsp;if&nbsp;we&nbsp;want&nbsp;to&nbsp;re-run&nbsp;the<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;code&nbsp;for&nbsp;new&nbsp;clips<br \/>\n&nbsp;&nbsp;if&nbsp;[&nbsp;-z&nbsp;\"$CLIFLAG\"&nbsp;]<br \/>\n&nbsp;&nbsp;then<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Now&nbsp;that&nbsp;we&nbsp;know&nbsp;the&nbsp;script&nbsp;was&nbsp;run&nbsp;in&nbsp;prompt&nbsp;mode,&nbsp;ask&nbsp;the&nbsp;user<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;&nbsp;if&nbsp;they&nbsp;want&nbsp;to&nbsp;make&nbsp;another&nbsp;clip,&nbsp;repeating&nbsp;this&nbsp;loop<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;\"---Would&nbsp;you&nbsp;like&nbsp;to&nbsp;create&nbsp;another&nbsp;clip&nbsp;from&nbsp;this&nbsp;input&nbsp;video?&nbsp;{Y\/n}\"<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;read&nbsp;REPLY<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;[&nbsp;\"$REPLY\"&nbsp;!=&nbsp;\"n\"&nbsp;]&nbsp;&&&nbsp;[&nbsp;\"$REPLY\"&nbsp;!=&nbsp;\"N\"&nbsp;]<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;then<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PROMPTCLIP<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;fi<br \/>\n&nbsp;&nbsp;#&nbsp;If&nbsp;it&nbsp;was&nbsp;run&nbsp;by&nbsp;command&nbsp;line,&nbsp;essentially&nbsp;abort&nbsp;the&nbsp;loop,<br \/>\n&nbsp;&nbsp;#&nbsp;&nbsp;and&nbsp;the&nbsp;script.<br \/>\n&nbsp;&nbsp;else<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;REPLY=\"n\"<br \/>\n&nbsp;&nbsp;fi<br \/>\ndone<br \/>\n<\/code><\/p>\n","protected":false},"excerpt":{"rendered":"<p>#!\/bin\/bash #&nbsp; #&nbsp;Title:&nbsp;HomeMoviesClipper.sh #&nbsp;Description:&nbsp;Use&nbsp;ffmpeg&nbsp;to&nbsp;split&nbsp;raw&nbsp;home&nbsp;movie&nbsp;captures&nbsp;into&nbsp;clips #&nbsp;Original&nbsp;Author:&nbsp;Joseph&nbsp;Gullo&nbsp;(surfrock66)&nbsp;(surfrock66@surfrock66.com) # #&nbsp;This&nbsp;script&nbsp;works&nbsp;with&nbsp;a&nbsp;very&nbsp;specific&nbsp;set&nbsp;of&nbsp;constraints&nbsp;and&nbsp;formats&nbsp;to&nbsp; #&nbsp;&nbsp;take&nbsp;raw&nbsp;video&nbsp;captures&nbsp;and&nbsp;split&nbsp;them&nbsp;into&nbsp;clips&nbsp;of&nbsp;events.&nbsp;&nbsp;Each&nbsp;of&nbsp; #&nbsp;&nbsp;these&nbsp;movies&nbsp;was&nbsp;captured,&nbsp;using&nbsp;a&nbsp;Dazzle&nbsp;USB&nbsp;video&nbsp;capture&nbsp;device,&nbsp; #&nbsp;&nbsp;into&nbsp;h264&nbsp;video&nbsp;and&nbsp;mp3&nbsp;audio,&nbsp;using&nbsp;VLC.&nbsp;&nbsp;These&nbsp;original&nbsp;tapes&nbsp;were&nbsp; #&nbsp;&nbsp;typically&nbsp;close&nbsp;to&nbsp;2&nbsp;hours&nbsp;long,&nbsp;however&nbsp;capture&nbsp;was&nbsp;often&nbsp;left&nbsp;to&nbsp;run,&nbsp; #&nbsp;&nbsp;creating&nbsp;videos&nbsp;that&nbsp;were&nbsp;8+&nbsp;hours&nbsp;long.&nbsp;&nbsp;The&nbsp;capture&nbsp;device&nbsp;produced&nbsp; #&nbsp;&nbsp;video&nbsp;that&nbsp;was&nbsp;480&#215;480&nbsp;and&nbsp;audio&nbsp;that&nbsp;only&nbsp;contains&nbsp;1&nbsp;channel&nbsp;(recorded&nbsp; #&nbsp;&nbsp;through&nbsp;stereo),&nbsp;and&nbsp;the&nbsp;output&nbsp;video&nbsp;will&nbsp;retain&nbsp;this.&nbsp;&nbsp;The&nbsp;desired&nbsp; #&nbsp;&nbsp;format&nbsp;is&nbsp;high-bitrate&nbsp;h264&nbsp;and&nbsp;aac&nbsp;audio,&nbsp;encapsulated&nbsp;in&nbsp;.mp4&nbsp;files.&nbsp; #&nbsp;&nbsp;This&nbsp;script&nbsp;also&nbsp;works&nbsp;within&nbsp;a&nbsp;predictable&nbsp;directory&nbsp;environment&nbsp; #&nbsp;&nbsp;because&nbsp;of&nbsp;how&nbsp;specific&nbsp;the&nbsp;task&nbsp;is,&nbsp;and&nbsp;because&nbsp;I&#8217;m&nbsp;a&nbsp;lazy&nbsp;bastard&nbsp; #&nbsp;&nbsp;that&nbsp;doesn&#8217;t&nbsp;want&nbsp;to&nbsp;code&nbsp;bunch&nbsp;of&nbsp;directory&nbsp;logic.&nbsp;&nbsp;The&nbsp;script&nbsp;first&nbsp; #&nbsp;&nbsp;queries&nbsp;the&nbsp;input&nbsp;file,&nbsp;then&nbsp;works&nbsp;on&nbsp;this&nbsp;file&nbsp;recursing&nbsp;the&nbsp;steps&nbsp; #&nbsp;&nbsp;for&nbsp;each&nbsp;clip.&nbsp;&nbsp;Each&nbsp;clip&nbsp;requires&nbsp;an&nbsp;output&nbsp;name,&nbsp;a&nbsp;start&nbsp;timecode&nbsp; #&nbsp;&nbsp;(formatted&nbsp;hh:mm:ss.nnn)&nbsp;and&nbsp;an&nbsp;ending&nbsp;timecode.&nbsp;&nbsp;This&nbsp;is&nbsp;part&nbsp;of&nbsp; #&nbsp;&nbsp;some&nbsp;of&nbsp;the&nbsp;headache,&nbsp;as&nbsp;ffmpeg&nbsp;processes&nbsp;clips&nbsp;with&nbsp;a&nbsp;start&nbsp;time&nbsp; #&nbsp;&nbsp;and&nbsp;a&nbsp;duration,&nbsp;meaning&nbsp;you&nbsp;have&nbsp;to&nbsp;do&nbsp;the&nbsp;difference&nbsp;math&nbsp;yourself.&nbsp;&nbsp; #&nbsp;&nbsp;I&nbsp;take&nbsp;care&nbsp;of&nbsp;this&nbsp;in&nbsp;there.&nbsp;&nbsp;After&nbsp;producing&nbsp;a&nbsp;clip,&nbsp;the&nbsp;script&nbsp; #&nbsp;&nbsp;will&nbsp;ask&nbsp;the&nbsp;user&nbsp;if&nbsp;they&nbsp;want&nbsp;to&nbsp;create&nbsp;another&nbsp;clip&nbsp;from&nbsp;the&nbsp;same&nbsp; #&nbsp;&nbsp;source&nbsp;file,&nbsp;at&nbsp;which&nbsp;it&nbsp;recurses&nbsp;through&nbsp;a&nbsp;prompting&nbsp;loop.&nbsp;&nbsp;The&nbsp; #&nbsp;&nbsp;script&nbsp;also&nbsp;can&nbsp;be&nbsp;run&nbsp;from&nbsp;the&nbsp;command&nbsp;line&#8230;however&nbsp;in&nbsp;CLI&nbsp;mode,&nbsp; #&nbsp;&nbsp;the&nbsp;intent&nbsp;is&nbsp;to&nbsp;NOT&nbsp;allow&nbsp;the&nbsp;script&nbsp;to&nbsp;re-prompt&nbsp;for&nbsp;additional&nbsp;cips&nbsp; #&nbsp;&nbsp;from&nbsp;the&nbsp;same&nbsp;source&nbsp;video. #&nbsp; #&nbsp;The&nbsp;script&nbsp;can&nbsp;optionally&nbsp;take&nbsp;4&nbsp;command&nbsp;line&nbsp;arguments: #&nbsp;&nbsp;1)&nbsp;The&nbsp;filename&nbsp;for&nbsp;the&nbsp;source&nbsp;video,&nbsp;without&nbsp;extension #&nbsp;&nbsp;2)&nbsp;The&nbsp;desired&nbsp;resulting&nbsp;clip&nbsp;name,&nbsp;without&nbsp;extension #&nbsp;&nbsp;3)&nbsp;The&nbsp;start&nbsp;timecode&nbsp;for&nbsp;the&nbsp;clip,&nbsp;format&nbsp;hh:mm:ss.nnn #&nbsp;&nbsp;4)&nbsp;The&nbsp;end&nbsp;timecode&nbsp;for&nbsp;the&nbsp;clip,&nbsp;format&nbsp;hh:mm:ss.nnn # #&nbsp;Variables: #&nbsp;&nbsp;INPUTFILE&nbsp;&#8211;&nbsp;Input&nbsp;video&nbsp;filename,&nbsp;without&nbsp;extension #&nbsp;&nbsp;OUTPUTFILE&nbsp;&#8211;&nbsp;Clip&nbsp;output&nbsp;filename,&nbsp;without&nbsp;extension #&nbsp;&nbsp;STARTTIME&nbsp;&#8211;&nbsp;Clip&nbsp;starting&nbsp;timecode,&nbsp;format&nbsp;hh:mm:ss.nnn #&nbsp;&nbsp;ENDTIME&nbsp;&#8211;&nbsp;Clip&nbsp;ending&nbsp;timecode,&nbsp;format&nbsp;hh:mm:ss.nnn #&nbsp;&nbsp;NANODIFF&nbsp;&#8211;&nbsp;Difference&nbsp;between&nbsp;start&nbsp;and&nbsp;end&nbsp;timecode,&nbsp;in&nbsp;milliseconds #&nbsp;&nbsp;NUMSECS&nbsp;&#8211;&nbsp;Timecoe&nbsp;difference&nbsp;in&nbsp;whole&nbsp;seconds #&nbsp;&nbsp;NUMNANO&nbsp;&#8211;&nbsp;Timecode&nbsp;difference&nbsp;remainder&nbsp;in&nbsp;milliseconds #&nbsp;&nbsp;REPLY&nbsp;&#8211;&nbsp;Flag&nbsp;for&nbsp;checking&nbsp;if&nbsp;the&nbsp;script&nbsp;should&nbsp;create&nbsp;another&nbsp;clip #&nbsp;&nbsp;CLIFLAG&nbsp;&#8211;&nbsp;Flag&nbsp;set&nbsp;if&nbsp;command&nbsp;line&nbsp;mode&nbsp;is&nbsp;detected,&nbsp;to&nbsp;prevent&nbsp;prompting # #&nbsp;Prompt&nbsp;the&nbsp;user&nbsp;for&nbsp;all&nbsp;parameters,&nbsp;by&nbsp;asking&nbsp;for&nbsp;the&nbsp;source&nbsp;clip&nbsp;name,&nbsp;then&nbsp;calling #&nbsp;&nbsp;the&nbsp;function&nbsp;which&nbsp;prompts&nbsp;for&nbsp;the&nbsp;clip&nbsp;info.&nbsp;&nbsp;This&nbsp;can&nbsp;safely&nbsp;call&nbsp;the&nbsp;clip-info&nbsp; #&nbsp;&nbsp;prompting&nbsp;function,&nbsp;as&nbsp;this&nbsp;should&nbsp;only&nbsp;be&nbsp;used&nbsp;once&nbsp;per&nbsp;execution,&nbsp;if&nbsp;at&nbsp;all. PROMPTFULL()&nbsp;{ &nbsp;&nbsp;echo&nbsp;&#8220;&#8212;What&nbsp;is&nbsp;the&nbsp;source&nbsp;video&nbsp;name?&nbsp;(No&nbsp;Extension)&nbsp;(Inside&nbsp;\/home\/surfrock66\/Videos\/HomeMoviesRaw\/):&#8221; &nbsp;&nbsp;#&nbsp;First&nbsp;point&nbsp;of&nbsp;possible&nbsp;declaration&nbsp;for&nbsp;INPUTFILE &nbsp;&nbsp;read&nbsp;INPUTFILE &nbsp;&nbsp;#&nbsp;Execute&nbsp;the&nbsp;PROMPCLIP&nbsp;function [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,3],"tags":[],"class_list":["post-1406","post","type-post","status-publish","format-standard","hentry","category-geek","category-projects"],"_links":{"self":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1406","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1406"}],"version-history":[{"count":6,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1406\/revisions"}],"predecessor-version":[{"id":1411,"href":"https:\/\/surfrock66.com\/index.php?rest_route=\/wp\/v2\/posts\/1406\/revisions\/1411"}],"wp:attachment":[{"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1406"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1406"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/surfrock66.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1406"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}