SHARE
TWEET

Untitled

jpWHY Jan 24th, 2020 107 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; A simple gui for ffmpeg
  2. ; by Schreq
  3. ; v1.3 (2017/11/13)
  4. ;
  5. ; TODO:
  6. ; -tune fastdecode for sony vegas compat
  7. ; dropdown for color space
  8. ; hevc_nvenc
  9.  
  10. #noenv
  11. #keyhistory 0
  12. #notrayicon
  13. #singleinstance off
  14. listlines, off
  15. setworkingdir %a_scriptdir%
  16.  
  17. filelist  := "filelist.txt"
  18. batchfile := "encode.bat"
  19. format := { start:      "ffmpeg.exe -hide_banner"
  20.           , concat:     " -f concat -safe 0 -i {:s}"
  21.           , normal:     " -i ""{:s}"""
  22.           , cv:         " -c:v {:s}"
  23.           , libx264:    " -crf {:s} -preset {:s}"
  24.           , h264_nvenc: " -qp {:s} -profile:v high -preset {:s}"
  25.           , ca:         " -c:a {:s}"
  26.           , aac:        " -b:a {:s}k"
  27.           , cut:        " -ss {:s} -to {:s} -copyts"
  28.           , size:       " -vf scale={:s}:{:s}"
  29.           , fps:        " -r {:s}"
  30.           , output:     " ""{:s}.{:s}""" }
  31.  
  32. tabs            := "General||Edit"
  33. , outfolder     := a_scriptdir
  34. , videofiles
  35.     := "Video (*.avi; *.flv; *.mkv; *.mov; *.mp4; *.mpg; *.webm)"
  36. , encodersv     := "libx264||h264_nvenc|copy"
  37. , encodersa     := "aac||copy"
  38. , muxers        := "mp4||mkv"
  39. , starttime     := 20000101000000
  40. , endtime       := 20000101000100
  41. , crfdefault    := 23
  42. , crfmax        := 51
  43. , bradefault    := 192  ; bitrate audio
  44. , bramin        := 96
  45. , bramax        := 320
  46. , resxdefault   := -1
  47. , resydefault   := 720
  48. , fpsdefault    := 30
  49. , presets
  50.     := "ultrafast|superfast|veryfast|faster|fast|medium||slow|slower|"
  51.     .  "veryslow|placebo"
  52. , presets_nvenc
  53.     := "default|slow|medium||fast|hp|hq|bd|ll|llhq|llhp|lossless|"
  54.     .  "losslesshp"
  55.  
  56. tooltiptext := { encoderv
  57. : "libx264: x264 is a free software library developed by VideoLAN for`n"
  58. . "encoding video streams into the H.264/MPEG-4 AVC format. Slow but`n"
  59. . "gives the best compression/quality.`n"
  60. . "`n"
  61. . "h264_nvenc: Nvidia NVENC is a feature in its graphics cards that`n"
  62. . "performs H.264 video encoding, offloading this compute-intensive`n"
  63. . "task from the CPU.`n"
  64. . "`n"
  65. . "copy: Direct stream copy, no encoding is done. Use this to not lose`n"
  66. . "quality when transcoding. It's not possible to resize or change the`n"
  67. . "fps in copy mode.`n"
  68. , muxer
  69. : "A muxer is an engine which will combine media assets into a single`n"
  70. . "output container such as a mp4 or mkv (Matroska)."
  71. , docut
  72. : "Enable to cut out a clip from the source file."
  73. , starttime
  74. : "The start time of the clip to cut out in HH:MM:SS format."
  75. , endtime
  76. : "The end time of the clip to cut out in HH:MM:SS format."
  77. , doresize
  78. : "Enable to resize the output. In order to keep the aspect ratio the`n"
  79. . "same, we need to specify only one component, either the width or`n"
  80. . "height, and set the other component to -1."
  81. , dofps
  82. : "Enable to change the framerate of the output."
  83. , preset_libx264
  84. : "A preset is a collection of options that will provide a certain`n"
  85. . "encoding speed to compression ratio. A slower preset will provide`n"
  86. . "better compression (compression is quality per filesize).`n"
  87. . "For constant quality encoding, you will simply save bitrate by`n"
  88. . "choosing a slower preset. The general guideline is to use the`n"
  89. . "slowest preset that you have patience for.`n"
  90. . "Ignore placebo as it is not useful."
  91. , preset_h264_nvenc
  92. : "A preset is a collection of options that will provide a certain`n"
  93. . "encoding speed to compression ratio. A slower preset will provide`n"
  94. . "better compression (compression is quality per filesize).`n"
  95. . "For constant quality encoding, you will simply save bitrate by`n"
  96. . "choosing a slower preset.`n"
  97. . "`n"
  98. . "default`n"
  99. . "slow: High Quality 2 passes`n"
  100. . "medium: High Quality 1 pass (Default)`n"
  101. . "fast: High Performance 1 pass`n"
  102. . "hp: High Performance`n"
  103. . "hq: High Quality`n"
  104. . "bd: Blue-ray Disk`n"
  105. . "ll: Low Latency`n"
  106. . "llhq: Low Latency High Quality`n"
  107. . "llhp: Low Latency High Performance`n"
  108. . "lossless`n"
  109. . "losslesshp: Lossless High Performance"
  110. , crf_libx264
  111. : "You can set the values between 0 and 51, where lower values would`n"
  112. . "result in better quality, at the expense of higher file sizes.`n"
  113. . "Higher values mean more compression, but at some point you will`n"
  114. . "notice the quality degradation.`n"
  115. . "`n"
  116. . "For x264, sane values are between 18 and 28. The default is 23,`n"
  117. . "so you can use this as a starting point."
  118. , crf_h264_nvenc
  119. : "You can set the values between 0 and 51, where lower values would`n"
  120. . "result in better quality, at the expense of higher file sizes.`n"
  121. . "Higher values mean more compression, but at some point you will`n"
  122. . "notice the quality degradation.`n"
  123. . "`n"
  124. . "For x264, sane values are between 18 and 28. The default is 23,`n"
  125. . "so you can use this as a starting point."
  126. , encodera
  127. : "aac: Advanced Audio Coding (AAC) is a proprietary audio coding`n"
  128. . "standard for lossy digital audio compression. Designed to be the`n"
  129. . "successor of the MP3 format, AAC generally achieves better sound`n"
  130. . "quality than MP3 at the same bit rate.`n"
  131. . "`n"
  132. . "copy: Direct stream copy, no encoding is done. Use this to not`n"
  133. . "lose quality when transcoding."
  134. , bra
  135. : "Bitrate refers to the number of bits (or the amount of data) that`n"
  136. . "are processed over a certain amount of time. The higher the rate`n"
  137. . "is, the better the quality of sound is. However, this also`n"
  138. . "increases the file size." }
  139.  
  140. prevcontrol := ""
  141. onmessage( 0x200, "WM_MOUSEMOVE" )
  142. onmessage( 0x2A3, "WM_MOUSELEAVE" )
  143.  
  144. ; File list
  145.  
  146. gui, add, tab3, , %tabs%
  147. gui, add, text, xm+10 y+m, Files
  148. gui, add, listview, r5 w190 -hdr vfiles, Files
  149. gui, add, button, gaddfile -wrap section, Add
  150. gui, add, button, gdelfile -wrap ys, Remove
  151. gui, add, checkbox, vdocat gcatchanged ys+5 disabled, Concatenate
  152. ; VIDEO
  153. gui, font, bold
  154. gui, add, text, w45 xs y+15, Video
  155. gui, font
  156. ; Video encoder selection
  157. gui, add, text, section w45 xs y+10, Encoder
  158. gui, add, dropdownlist, vencoderv gencodervchanged w100 ys-4
  159.     , %encodersv%
  160. ; Preset selection
  161. gui, add, text, section vpresetlabel w45 xs, Preset
  162. gui, add, dropdownlist, vpreset w100 ys-4, %presets%
  163. ; CRF selection
  164. gui, add, text, section vcrflabel w45 xs, Quality
  165. gui, add, edit, vcrfvalue center readonly -tabstop w60 ys-4
  166.     , %crfdefault%
  167. gui, add, text, vcrfb1 section, Good
  168. gui, add, text, vcrfb2 ys, Bad
  169. gui, add, slider,
  170. (
  171.     vcrfslider gcrfchanged altsubmit buddy1crfb1 buddy2crfb2 center
  172.     noticks range0-%crfmax% xs ys
  173. ), %crfdefault%
  174. ; AUDIO
  175. gui, font, bold
  176. gui, add, text, w45 xm+10 y+10, Audio
  177. gui, font
  178. ; Audio encoder selection
  179. gui, add, text, section w45 y+10, Encoder
  180. gui, add, dropdownlist, vencodera gencoderachanged w100 ys-4
  181.     , %encodersa%
  182. ; Audio bitrate selection
  183. gui, add, text, section vbralabel w45 xs, Bitrate
  184. gui, add, edit, vbra limit3 number w100 ys-4, %bradefault%
  185. gui, add, updown, vbraupdown range%bramin%-%bramax%, %bradefault%
  186. gui, add, text, vbraunit ys, kbit/s
  187.  
  188. gui, tab, 2
  189.  
  190. ; Cut times
  191. gui, add, checkbox, section vdocut gcutchanged left xm+10 y+m, Cut
  192. gui, add, text, section vstartlabel disabled w45 xs y+10, Start
  193. gui, add, datetime, vstarttime 1 choose%starttime% w100 ys-4 disabled
  194.     , HH:mm:ss
  195. gui, add, text, section vendlabel disabled w45 xs, End
  196. gui, add, datetime, vendtime 1 choose%endtime% w100 ys-4 disabled
  197.     , HH:mm:ss
  198. ; Resize
  199. gui, add, checkbox, section vdoresize gresizechanged left xm+10 y+15
  200.     , Resize
  201. gui, add, text, section vresizelabel w45 xs y+10 disabled, Size
  202. gui, add, edit, vresx number w55 ys-4 disabled, %resxdefault%
  203. gui, add, updown, vresxupdown range-1-99999 disabled, %resxdefault%
  204. gui, add, text, ys vresxlabel disabled, X
  205. gui, add, edit, vresy number w55 ys-4 disabled, %resydefault%
  206. gui, add, updown, vresyupdown range-1-99999 disabled, %resydefault%
  207. ; FPS
  208. gui, add, checkbox, section vdofps gfpschanged left xm+10 y+15
  209.     , Framerate
  210. gui, add, text, section vfpslabel w45 xs y+10 disabled, FPS
  211. gui, add, edit, vfps number w100 ys-4 disabled, %fpsdefault%
  212. gui, add, updown, vfpsupdown disabled, %fpsdefault%
  213.  
  214. gui, tab
  215. gui, add, text, section vmuxerlabel w45 xm+10 y+10, Muxer
  216. gui, add, dropdownlist, vmuxer w45 ys-4, %muxers%
  217. gui, add, button, grunffmpeg -wrap w99 ys-5, Run
  218. gui +owndialogs
  219. gui, show, autosize
  220. gui, submit, nohide
  221.  
  222. return
  223.  
  224. WM_MOUSEMOVE()
  225. {
  226.     global tooltiptext, encoderv, prevcontrol
  227.     static currcontrol
  228.  
  229.     if ( a_guicontrol == "" )
  230.         return
  231.  
  232.     if ( a_guicontrol <> prevcontrol ) {
  233.         settimer, displaytooltip, off
  234.         currcontrol   := a_guicontrol
  235.         , prevcontrol := currcontrol
  236.         settimer, displaytooltip, -750
  237.     }
  238.     return
  239.  
  240.     displaytooltip:
  241.         if ( currcontrol == "preset" )
  242.             key := currcontrol "_" encoderv
  243.         else if ( substr( currcontrol, 1, 3 ) == "crf" )
  244.             key := "crf_" . encoderv
  245.         else if ( substr( currcontrol, 1, 3 ) == "bra" )
  246.             key := "bra"
  247.         else if ( substr( currcontrol, 1, 3 ) == "res" )
  248.             key := "doresize"
  249.         else if ( substr( currcontrol, 1, 3 ) == "fps" )
  250.             key := "dofps"
  251.         else
  252.             key := currcontrol
  253.  
  254.         tooltip % tooltiptext[key]
  255.     return
  256. }
  257.  
  258. WM_MOUSELEAVE()
  259. {
  260.     global prevcontrol
  261.     tooltip
  262.     settimer, displaytooltip, off
  263.     prevcontrol := ""
  264. }
  265.  
  266. changectl( state, ctrls )
  267. {
  268.     local i, ctrl
  269.  
  270.     for i, ctrl in ctrls
  271.         guicontrol, %state%, %ctrl%
  272. }
  273.  
  274. encodervchanged()
  275. {
  276.     global
  277.     static prevenc := encoderv
  278.     gui, submit, nohide
  279.  
  280.     if ( encoderv == prevenc )
  281.         return
  282.  
  283.     local controls
  284.         := [ "presetlabel", "preset", "crflabel", "crfvalue"
  285.            , "crfslider", "crfb1", "crfb2", "doresize", "resizelabel"
  286.            , "resx", "resy", "resxlabel", "resxupdown", "resyupdown"
  287.            , "dofps", "fpslabel", "fps", "fpsupdown" ]
  288.  
  289.     if ( encoderv == "copy" )
  290.         changectl( "disable", controls )
  291.     else if ( prevenc == "copy" )
  292.         changectl( "enable", controls )
  293.  
  294.     if ( encoderv == "libx264" )
  295.         guicontrol, , preset, |%presets%
  296.     else if ( encoderv == "h264_nvenc" )
  297.         guicontrol, , preset, |%presets_nvenc%
  298.    
  299.     prevenc := encoderv
  300. }
  301.  
  302. encoderachanged()
  303. {
  304.     global
  305.     static prevenc := encodera
  306.     gui, submit, nohide
  307.  
  308.     if ( encodera == prevenc )
  309.         return
  310.  
  311.     local controls := [ "bralabel", "bra", "braupdown", "braunit" ]
  312.     if ( encodera == "copy" )
  313.         changectl( "disable", controls )
  314.     else
  315.         changectl( "enable", controls )
  316.  
  317.     prevenc := encodera
  318. }
  319.  
  320. cutchanged()
  321. {
  322.     global
  323.     gui, submit, nohide
  324.     local controls
  325.         := [ "startlabel", "endlabel", "starttime", "endtime" ]
  326.     if docut
  327.         changectl( "enable", controls )
  328.     else
  329.         changectl( "disable", controls )
  330. }
  331.  
  332. resizechanged()
  333. {
  334.     global
  335.     gui, submit, nohide
  336.     local controls
  337.         := [ "resizelabel", "resx", "resxlabel", "resy", "resxupdown"
  338.            , "resyupdown"]
  339.     if doresize
  340.         changectl( "enable", controls )
  341.     else
  342.         changectl( "disable", controls )
  343. }
  344.  
  345. fpschanged()
  346. {
  347.     global
  348.     gui, submit, nohide
  349.     local controls := [ "fpslabel", "fps", "fpsupdown" ]
  350.     if dofps
  351.         changectl( "enable", controls )
  352.     else
  353.         changectl( "disable", controls )
  354. }
  355.  
  356. crfchanged()
  357. {
  358.     global encoderv, crfslider, crfvalue
  359.     if ( encoderv <> "h264_nvenc" and crfslider = 0 )
  360.         guicontrol, text, crfvalue, lossless
  361.     else
  362.         guicontrol, text, crfvalue, %crfslider%
  363. }
  364.  
  365. addfile()
  366. {
  367.     local files, path, filepath
  368.     gui +owndialogs
  369.     fileselectfile, files, m, , , %videofiles%
  370.  
  371.     loop, parse, files, `n
  372.     {
  373.         if ( a_index == 1 ) {
  374.             path := a_loopfield
  375.         } else {
  376.             filepath := path "\" a_loopfield
  377.             lv_add( "", filepath )
  378.         }
  379.     }
  380.     lv_modifycol()
  381.     if ( lv_getcount() > 1 )
  382.         guicontrol, enable, docat
  383. }
  384.  
  385. delfile()
  386. {
  387.     local selected, row := lv_getcount()
  388.  
  389.     loop
  390.     {
  391.         if row < 0
  392.             break
  393.         selected := lv_getnext( row )
  394.         if selected
  395.             lv_delete( selected )
  396.         row--
  397.     }
  398.     if ( lv_getcount() < 2 ) {
  399.         guicontrolget, docat
  400.  
  401.         if docat {
  402.             guicontrol, , docat, 0
  403.             catchanged()
  404.         }
  405.         guicontrol, disable, docat
  406.     }
  407.     lv_modifycol()
  408. }
  409.  
  410. catchanged()
  411. {
  412.     global
  413.  
  414.     guicontrolget, docat
  415.  
  416.     if docat {
  417.         ; disable the cut checkbox and time input boxes for concat mode
  418.         guicontrol, disable, docut
  419.         if docut
  420.             changectl( "disable"
  421.                 , [ "startlabel", "endlabel", "starttime", "endtime" ] )
  422.     } else {
  423.         guicontrol, enable, docut
  424.         if docut
  425.             changectl("enable"
  426.                 , [ "startlabel", "endlabel", "starttime", "endtime" ] )
  427.     }
  428. }
  429.  
  430. genfilelist( concatfile )
  431. {
  432.     ; '`n' = replace `n with `r`n when writing
  433.     ;  '-' = locks the file for read, write and delete access
  434.     file := fileopen( concatfile, "w`n-" )
  435.     if not isobject( file ) {
  436.         msgbox, 16, , Error: Could not open "%concatfile%" for writing. Exiting.
  437.         exitapp
  438.     }
  439.  
  440.     loop
  441.     {
  442.         if not lv_gettext( filepath, a_index )
  443.             break
  444.  
  445.         ;stringreplace, filepath, filepath, \, /, 1
  446.         fileappend, file '%filepath%'`n, %concatfile%
  447.         file.writeline( "file '" filepath "'")
  448.     }
  449.     file.close()
  450. }
  451.  
  452. runffmpeg()
  453. {
  454.     local filecount := lv_getcount()
  455.  
  456.     gui, submit, nohide
  457.  
  458.     if not filecount {
  459.         msgbox, 16, , Error: No files added for encoding.
  460.         return
  461.     }
  462.  
  463.     if ( filecount > 1 and not docat ) {
  464.         runbatch()
  465.         return
  466.     }
  467.  
  468.     local outfile
  469.     gui +owndialogs
  470.     fileselectfile, outfile, s, , , % "Video (*." muxer ")"
  471.  
  472.     if errorlevel
  473.         return
  474.  
  475.     if substr( outfile, -3 ) == "." muxer
  476.         outfile := substr( outfile, 1, -4 )
  477.  
  478.     local cmd = format["start"]
  479.  
  480.     if ( filecount > 1 ) {
  481.         genfilelist( filelist )
  482.         cmd .= format( format["concat"], filelist )
  483.     } else {
  484.         local infile
  485.         lv_gettext( infile, 1 )
  486.         cmd .= format( format["normal"], infile )
  487.  
  488.         if docut {
  489.             cmd .= format( format["cut"]
  490.                 , regexreplace( starttime
  491.                     , "\d{8}(\d\d)(\d\d)(\d\d)", "$1:$2:$3" )
  492.                 , regexreplace( endtime
  493.                     , "\d{8}(\d\d)(\d\d)(\d\d)", "$1:$2:$3" ) )
  494.         }
  495.     }
  496.    
  497.     if doresize
  498.         cmd .= format( format["size"], resxupdown, resyupdown )
  499.  
  500.     cmd .= format( format["cv"], encoderv )
  501.  
  502.     if dofps
  503.         cmd .= format( format["fps"], fpsupdown )
  504.    
  505.     if ( encoderv <> "copy" )
  506.         cmd .= format( format[encoderv], crfslider, preset )
  507.  
  508.     cmd .= format( format["ca"], encodera )
  509.  
  510.     if ( encodera <> "copy" )
  511.         cmd .= format( format[encodera], bra )
  512.  
  513.     cmd .= format( format["output"], outfile, muxer )
  514.  
  515.     run, cmd.exe /c %cmd% & pause
  516. }
  517.  
  518. runbatch()
  519. {
  520.     global
  521.  
  522.     gui +owndialogs
  523.     fileselectfolder, selected, *%outfolder%, ,
  524.  
  525.     if errorlevel
  526.         return
  527.  
  528.     outfolder := selected
  529.  
  530.     ; '`n' = replace `n with `r`n when writing
  531.     ;  '-' = locks the file for read, write and delete access
  532.     file := fileopen( batchfile, "w`n-" )
  533.     if not isobject( file ) {
  534.         msgbox, 16, , Error: Could not open "%batchfile%" for writing. Exiting.
  535.         exitapp
  536.     }
  537.     file.writeline( "@echo off" )
  538.  
  539.     local filecount := lv_getcount()
  540.  
  541.     loop, %filecount%
  542.     {
  543.         local cmd = format["start"]
  544.         local infile
  545.         lv_gettext( infile, a_index )
  546.         cmd .= format( format["normal"], infile )
  547.  
  548.         if docut {
  549.             cmd .= format( format["cut"]
  550.                 , regexreplace( starttime
  551.                     , "\d{8}(\d\d)(\d\d)(\d\d)", "$1:$2:$3" )
  552.                 , regexreplace( endtime
  553.                     , "\d{8}(\d\d)(\d\d)(\d\d)", "$1:$2:$3" ) )
  554.         }
  555.        
  556.         if doresize
  557.             cmd .= format( format["size"], resxupdown, resyupdown )
  558.  
  559.         cmd .= format( format["cv"], encoderv )
  560.  
  561.         if dofps
  562.             cmd .= format( format["fps"], fpsupdown )
  563.        
  564.         if ( encoderv <> "copy" )
  565.             cmd .= format( format[encoderv], crfslider, preset )
  566.  
  567.         cmd .= format( format["ca"], encodera )
  568.  
  569.         if ( encodera <> "copy" )
  570.             cmd .= format( format[encodera], bra )
  571.  
  572.         splitpath, infile, , , , infile
  573.         cmd .= format( format["output"], outfolder "\" infile "_" encoderv, muxer )
  574.         file.writeline( "echo." )
  575.         file.writeline( "echo " a_index " of " filecount)
  576.         file.writeline( cmd )
  577.     }
  578.     file.writeline( "pause" )
  579.     file.close()
  580.     run, %batchfile%
  581. }
  582.  
  583. guidropfiles()
  584. {
  585.     global
  586.  
  587.     loop, parse, a_guievent, `n
  588.         lv_add( "", a_loopfield )
  589.  
  590.     lv_modifycol()
  591.     if ( lv_getcount() > 1 )
  592.         guicontrol, enable, docat
  593. }
  594.  
  595. guiclose()
  596. {
  597.     exitapp
  598. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top