Nologic 30 Posted March 1, 2015 Share Posted March 1, 2015 (edited) What this solves: 1. On demand creating Roku Bif files recursively through sub folders, using Emby Servers naming scheme. (Simple Dialog Interface, Command Line and SendTo {must be compiled}). 2. Scheduled Bif file creation, 3. Allow networked computers to work on shared folders to speed things along. Only limiting factors are the speed of your network & the number of systems connected. Notes: The Folders this script is to run against must be on ether a local or network mapped drive, as the script isn't setup to handle UNC paths. Also checkout the concurrent version further down in the thread. Requirements: AutoIt FFMpeg Roku SDK Instructions: Install AutoIt and set it to execute scripts when double clicked. Create a folder somewhere...lets call it "Creat BIF" just to be unimaginative. Now inside "Create BIF" create a sub folder called "Bin". Now extract the contents of FFMpeg's "Bin" folder into your new "Bin" sub folder. Now extract "biftool.exe" from the Roku SDK into your new "Bin" sub folder. Now going back into "Create BIF" folder Right Click on it's background and select "New\AutoIt v3 Script" from the context menu, and Rename it "Create BIF.au3" Now Right Click "Create BIF.au3" & select "Edit Script" from the context menu. Now paste the following code into: #Include <Array.au3> #Include <File.au3> #Include <String.au3> Global $iVideoWidthSize = 320 Global $sErrorLog Global $aWeekLong = StringSplit( 'Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday' , '|' ) Global $aWeekShort = StringSplit( 'Sun|Mon|Tue|Wed|Thu|Fri|Sat' , '|' ) Global $iSchedule = 0 Global $sExtension = '*.mkv;*.mp4;*.mov;*.m4v' ; Create Basic Settings If Required $sSavedSettings = @ScriptDir & '\Create Bif.ini' If NOT FileExists( $sSavedSettings ) Then _Settings( $sSavedSettings ) ; Create SendTo Shortcut If StringRight( @ScriptName , 4 ) = '.exe' Then $sSendTo = StringReplace( RegRead( 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders' , 'SendTo' ) , '%USERPROFILE%' , @UserProfileDir ) If StringRight( $sSendTo , 1 ) <> '\' Then $sSendTo &= '\' ; Actual SendTo Shortcut Creation If NOT FileExists( $sSendTo & StringTrimRight( @ScriptName , 4 ) & '.lnk' ) Then FileCreateShortcut( @ScriptDir & '\' & @ScriptName , $sSendTo & StringTrimRight( @ScriptName , 4 ) & '.lnk' , '' , '' , '' , @ScriptDir & '\' & @ScriptName , '' , 0 ) EndIf EndIf ; Remove Temp Files & Folders $aTemps = _FileListToArrayRec( @TempDir , 'Create Biff-*' , 14 , 0 , 1 , 2 ) If IsArray( $aTemps ) Then For $ii = 1 To $aTemps[0] DirRemove( $aTemps[$ii] & '\' , 1 ) Next EndIf ; Select Video Folder If $CmdLine[0] = 0 Then While 1 $sSourceFolder = FileSelectFolder( 'Select Video Folder.' , '' , 6 ) If @[member="ERROR"] = 1 AND $sSourceFolder = '' Then MsgBox( 4096 , 'Exit:' , 'Ending Application' ) Exit ElseIf $sSourceFolder = '' Then MsgBox( 4096 , 'Error:' , 'Unable To Open Folder.' ) ElseIf NOT FileExists ( $sSourceFolder ) Then MsgBox( 4096 , 'Error:' , 'Invalid Folder.' ) Else If StringRight( $sSourceFolder , 1 ) <> '\' Then $sSourceFolder &= '\' $aAllFiles = _FileListToArrayRec( $sSourceFolder , $sExtension , 1 , 1 , 0 , 2 ) If NOT IsArray( $aAllFiles ) Then MsgBox( 4096 , 'Error:' , 'No Videos Found.' ) Else _ArraySort( $aAllFiles , 0 , 1 ) ExitLoop EndIf EndIf WEnd ; One Instance at a Time $RunningScripts = ProcessList( @ScriptName ) For $aa = 1 To $RunningScripts[0][0] If $RunningScripts[$aa][1] <> @AutoItPID Then ProcessWaitClose( $RunningScripts[$aa][1] ) Next _Main( $aAllFiles ) Else Switch $CmdLine[1] ; Run All Bif Tasks Case 'Schedule' $iSchedule = 1 $aEndTime = _ScheduleTaskRead( $sSavedSettings ) $aFolders = IniReadSection( $sSavedSettings , 'Folders' ) For $ii = 1 To $aFolders[0][0] If FileExists( $aFolders[$ii][1] ) Then If StringRight( $aFolders[$ii][1] , 1 ) <> '\' Then $aFolders[$ii][1] &= '\' $aAllFiles = _FileListToArrayRec( $aFolders[$ii][1] , $sExtension , 1 , 1 , 0 , 2 ) If NOT IsArray( $aAllFiles ) Then ContinueLoop _ArraySort( $aAllFiles , 0 , 1 ) _Main( $aAllFiles ) EndIf Next ; Create New Bif Tasks Case 'ScheduleNew' _ScheduleTaskCreate( $sSavedSettings ) Exit ; Delete All Bif Tasks Case 'ScheduleDelete' _ScheduleTaskDelete() Exit ; Process Command Line Files & Folders Case Else For $ii = 1 To $CmdLine[0] ; One Instance at a Time $RunningScripts = ProcessList( @ScriptName ) For $aa = 1 To $RunningScripts[0][0] If $RunningScripts[$aa][1] <> @AutoItPID Then ProcessWaitClose( $RunningScripts[$aa][1] ) Next ; Test if Folder If StringInStr( FileGetAttrib( $CmdLine[$ii] ) , 'D' ) <> 0 Then $sSourceFolder = $CmdLine[$ii] If StringRight( $sSourceFolder , 1 ) <> '\' Then $sSourceFolder &= '\' $aAllFiles = _FileListToArrayRec( $sSourceFolder , $sExtension , 1 , 1 , 0 , 2 ) If NOT IsArray( $aAllFiles ) Then ContinueLoop _ArraySort( $aAllFiles , 0 , 1 ) _Main( $aAllFiles ) Else ; Test if Supported File Type If StringInStr( $sExtension , StringTrimLeft( $CmdLine[$ii] , StringInStr( $CmdLine[$ii] , '.' , 0 , -1 ) - 1 )) <> 0 Then Dim $aAllFiles[2] = [1 , $CmdLine[$ii]] _Main( $aAllFiles ) EndIf EndIf Next EndSwitch EndIf ; Create Error Log If StringLen( $sErrorLog ) > 1 Then If NOT FileExists( @ScriptDir & '\Error Logs\' ) Then DirCreate( @ScriptDir & '\Error Logs\' ) $sErrorLogFile = @ScriptDir & '\Error Logs\[' & @YEAR & '-' & @[member="Mon"] & '-' & @MDAY & '] ' & @HOUR & '-' & @MIN & '.txt' FileWrite( $sErrorLogFile , $sErrorLog ) ShellExecute( $sErrorLogFile ) EndIf MsgBox( 0 , 'Finished:' , 'Batch BIF File Creation Is Complete.' ) Func _Main( ByRef $aArray ) For $ii = 1 To $aArray[0] ; Early Out If $iSchedule = 1 Then If $aEndTime[1] > @HOUR Then Exit If $aEndTime[1] = @HOUR AND $aEndTime[2] >= @MIN Then Exit EndIf ; Create Base Name _FileMacros( $aArray[$ii] ) $sTempName = $sShortName & '-' & $iVideoWidthSize ; Early Out If FileExists( $aArray[$ii] ) = 0 Then ContinueLoop If FileExists( $sFileDir & $sTempName & '.bif' ) Then ContinueLoop ; Create Temp Folder $sTempFolder = @TempDir & '\Create Biff-' & _RandomString() & '\' & $sTempName If NOT FileExists( $sTempFolder ) Then DirCreate( $sTempFolder ) ; Create Images If StringInStr( $sTempFolder , '%' ) <> 0 Then $sTempFolderNew = StringReplace( $sTempFolder , '%' , '%%' ) Else $sTempFolderNew = $sTempFolder EndIf RunWait( @ComSpec & ' /c ffmpeg -i "' & $aArray[$ii] & '" -r .1 -vf "scale=min(iw\,' & $iVideoWidthSize & '):trunc(ow/dar/2)*2:flags=lanczos" -f image2 "' & $sTempFolderNew & '\%08d.jpg"' , @ScriptDir & '\BIN\' , @SW_HIDE ) ; Re Number Images (0 Base Index) $aAllImages = _FileListToArrayRec( $sTempFolder , '*.jpg' , 1 , 1 , 0 , 2 ) If IsArray( $aAllImages ) Then _ArraySort( $aAllImages , 0 , 1 ) For $jj = 1 To $aAllImages[0] FileMove( $aAllImages[$jj] , $sTempFolder & '\' & _StringRepeat( '0' , 8 - StringLen( $jj - 1 )) & $jj - 1 & '.jpg' ) Next Else DirRemove( $sTempFolder , 1 ) $sErrorLog &= 'Could Not Process File:' & @CRLF & $aArray[$ii] & @CRLF & @CRLF ContinueLoop EndIf ; Create Actual BIF File RunWait( @ComSpec & ' /c biftool -t 10000 "' & $sTempFolder & '"' , @ScriptDir & '\BIN\' , @SW_HIDE ) ; Move BIF To Correct Folder FileMove( @ScriptDir & '\BIN\' & $sTempName & '.bif' , $sFileDir , 1 ) ; Delete Temp Folder DirRemove( $sTempFolder , 1 ) Next EndFunc Func _FileMacros( $sInFile ) Global $sFileDir = StringLeft ( $sInFile , StringInStr( $sInFile , '\' , 0 , -1 ) ) Global $sFileExt = StringTrimLeft ( $sInFile , StringInStr( $sInFile , '.' , 0 , -1 ) - 1 ) Global $sFileName = StringTrimLeft ( $sInFile , StringInStr( $sInFile , '\' , 0 , -1 ) ) Global $sShortName = StringLeft ( $sFileName , StringInStr( $sFileName , '.' , 0 , -1 ) - 1 ) Global $sParent = StringTrimLeft ( $sFileDir , StringInStr( $sFileDir , '\' , 0 , -2 ) ) Global $sFolderName = StringTrimRight( StringTrimLeft( $sFileDir , StringInStr( $sFileDir , '\' , 0 , -2 ) ) , 1 ) EndFunc Func _RandomString() Local $sString , $aSpace[3] For $i = 1 To 15 $aSpace[0] = Chr( Random( 65 , 90 , 1 )) ; A-Z $aSpace[1] = Chr( Random( 97 , 122 , 1 )) ; a-z $aSpace[2] = Chr( Random( 48 , 57 , 1 )) ; 0-9 $sString &= $aSpace[Random( 0 , 2 , 1 )] Next Return $sString EndFunc Func _Settings( $sSettingsFile ) $sString = '' For $ii = 1 To $aWeekLong[0] $sString &= '[' & $aWeekLong[$ii] & ']' & @CRLF $sString &= 'Start=03:00' & @CRLF $sString &= 'End=06:00' & @CRLF $sString &= @CRLF Next $sString &= '[Folders]' & @CRLF $sString &= 'Folder_01=' & @CRLF & @CRLF FileWrite( $sSettingsFile , $sString ) EndFunc Func _ScheduleTaskRead( $sSettingsFile ) Return StringSplit( IniRead( $sSettingsFile , $aWeekLong[@WDAY] , 'End' , '06:00' ) , ':' ) EndFunc Func _ScheduleTaskDelete() For $ii = 1 To $aWeekLong[0] ; Remove Old Tasks If Exists RunWait( @ComSpec & ' /c SchTasks /DELETE /TN "Create Bif - ' & $aWeekLong[$ii] & '" /F' , '' , @SW_HIDE ) Next EndFunc Func _ScheduleTaskCreate( $sSettingsFile ) $aFolders = IniReadSection( $sSettingsFile , 'Folders' ) If IsArray( $aFolders ) = 0 Then MsgBox( 48 , 'Error:' , 'Folders in INI Invalid or Missing.' ) Exit EndIf For $ii = 1 To $aFolders[0][0] If FileExists( $aFolders[$ii][1] ) = 0 Then MsgBox( 48 , 'Error:' , 'Folder Invalid.' & @LF & $aFolders[$ii][1] ) Exit EndIf Next For $ii = 1 To $aWeekLong[0] ; Remove Old Task If Exists RunWait( @ComSpec & ' /c SchTasks /DELETE /TN "Create Bif - ' & $aWeekLong[$ii] & '" /F' , '' , @SW_HIDE ) $aTaskStart = StringSplit( IniRead( $sSettingsFile , $aWeekLong[$ii] , 'Start' , '03:00' ) , ':' ) $aTaskEnd = StringSplit( IniRead( $sSettingsFile , $aWeekLong[$ii] , 'End' , '06:00' ) , ':' ) Select Case $aTaskStart[1] < 0 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Hour Less Than 0.' & @LF & $aTaskStart[1] & ':' & $aTaskStart[2] ) Exit Case $aTaskStart[2] < 0 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Minute Less Than 0.' & @LF & $aTaskStart[1] & ':' & $aTaskStart[2] ) Exit Case $aTaskEnd[1] < 0 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Hour Less Than 0.' & @LF & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskEnd[2] < 0 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Minute Less Than 0.' & @LF & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskStart[1] > 24 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Hour Greater Than 24.' & @LF & $aTaskStart[1] & ':' & $aTaskStart[2] ) Exit Case $aTaskStart[2] > 59 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Minute Greater Than 59.' & @LF & $aTaskStart[1] & ':' & $aTaskStart[2] ) Exit Case $aTaskEnd[1] > 24 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Hour Greater Than 24.' & @LF & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskEnd[2] > 59 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Minute Greater Than 59.' & @LF & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskStart[1] > $aTaskEnd[1] MsgBox( 48 , 'Error:' , 'Start Time Hour Greater Than End Time Hour.' & @LF & 'Start: ' & $aTaskStart[1] & ':' & $aTaskStart[2] & @LF & 'End: ' & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskStart[1] = $aTaskEnd[1] AND $aTaskStart[2] > $aTaskEnd[2] MsgBox( 48 , 'Error:' , 'Start Time Minutes Greater Than End Time Minutes.' & @LF & 'Start: ' & $aTaskStart[1] & ':' & $aTaskStart[2] & @LF & 'End: ' & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskStart[1] = $aTaskEnd[1] AND $aTaskStart[2] = $aTaskEnd[2] ContinueLoop EndSelect ; Create New Task RunWait( @ComSpec & ' /c SchTasks /Create /SC WEEKLY /D ' & $aWeekShort[$ii] & ' /TN "Create Bif - ' & $aWeekLong[$ii] & '" /TR "\"' & @ScriptFullPath & '\" Schedule" /ST ' & $aTaskStart[1] & ':' & $aTaskStart[2] & ' /F' , '' , @SW_HIDE ) Next EndFunc Now save the script & execute it by double clicking it and then select the folder holding your videos that you wish to process. Now go do something else, this will take a while...maybe a great while depending on the number of videos you have. The script will notify you when it's done...and if you're currious as to if it's still running there should be a icon in your system tray that looks like a blue "A". Past that you can start your Task Manager and you should more than likely see FFMpeg running in the background. By default this will create 320px aspect correct BIF files, if you wish to create 240px or any other size you'll need to edit line 7. Example: from $iVideoWidthSize = 320 to $iVideoWidthSize = 240 Update 1: I decided to let FFMpeg do all the calculations for resize...which result in a massive code reduction. Update 2: Added passing folders via command line. This is mostly aimed at adding SendTo context menu support. 1. Right Click on "Create BIF.au3" and select "Compile Script (x86)" from the context menu 2. ALT + Left Click on "Create BIF.exe" and Drag to create a shortcut...rename to remove ".exe" from the file name 3. Cut & Paste shortcut to your SendTo folder: %APPDATA%\Microsoft\Windows\SendTo\ Now you don't even need to hunt down the script when you need it. Update 3: Added very simplistic scheduling based on a 24 hour clock. Currently you can not start on one day and end on the following. Only one time block allowed per day. The script now produces an INI that can be edited "Create Bif.ini" If you choose to use the scheduling the script needs to be compiled. Once compiled & the INI edited to your liking, open up a console in the script folder. Then enter: "Create Bif.exe" ScheduleNew Now new tasks have been created in the Windows Task Scheduler. To remove tasks enter: "Create Bif.exe" ScheduleDelete To not have a task scheduled for a day, set the start time and end time to be the same. Update 4: Command Line now supports both Folders & Files...thus making a SendTo shortcut more useful. Update 5: Added auto SendTo shortcut creation...only happens if script is compiled. To trigger this...simply use the executable once...you don't even have to actually process a file. If you don't want this feature simply delete the code on and between lines 17 & 25 (currently) Update 6: Now allows only one instance to run at a time, to prevent bogging down your system. This applies to Command Line and GUI, but not Task Scheduler...as the Task Scheduler should only have one instance anyways. This allows you to cue up several folders\files to be processed, even though they are in very different locations. Update 7: Made it easier for the script to clean up after it's self. Edited February 26, 2016 by Nologic 2 Link to comment Share on other sites More sharing options...
Luke 37060 Posted March 1, 2015 Share Posted March 1, 2015 Well done! Link to comment Share on other sites More sharing options...
Nologic 30 Posted March 1, 2015 Author Share Posted March 1, 2015 Thanks Link to comment Share on other sites More sharing options...
dnicks 25 Posted March 2, 2015 Share Posted March 2, 2015 great work! Link to comment Share on other sites More sharing options...
Nologic 30 Posted March 3, 2015 Author Share Posted March 3, 2015 Why thank you. Link to comment Share on other sites More sharing options...
Spaceboy 2493 Posted March 3, 2015 Share Posted March 3, 2015 But the plugin does create bif files for existing videos if you run the scheduled task. I've just spent the last 2 weeks with it running. Or am I missing something? 1 Link to comment Share on other sites More sharing options...
Nologic 30 Posted March 4, 2015 Author Share Posted March 4, 2015 Well if the plugin did it for you...then I'd say I missed something or something was screwy with my config...as I certainly didn't write the script for giggles. If that's the case, as it sounds like it is...then the only reason to run my script would be spread the work around, between multiple systems. Link to comment Share on other sites More sharing options...
Nologic 30 Posted March 7, 2015 Author Share Posted March 7, 2015 Updated the script, now has an error log file, for video's it's unable to process for whatever reason. Link to comment Share on other sites More sharing options...
Nologic 30 Posted March 27, 2015 Author Share Posted March 27, 2015 Minor update to correct creating images for files that already have a percent sign in them "%" which was causing the script to fail on some files. Link to comment Share on other sites More sharing options...
hoxtonia 46 Posted May 22, 2015 Share Posted May 22, 2015 Thanks for this tool Nologic - has really sped up my processing for BIFs spread around various pcs - essential if you have a roku Link to comment Share on other sites More sharing options...
Nologic 30 Posted May 25, 2015 Author Share Posted May 25, 2015 You are very welcome, and glad to hear it's helpful. I'm thinking of making a modified version that can be used as a scheduled task. Where one just has to edit an INI file for when to start, and end processing, and what folders to do. Granted generally after the bulk of the BIF files are created, the Roku Plug-in should handle things fine unless one is always adding video's in mass...then a scheduled networked BIF setup like I'm suggesting might be useful. 1 Link to comment Share on other sites More sharing options...
hoxtonia 46 Posted May 27, 2015 Share Posted May 27, 2015 I think that's a great idea - would be really useful to be able to run as a scheduled task Link to comment Share on other sites More sharing options...
Nologic 30 Posted May 28, 2015 Author Share Posted May 28, 2015 I updated the code...so give it a try and let me know how it works out. 1 Link to comment Share on other sites More sharing options...
Nologic 30 Posted February 7, 2016 Author Share Posted February 7, 2016 (edited) Okay took another wack at this, this time looking to run concurrent BIF file creations...to help speed things along. The recommended setting is 1 less the number of physical cores your CPU has...in my case since my Ivy has 4...I set it to 3, to keep the system usable...anything above would hose the system. For me this speeds things up to about 2.5X what is normally done with the original script. This takes two scripts to make this work, I call this "Create Bif Master.au3" & "Create Bif Slave.au3" both need to be compiled, and used the same way as the original. Here is the master script: #Include <Array.au3> #Include <File.au3> #Include <String.au3> ;================================================================================ ;== User Vars ;================================================================================ Global $iImage_Width = 320 Global $iConcurrent = 3 ;================================================================================ ;================================================================================ Global $aWeekLong = StringSplit( 'Sunday|Monday|Tuesday|Wednesday|Thursday|Friday|Saturday' , '|' ) Global $aWeekShort = StringSplit( 'Sun|Mon|Tue|Wed|Thu|Fri|Sat' , '|' ) Global $iSchedule = 0 Global $sExtension = '*.mkv;*.mp4;*.mov;*.m4v' Global $bExitLoop = False ; Create Basic Settings If Required $sSavedSettings = @ScriptDir & '\Create Bif.ini' If NOT FileExists( $sSavedSettings ) Then _Settings( $sSavedSettings ) ; Create SendTo Shortcut If StringRight( @ScriptName , 4 ) = '.exe' Then $sSendTo = StringReplace( RegRead( 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders' , 'SendTo' ) , '%USERPROFILE%' , @UserProfileDir ) If StringRight( $sSendTo , 1 ) <> '\' Then $sSendTo &= '\' ; Actual SendTo Shortcut Creation If NOT FileExists( $sSendTo & StringTrimRight( @ScriptName , 4 ) & '.lnk' ) Then FileCreateShortcut( @ScriptDir & '\' & @ScriptName , $sSendTo & StringTrimRight( @ScriptName , 4 ) & '.lnk' , '' , '' , '' , @ScriptDir & '\' & @ScriptName , '' , 0 ) EndIf EndIf ; Remove Temp Files & Folders $aTemps = _FileListToArrayRec( @TempDir , 'Create Biff-*' , 14 , 0 , 1 , 2 ) If IsArray( $aTemps ) Then For $ii = 1 To $aTemps[0] DirRemove( $aTemps[$ii] & '\' , 1 ) Next EndIf ; Select Video Folder If $CmdLine[0] = 0 Then While 1 $sSourceFolder = FileSelectFolder( 'Select Video Folder.' , '' , 6 ) If @[member="ERROR"] = 1 AND $sSourceFolder = '' Then MsgBox( 4096 , 'Exit:' , 'Ending Application' ) Exit ElseIf $sSourceFolder = '' Then MsgBox( 4096 , 'Error:' , 'Unable To Open Folder.' ) ElseIf NOT FileExists ( $sSourceFolder ) Then MsgBox( 4096 , 'Error:' , 'Invalid Folder.' ) Else If StringRight( $sSourceFolder , 1 ) <> '\' Then $sSourceFolder &= '\' Global $aAllFiles = _FileListToArrayRec( $sSourceFolder , $sExtension , 1 , 1 , 0 , 2 ) If NOT IsArray( $aAllFiles ) Then MsgBox( 4096 , 'Error:' , 'No Videos Found.' ) Else _ArraySort( $aAllFiles , 0 , 1 ) ExitLoop EndIf EndIf WEnd ; One Instance at a Time $RunningScripts = ProcessList( @ScriptName ) For $aa = 1 To $RunningScripts[0][0] If $RunningScripts[$aa][1] <> @AutoItPID Then ProcessWaitClose( $RunningScripts[$aa][1] ) Next _Main() Else Switch $CmdLine[1] ; Run All Bif Tasks Case 'Schedule' $iSchedule = 1 $aEndTime = _ScheduleTaskRead( $sSavedSettings ) $aFolders = IniReadSection( $sSavedSettings , 'Folders' ) For $ii = 1 To $aFolders[0][0] If FileExists( $aFolders[$ii][1] ) Then If StringRight( $aFolders[$ii][1] , 1 ) <> '\' Then $aFolders[$ii][1] &= '\' Global $aAllFiles = _FileListToArrayRec( $aFolders[$ii][1] , $sExtension , 1 , 1 , 0 , 2 ) If NOT IsArray( $aAllFiles ) Then ContinueLoop _ArraySort( $aAllFiles , 0 , 1 ) _Main() EndIf Next ; Create New Bif Tasks Case 'ScheduleNew' _ScheduleTaskCreate( $sSavedSettings ) Exit ; Delete All Bif Tasks Case 'ScheduleDelete' _ScheduleTaskDelete() Exit ; Process Command Line Files & Folders Case Else For $ii = 1 To $CmdLine[0] ; One Instance at a Time $RunningScripts = ProcessList( @ScriptName ) For $aa = 1 To $RunningScripts[0][0] If $RunningScripts[$aa][1] <> @AutoItPID Then ProcessWaitClose( $RunningScripts[$aa][1] ) Next ; Test if Folder If StringInStr( FileGetAttrib( $CmdLine[$ii] ) , 'D' ) <> 0 Then $sSourceFolder = $CmdLine[$ii] If StringRight( $sSourceFolder , 1 ) <> '\' Then $sSourceFolder &= '\' Global $aAllFiles = _FileListToArrayRec( $sSourceFolder , $sExtension , 1 , 1 , 0 , 2 ) If NOT IsArray( $aAllFiles ) Then ContinueLoop _ArraySort( $aAllFiles , 0 , 1 ) _Main() Else ; Test if Supported File Type If StringInStr( $sExtension , StringTrimLeft( $CmdLine[$ii] , StringInStr( $CmdLine[$ii] , '.' , 0 , -1 ) - 1 )) <> 0 Then Global $aAllFiles[2] = [1 , $CmdLine[$ii]] _Main() EndIf EndIf Next EndSwitch EndIf MsgBox( 0 , 'Finished:' , 'Batch BIF File Creation Is Complete.' ) Func _Main() _ArrayDelete( $aAllFiles , 0 ) AdlibRegister( '_Concurrent' , 250 ) While $bExitLoop = False Sleep( 100 ) WEnd $bExitLoop = False AdlibUnRegister( '_Concurrent' ) EndFunc Func _Concurrent() ; Early Out If $iSchedule = 1 Then If $aEndTime[1] > @HOUR Then Exit If $aEndTime[1] = @HOUR AND $aEndTime[2] >= @MIN Then Exit EndIf $aProcesslist = ProcessList( 'Create Bif Slave.exe' ) If $aProcesslist[0][0] < $iConcurrent Then If UBound( $aAllFiles ) <> 0 Then $sCurrentFile = _ArrayPop( $aAllFiles ) If $sCurrentFile <> '' Then ; Create Base Name _FileMacros( $sCurrentFile ) $sTempName = $sShortName & '-' & $iImage_Width ; Early Out If FileExists( $sCurrentFile ) = 0 Then Return If FileExists( $sFileDir & $sTempName & '.bif' ) Then Return Run( '"' & @ScriptDir & '\Create Bif Slave.exe" "' & $sCurrentFile & '" "' & $iImage_Width & '"' ) EndIf Else If ProcessExists( 'Create Bif Slave.exe' ) = 0 Then $bExitLoop = True EndIf EndIf EndIf EndFunc Func _FileMacros( $sInFile ) Global $sFileDir = StringLeft ( $sInFile , StringInStr( $sInFile , '\' , 0 , -1 ) ) Global $sFileExt = StringTrimLeft ( $sInFile , StringInStr( $sInFile , '.' , 0 , -1 ) - 1 ) Global $sFileName = StringTrimLeft ( $sInFile , StringInStr( $sInFile , '\' , 0 , -1 ) ) Global $sShortName = StringLeft ( $sFileName , StringInStr( $sFileName , '.' , 0 , -1 ) - 1 ) Global $sParent = StringTrimLeft ( $sFileDir , StringInStr( $sFileDir , '\' , 0 , -2 ) ) Global $sFolderName = StringTrimRight( StringTrimLeft( $sFileDir , StringInStr( $sFileDir , '\' , 0 , -2 ) ) , 1 ) EndFunc Func _Settings( $sSettingsFile ) $sString = '' For $ii = 1 To $aWeekLong[0] $sString &= '[' & $aWeekLong[$ii] & ']' & @CRLF $sString &= 'Start=03:00' & @CRLF $sString &= 'End=06:00' & @CRLF $sString &= @CRLF Next $sString &= '[Folders]' & @CRLF $sString &= 'Folder_01=' & @CRLF & @CRLF FileWrite( $sSettingsFile , $sString ) EndFunc Func _ScheduleTaskRead( $sSettingsFile ) Return StringSplit( IniRead( $sSettingsFile , $aWeekLong[@WDAY] , 'End' , '06:00' ) , ':' ) EndFunc Func _ScheduleTaskDelete() For $ii = 1 To $aWeekLong[0] ; Remove Old Tasks If Exists RunWait( @ComSpec & ' /c SchTasks /DELETE /TN "Create Bif - ' & $aWeekLong[$ii] & '" /F' , '' , @SW_HIDE ) Next EndFunc Func _ScheduleTaskCreate( $sSettingsFile ) $aFolders = IniReadSection( $sSettingsFile , 'Folders' ) If IsArray( $aFolders ) = 0 Then MsgBox( 48 , 'Error:' , 'Folders in INI Invalid or Missing.' ) Exit EndIf For $ii = 1 To $aFolders[0][0] If FileExists( $aFolders[$ii][1] ) = 0 Then MsgBox( 48 , 'Error:' , 'Folder Invalid.' & @LF & $aFolders[$ii][1] ) Exit EndIf Next For $ii = 1 To $aWeekLong[0] ; Remove Old Task If Exists RunWait( @ComSpec & ' /c SchTasks /DELETE /TN "Create Bif - ' & $aWeekLong[$ii] & '" /F' , '' , @SW_HIDE ) $aTaskStart = StringSplit( IniRead( $sSettingsFile , $aWeekLong[$ii] , 'Start' , '03:00' ) , ':' ) $aTaskEnd = StringSplit( IniRead( $sSettingsFile , $aWeekLong[$ii] , 'End' , '06:00' ) , ':' ) Select Case $aTaskStart[1] < 0 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Hour Less Than 0.' & @LF & $aTaskStart[1] & ':' & $aTaskStart[2] ) Exit Case $aTaskStart[2] < 0 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Minute Less Than 0.' & @LF & $aTaskStart[1] & ':' & $aTaskStart[2] ) Exit Case $aTaskEnd[1] < 0 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Hour Less Than 0.' & @LF & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskEnd[2] < 0 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Minute Less Than 0.' & @LF & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskStart[1] > 24 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Hour Greater Than 24.' & @LF & $aTaskStart[1] & ':' & $aTaskStart[2] ) Exit Case $aTaskStart[2] > 59 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Minute Greater Than 59.' & @LF & $aTaskStart[1] & ':' & $aTaskStart[2] ) Exit Case $aTaskEnd[1] > 24 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Hour Greater Than 24.' & @LF & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskEnd[2] > 59 MsgBox( 48 , 'Error:' , $aWeekLong[$ii] ' Minute Greater Than 59.' & @LF & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskStart[1] > $aTaskEnd[1] MsgBox( 48 , 'Error:' , 'Start Time Hour Greater Than End Time Hour.' & @LF & 'Start: ' & $aTaskStart[1] & ':' & $aTaskStart[2] & @LF & 'End: ' & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskStart[1] = $aTaskEnd[1] AND $aTaskStart[2] > $aTaskEnd[2] MsgBox( 48 , 'Error:' , 'Start Time Minutes Greater Than End Time Minutes.' & @LF & 'Start: ' & $aTaskStart[1] & ':' & $aTaskStart[2] & @LF & 'End: ' & $aTaskEnd[1] & ':' & $aTaskEnd[2] ) Exit Case $aTaskStart[1] = $aTaskEnd[1] AND $aTaskStart[2] = $aTaskEnd[2] ContinueLoop EndSelect ; Create New Task RunWait( @ComSpec & ' /c SchTasks /Create /SC WEEKLY /D ' & $aWeekShort[$ii] & ' /TN "Create Bif - ' & $aWeekLong[$ii] & '" /TR "\"' & @ScriptFullPath & '\" Schedule" /ST ' & $aTaskStart[1] & ':' & $aTaskStart[2] & ' /F' , '' , @SW_HIDE ) Next EndFunc Now the Slave: #Include <Array.au3> #Include <File.au3> #Include <String.au3> If $CmdLine[0] = 0 OR $CmdLine[0] < 2 Then Exit ; Create Base Name _FileMacros( $CmdLine[1] ) $sTempName = $sShortName & '-' & $CmdLine[2] ; Create Temp Folder $sTempFolder = @TempDir & '\Create Biff-' & _RandomString() & '\' & $sTempName If NOT FileExists( $sTempFolder ) Then DirCreate( $sTempFolder ) ; Create Images If StringInStr( $sTempFolder , '%' ) <> 0 Then $sTempFolderNew = StringReplace( $sTempFolder , '%' , '%%' ) Else $sTempFolderNew = $sTempFolder EndIf RunWait( @ComSpec & ' /c ffmpeg -i "' & $CmdLine[1] & '" -r .1 -vf "scale=min(iw\,' & $CmdLine[2] & '):trunc(ow/dar/2)*2:flags=lanczos" -f image2 "' & $sTempFolderNew & '\%08d.jpg"' , @ScriptDir & '\BIN\' , @SW_HIDE ) ; Re Number Images (0 Base Index) $aAllImages = _FileListToArrayRec( $sTempFolder , '*.jpg' , 1 , 1 , 0 , 2 ) If IsArray( $aAllImages ) Then _ArraySort( $aAllImages , 0 , 1 ) For $ii = 1 To $aAllImages[0] FileMove( $aAllImages[$ii] , $sTempFolder & '\' & _StringRepeat( '0' , 8 - StringLen( $ii - 1 )) & $ii - 1 & '.jpg' ) Next Else DirRemove( $sTempFolder , 1 ) Exit EndIf ; Create Actual BIF File RunWait( @ComSpec & ' /c biftool -t 10000 "' & $sTempFolder & '"' , @ScriptDir & '\BIN\' , @SW_HIDE ) ; Move BIF To Correct Folder FileMove( @ScriptDir & '\BIN\' & $sTempName & '.bif' , $sFileDir & $sTempName & '.bif' , 1 ) ; Delete Temp Folder DirRemove( $sTempFolder , 1 ) Func _FileMacros( $sInFile ) Global $sFileDir = StringLeft ( $sInFile , StringInStr( $sInFile , '\' , 0 , -1 ) ) Global $sFileExt = StringTrimLeft ( $sInFile , StringInStr( $sInFile , '.' , 0 , -1 ) - 1 ) Global $sFileName = StringTrimLeft ( $sInFile , StringInStr( $sInFile , '\' , 0 , -1 ) ) Global $sShortName = StringLeft ( $sFileName , StringInStr( $sFileName , '.' , 0 , -1 ) - 1 ) Global $sParent = StringTrimLeft ( $sFileDir , StringInStr( $sFileDir , '\' , 0 , -2 ) ) Global $sFolderName = StringTrimRight( StringTrimLeft( $sFileDir , StringInStr( $sFileDir , '\' , 0 , -2 ) ) , 1 ) EndFunc Func _RandomString() Local $sString , $aSpace[3] For $i = 1 To 15 $aSpace[0] = Chr( Random( 65 , 90 , 1 )) ; A-Z $aSpace[1] = Chr( Random( 97 , 122 , 1 )) ; a-z $aSpace[2] = Chr( Random( 48 , 57 , 1 )) ; 0-9 $sString &= $aSpace[Random( 0 , 2 , 1 )] Next Return $sString EndFunc Enjoy! Edited February 26, 2016 by Nologic Link to comment Share on other sites More sharing options...
cf23 0 Posted January 12, 2017 Share Posted January 12, 2017 Nologic, thank you very much for creating these scripts. They'll potentially save me a ton of time. However, can someone post a link to biftool.exe. I'm not able to find it on the Roku SDK site anywhere, and they haven't responded to my emails asking about it. Thanks. Link to comment Share on other sites More sharing options...
Happy2Play 8281 Posted January 12, 2017 Share Posted January 12, 2017 (edited) Nologic, thank you very much for creating these scripts. They'll potentially save me a ton of time. However, can someone post a link to biftool.exe. I'm not able to find it on the Roku SDK site anywhere, and they haven't responded to my emails asking about it. Thanks. Just googled it. Here you go. Edited January 12, 2017 by Happy2Play Link to comment Share on other sites More sharing options...
cf23 0 Posted January 18, 2017 Share Posted January 18, 2017 Clearly your Google-Fu is better than mine. Thanks! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now