SHARE
TWEET

4ffmpeg-8.215

a guest Nov 28th, 2015 110 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. '''
  5. ---------------------------------
  6. work in python2.7/3
  7. os: gnu/linux only
  8. ---------------------------------
  9. need:
  10. python, gtk3 (3.14|3.16), cairo, pango, libvte (2.90|2.91)
  11. --------------------------------
  12. packages in debian could be:
  13. libgtk-3-0
  14. python-gi
  15. python-gi-cairo
  16. python-gobject
  17. gir1.2-pango-1.0
  18. libvte9
  19. libvte-2.90-9 | libvte-2.91-0
  20. gir1.2-vte-2.90 | gir1.2-vte-2.91
  21. ---------------------------------
  22. ffmpeg executables:
  23. ffmpeg, ffplay, ffprobe >= 2.8
  24. build with:
  25. libfaac, libaacplus, libfdk-aac, libmp3lame,
  26. postproc, avfilter,
  27. libx264, libx265 multilib (8-10bit),
  28. libsoxr, libzimg
  29. ---------------------------------
  30. '''
  31.  
  32. import gi
  33. try:
  34.         gi.require_version('Vte', '2.90')
  35. except:
  36.         pass
  37. from gi.repository import Gtk, GObject, Vte, GLib, Pango
  38. import os, sys, subprocess, threading, time, re
  39. from subprocess import call
  40. from math import pow
  41.  
  42. # Abstract struct class      
  43. class Struct:
  44.        
  45.         def __init__ (self, *argv, **argd):
  46.                 if len(argd):
  47.                         # Update by dictionary
  48.                         self.__dict__.update (argd)
  49.                 else:
  50.                         # Update by position
  51.                         attrs = [x for x in dir(self) if x[0:2] != "__"]
  52.                         for n in range(len(argv)):
  53.                                 setattr(self, attrs[n], argv[n])
  54.  
  55. class Vars(Struct):
  56.        
  57.         version = "8.125"
  58.         ffmpeg_ex = 'ffmpeg'
  59.         ffplay_ex = 'ffplay'
  60.         ffprobe_ex = 'ffprobe'
  61.         final_vf_str = ""
  62.         final_af_str = ""
  63.         deint_str = ""
  64.         crop_str = ""
  65.         scalestr = ""
  66.         dn_str = ""
  67.         uns_str = ""
  68.         fr_str = ""
  69.         filter_test_str = ""
  70.         video_width = "0"
  71.         video_height = "0"
  72.         darin = "1"
  73.         add_1_1_dar = True
  74.         framerate = 25
  75.         maps_str = ""
  76.         time_final_str = ""
  77.         final_codec_str = ""
  78.         final_other_str = ""
  79.         acodec_is = ""
  80.         audio_channels = 0
  81.         audio_srate_in = ""
  82.         audio_codec_str = ""
  83.         vcodec_is = ""
  84.         video_codec_str = ""
  85.         video_codec_str_more = ""
  86.         container_str = ""
  87.         info_str = ''
  88.         blackdet_is_run = False
  89.         compinit = '.3 .3:1 1:-90/-90 -60/-40 -39/-30 -20/-14 -9/-9 0/-3:6:-5:0:.5'
  90.         compand_data = ''
  91.         compand_time = 0
  92.         dynaudnorm = "f=500:g=31:s=18:p=0.80"
  93.         dynaudnorm_data = ''
  94.         time_start = 0 # for cropdetect and test
  95.         p3_command = ""
  96.         filename = ""
  97.         dirname = ""
  98.         basename = ""
  99.         in_file_size = ""
  100.         ext = ""
  101.         outdir = ""
  102.         indir = ""
  103.         newname = ""
  104.         duration = ""
  105.         duration_in_sec = 0
  106.         time_done = 0
  107.         time_done_1 = 0
  108.         out_file_size = ""
  109.         debug = 0
  110.         first_pass = 0
  111.         n_pass = 1
  112.         p3_comm_first_p = ""
  113.         final_command1 = ""
  114.         final_command2 = ""
  115.         eff_pass = 0
  116.         BLACKDT_DONE = False
  117.         VOLDT_DONE = False
  118.         FRAMDT_DONE = False
  119.         ENCODING = False
  120.         ac3_drc = ""
  121.         have_subs = False
  122.         maps_ch = ['0:0', '0:1', '0:2']
  123.         XaCheck = ""
  124.         XvCheck = ""
  125.         acodec_list = ""
  126.         vcodec_list = ""
  127.         preset_list = ''
  128.         tune_list = ''
  129.         opt_list = ''
  130.         vrc_list = ''
  131.        
  132. class Tips(Struct):
  133.        
  134.         map_tooltip_str = ' use: 0:0  or  0:0,0:1,0:2 '
  135.         time_tooltip_str = '  use: 90  or  90.555  or  00:01:30  or  00:01:30.555   '
  136.         customscale_str = '   use:  filter=parm:parm,filter... and press ENTER   '
  137.         time2frame_str = '  Convert time sec or hh:mm:ss (.decimal) to frames   '
  138.         black_dt_init_str = 'Detect black frames can take some time,\ndepending on the length of the video.'
  139.         compad_str = ' attacks attacks:decays decays: points dbin/dbout dbin/dbout:soft-knee:gain:initial volume:delay  '
  140.         dynaudnorm_str = ' f= 10 to 8000 - frame length ms (500)\n g= 3 to 301 - filter window size (31) must be odd number \n s= 3.00 to 30.0 - compress factor, 0 = disable, 3 = max comp \n p= 0 to 1 (0.95) - target peak value '
  141.         drc_str = '   -drc_scale percentage of dynamic range compression to apply (from 0 to 6) (default 1)   '
  142.         but_file_str = '  Choose input file   '
  143.         audio_samp_str = ' audio samplerate '
  144.         audio_channels_str = ' audio channels '
  145.         subcopy_tooltip_srt = ' false= srt->ass '
  146.         nometa_tooltip_srt = ' true= --map_metadata -1 '
  147.         debug_tooltip_srt = ' only print command in terminal '
  148.         preset_tooltip_str = ' x264/5 preset '
  149.         tune_tooltip_str = ' x264/5 tune '
  150.         opt_tooltip_str = ' x264/5 options/params '
  151.         x265_optscustom_str = '   x265-params custom, use:   \n   rd=3:aq-mode=3:zones=300,1000,b=1.5\/5000,6000,q=50   \n   this override | add the currents params, press ENTER to apply   '
  152.         ffplay_tooltip_str = ' ffplay keys: \n f - full screen \n a - audio stream \n v - video stream \n s - sub stream \n arrows - seek '
  153.         out_dir_tooltip_str = '  Change current out dir   \n  Default: same as input   '
  154.         container_tooltip_srt = '  Change out container   '
  155.  
  156. ################ AUDIO ##################################
  157.  
  158. class ACodec(object):
  159.         def __init__(self, label=None, codec=None, toolt=None, value=None, comm_str=None, kb=False, afterbrn=False, force_stereo=False, no_audio_enc=False):
  160.                 self.label = label
  161.                 self.codec = codec
  162.                 self.toolt = toolt
  163.                 self.value = value
  164.                 self.comm_str = comm_str
  165.                 self.kb = kb
  166.                 self.afterbrn = afterbrn
  167.                 self.force_stereo =  force_stereo
  168.                 self.no_audio_enc = no_audio_enc
  169.         def __str__(self):
  170.                 return '{}, {}, {}'.format(self.label, self.codec, self.toolt)
  171.  
  172.  
  173. class AudioEncoder():
  174.        
  175.         # audio encoder
  176.         # value=(defvalue, lower, upper, step_inc, page_inc)
  177.        
  178.         AEfaaq = ACodec(label='AAC (faac quality Q)', codec='faaq', toolt=' faac vbr: q 80 ~96k, 90 ~100k, 100 ~118k, 120 ~128k, 160 ~156k, 330 ~270k, def:100 ', value=(100.0, 80, 330, 10, 1), comm_str='-c:a libfaac -q:a ')
  179.        
  180.         AEfaacb = ACodec(label='AAC (faac ABR Kb/s)', codec='faacb', toolt=' faac abr: 32-320 Kb/s def:112 ', value=(112.0, 64, 320, 8, 2), comm_str='-c:a libfaac -b:a ', kb=True)
  181.        
  182.         AEfdkaac = ACodec(label='AAC (fdk CBR Kb/s)', codec='fdkaac', toolt=' aac_fdk cbr: 64-320 Kb/s def:128 ', value=(128.0, 32, 320, 8, 2), comm_str='-c:a libfdk_aac -b:a ', kb=True, afterbrn=True)
  183.        
  184.         AElame = ACodec(label='MP3 (lame CBR Kb/s)', codec='lame', toolt=' lame mp3: 32-320 Kb/s def:128 ', value=(128.0, 32, 320, 8, 2), comm_str='-c:a libmp3lame -b:a ', kb=True)
  185.        
  186.         AElameq = ACodec(label='MP3 (lame VBR Q)', codec='lameq', toolt=' lame mp3 vbr: q 0 ~245Kb/s, 5 ~130Kb/s, 6 ~115Kb/s, 9 ~65Kb/s, def:6 ', value=(6.0, 0, 9, 1, 1), comm_str='-c:a libmp3lame -q:a ')
  187.        
  188.         AEaacn = ACodec(label='AAC (native CBR Kb/s)', codec='aacn', toolt=' aac cbr: 32-320 Kb/s def:128 ', value=(128.0, 34, 320, 8, 2), comm_str='-c:a aac -strict -2 -b:a ', kb=True)
  189.        
  190.         AEacopy = ACodec(label='Audio Copy', codec='acopy', no_audio_enc=True, comm_str='-c:a copy')
  191.        
  192.         AEanone = ACodec(label='No Audio', codec='anone',  no_audio_enc=True, comm_str='-an')
  193.        
  194.         AEaap32 = ACodec(label='AAC-HEv1 (aac+ 32 Kb/s)', codec='aap32', comm_str='-c:a libaacplus -b:a 32k')
  195.        
  196.         AEaap64 = ACodec(label='AAC-HEv1 (aac+ 64 Kb/s)', codec='aap64', comm_str='-c:a libaacplus -b:a 64k', force_stereo=True)
  197.        
  198.         AEfdkaac_he = ACodec(label='AAC-HEv1 (fdk Kb/s)', codec='fdkaac_he', toolt=' aac_fdk_he1 cbr: 48-64 Kb/s def:64 ', value=(64.0, 48, 64 , 2, 2), comm_str='-c:a libfdk_aac -profile:a aac_he -b:a ', kb=True, afterbrn=True)
  199.        
  200.         AEfdkaac_vbr = ACodec(label='AAC (fdk VBR Q)', codec='fdkaac_vbr', toolt=' aac_fdk vbr: 5 ~160K, 4 ~120K, 3 ~100K, 2 ~80K, 1 ~70K ', value=(2.0, 1, 5, 1, 1), comm_str='-c:a libfdk_aac -vbr ', afterbrn=True)
  201.  
  202.         # groups: ------------------------------
  203.        
  204.         AEall = (AEfaaq, AEfaacb, AEfdkaac, AElame, AElameq, AEaacn, AEacopy, AEanone, AEaap32, AEaap64, AEfdkaac_he, AEfdkaac_vbr)
  205.        
  206.         #
  207.         AEmp4 = (AEfaaq, AEfaacb, AEaacn, AEfdkaac, AEfdkaac_vbr, AEfdkaac_he, AEaap64, AEaap32, AElame, AElameq, AEacopy, AEanone)
  208.        
  209.         AEmp4_default = AEmp4.index(AEfdkaac_vbr)
  210.        
  211.         #
  212.         AEmka = (AEfaaq, AEfaacb, AEaacn, AEfdkaac, AEfdkaac_vbr, AEfdkaac_he, AEaap64, AEaap32, AElame, AElameq, AEacopy)
  213.        
  214.         AEmka_default = AEmka.index(AEfaaq)
  215.        
  216.         #
  217.         AEavi = (AElame, AElameq, AEacopy, AEanone)
  218.        
  219.         AEavi_default = AEavi.index(AElame)
  220.  
  221.         ######## AUDIO SAMPLE RATE ########################
  222.         AEaudio_sample = [
  223.                 '48000',
  224.                 '44100'
  225.                 ]
  226.  
  227.         ######## AUDIO CHANNEL ############################
  228.         AEaudio_channels = [
  229.                 "2",
  230.                 "1"
  231.                 ]
  232.  
  233. # ##########################  VIDEO  #################################
  234.  
  235. class VCodec(object):
  236.         def __init__(self, label=None, codec=None, comm_str=None, crf_val=None, br_val=None, q_val=None, kb=False, vrc=False, br2pass=False, preset=False, tune=False, opts=False, opts_comm=False, opencl=False, is10bit=False, pool=False, threads=False, no_video_enc=False):
  237.                 self.label = label
  238.                 self.codec = codec
  239.                 self.comm_str = comm_str
  240.                 self.crf_val = crf_val
  241.                 self.br_val = br_val
  242.                 self.q_val = q_val
  243.                 self.kb = kb
  244.                 self.vrc = vrc
  245.                 self.br2pass = br2pass
  246.                 self.preset = preset
  247.                 self.tune = tune
  248.                 self.opts = opts
  249.                 self.opts_comm = opts_comm
  250.                 self.opencl = opencl
  251.                 self.is10bit = is10bit
  252.                 self.pool = pool
  253.                 self.threads = threads
  254.                 self.no_video_enc = no_video_enc
  255.         def __str__(self):
  256.                 return '{}, {}, {}'.format(self.label, self.codec, self.comm_str)
  257.        
  258. class VideoEncoder():
  259.        
  260.         VEx264 = VCodec(label='AVC (x264)' , codec='x264', comm_str='-c:v libx264 ', crf_val=(21.3, 15, 40, 0.1, 1), br_val=(730.0, 100, 4000, 10, 100), kb=True, vrc=True, br2pass=True, preset=True, tune=True, opts=True, opts_comm=' -x264opts ', opencl=True,  threads=True )
  261.        
  262.         VEx265 = VCodec(label='HEVC (x265)' , codec='x265', comm_str='-c:v libx265 ', crf_val=(22.8, 15, 40, 0.1, 1), br_val=(400.0, 100, 4000, 10, 100), kb=True, vrc=True,  br2pass=True, preset=True, tune=True, opts=True, opts_comm=' -x265-params ', is10bit=True, pool=True )
  263.        
  264.         VEmpeg4 = VCodec(label='ASP (mpeg4)' , codec='mpeg4', comm_str='-c:v mpeg4 -mpv_flags strict_gop ', br_val=(1200.0, 300, 5000, 100, 100), q_val=(5.0, 1, 31, 1, 1), kb=True, vrc=True, br2pass=True )
  265.        
  266.         VEcopy = VCodec(label='Video Copy' , codec='vcopy', comm_str='-c:v copy', no_video_enc=True)
  267.        
  268.         VEnone = VCodec(label='No Video' , codec='none', comm_str='-vn', no_video_enc=True)
  269.        
  270.         # groups: ------------------------------
  271.        
  272.         VEall = (VEx264, VEx265, VEmpeg4, VEcopy, VEnone)
  273.        
  274.         #
  275.         VEmp4 = (VEx265, VEx264, VEmpeg4, VEcopy, VEnone)
  276.        
  277.         VEmp4_default = VEmp4.index(VEx265)
  278.        
  279.         #
  280.         VEavi = (VEmpeg4, VEcopy)
  281.        
  282.         VEavi_default = VEavi.index(VEmpeg4)
  283.        
  284.         #
  285.         VEmka = (VEnone, VEnone) # min 2 obj for self.cboxtxt_change2()
  286.        
  287.         VEmka_default = 0
  288.        
  289. ######################### OPTIONS ################################################
  290.  
  291. class VcOptions(object):
  292.         def __init__(self, label=None, comm_str=None, text_entry=False):
  293.                 self.label = label
  294.                 self.comm_str = comm_str
  295.                 self.text_entry = text_entry
  296.         def __str__(self):
  297.                 return '{}, {}'.format(self.label, self.comm_str)
  298.                
  299. class VcodecOptions():
  300.        
  301.         ### HEVC libx265 ############################################
  302.         OPThevc1 = VcOptions(label='none (ssim psnr)', comm_str='ssim=1:psnr=1', text_entry=True)
  303.        
  304.         OPThevc2 = VcOptions(label='db-4 psy0.5 no-sao', comm_str='rd=3:psy-rd=.5:no-sao=1:rc-lookahead=40:deblock=-4:ssim=1:psnr=1', text_entry=True)
  305.        
  306.         OPThevc3 = VcOptions(label='db-3 no-sao', comm_str='deblock=-3:no-sao=1:ssim=1:psnr=1', text_entry=True)
  307.        
  308.         OPThevc4 = VcOptions(label='1+aq-mode3', comm_str='rd=3:psy-rd=.5:aq-mode=3:no-sao=1:rc-lookahead=40:deblock=-3:ssim=1:psnr=1', text_entry=True)
  309.        
  310.         OPThevc5 = VcOptions(label='1+aq-mode3 rd2', comm_str='rd=2:psy-rd=.5:aq-mode=3:no-sao=1:rc-lookahead=40:deblock=-3:ssim=1:psnr=1', text_entry=True)
  311.        
  312.         #OPThevc6 = VcOptions(label='custom ->', text_entry=True)
  313.         #
  314.         OPTx265 = (OPThevc1, OPThevc2, OPThevc3, OPThevc4, OPThevc5)
  315.         OPTx265_default = OPTx265.index(OPThevc5)
  316.        
  317.         ### AVC libx264 #############################################
  318.         OPTavc1 = VcOptions(label='opts 1', comm_str='ref=4:bframes=4:direct=auto:aq-strength=1.3:ssim:psnr')
  319.        
  320.         OPTavc2 = VcOptions(label='no opts (ssim)', comm_str='ssim')
  321.         #
  322.         OPTx264 = (OPTavc1, OPTavc2)
  323.         OPTx264_default = OPTx264.index(OPTavc1)
  324.        
  325.         '''
  326.        input parse: list auto generate from html wiki page,
  327.        see http://http://x265.readthedocs.org/en/default/cli.html
  328.        '''
  329.         OPTx265_keys = ['log-level', 'ssim', 'no-ssim', 'psnr', 'no-psnr', 'asm', 'no-asm', 'frame-threads', 'pools', 'numa-pools', 'wpp', 'no-wpp', 'pmode', 'no-pmode', 'pme', 'no-pme', 'preset', 'tune', 'input-csp', 'fps', 'interlace', 'no-interlace', 'frames', 'level-idc', 'high-tier', 'no-high-tier', 'ref', 'allow-non-conformance', 'no-allow-non-conformance', 'rd', 'ctu', 'min-cu-size', 'limit-refs', 'limit-modes', 'no-limit-modes', 'rect', 'no-rect', 'amp', 'no-amp', 'early-skip', 'no-early-skip', 'fast-intra', 'no-fast-intra', 'b-intra', 'no-b-intra', 'cu-lossless', 'no-cu-lossless', 'tskip-fast', 'no-tskip-fast', 'analysis-mode', 'analysis-file', 'rdoq-level', 'no-rdoq-level', 'tu-intra-depth', 'tu-inter-depth', 'nr-intra', 'nr-inter', 'tskip', 'no-tskip', 'rdpenalty', 'max-tu-size', 'max-merge', 'me', 'subme', 'merange', 'temporal-mvp', 'no-temporal-mvp', 'weightp', 'no-weightp', 'weightb', 'no-weightb', 'strong-intra-smoothing', 'no-strong-intra-smoothing', 'constrained-intra', 'no-constrained-intra', 'psy-rd', 'psy-rdoq', 'open-gop', 'no-open-gop', 'keyint', 'min-keyint', 'scenecut', 'no-scenecut', 'intra-refresh', 'rc-lookahead', 'lookahead-slices', 'b-adapt', 'bframes', 'bframe-bias', 'b-pyramid', 'no-b-pyramid', 'bitrate', 'crf', 'crf-max', 'crf-min', 'vbv-bufsize', 'vbv-maxrate', 'vbv-init', 'qp', 'lossless', 'no-lossless', 'aq-mode', 'aq-strength', 'qg-size', 'cutree', 'no-cutree', 'pass', 'stats', 'slow-firstpass', 'no-slow-firstpass', 'strict-cbr', 'no-strict-cbr', 'cbqpoffs', 'crqpoffs', 'ipratio', 'pbratio', 'qcomp', 'qpstep', 'qblur', 'cplxblur', 'zones', 'signhide', 'no-signhide', 'qpfile', 'scaling-list', 'lambda-file', 'deblock', 'no-deblock', 'sao', 'no-sao', 'sao-non-deblock', 'no-sao-non-deblock', 'sar', 'display-window', 'overscan', 'videoformat', 'range', 'colorprim', 'transfer', 'colormatrix', 'chromaloc', 'master-display', 'max-cll', 'min-luma', 'max-luma', 'annexb', 'no-annexb', 'repeat-headers', 'no-repeat-headers', 'aud', 'no-aud', 'hrd', 'no-hrd', 'info', 'no-info', 'hash', 'temporal-layers']
  330.        
  331. ########## PRESET # TUNE # OUT CONTAINER ##########################################
  332.  
  333.  
  334. class AVContainer(object):
  335.         def __init__(self, label=None, cont=None, comm_str=None, ext=None, sub_stream=False, alist=None, vlist=None, audio_only=False):
  336.                 self.label = label
  337.                 self.cont = cont
  338.                 self.comm_str=comm_str
  339.                 self.ext = ext
  340.                 self.sub_stream = sub_stream
  341.                 self.alist = alist
  342.                 self.vlist = vlist
  343.                 self.audio_only = audio_only
  344.         def __str__(self):
  345.                 return '{}, {}'.format(self.label, self.ext)
  346.        
  347. class VideoRC(object):
  348.         def __init__(self, label=None):
  349.                 self.label = label
  350.         def __str__(self):
  351.                 return '{}'.format(self.label)
  352.        
  353. class VcodecOther():
  354.        
  355.         ### OUT CONTAINER ############################
  356.         CONTmkv = AVContainer(label='MKV', cont='mkv', comm_str='-f matroska', ext='.mkv', sub_stream=True, alist='mp4', vlist='mp4')
  357.        
  358.         CONTmp4 = AVContainer(label='MP4', cont='mp4', comm_str='-f mp4', ext='.mp4', alist='mp4', vlist='mp4')
  359.        
  360.         CONTavi = AVContainer(label='AVI', cont='avi', comm_str='-f avi', ext='.avi', alist='avi', vlist='avi')
  361.        
  362.         CONTmka = AVContainer(label='MKA', cont='mka', comm_str='-f matroska', ext='.mka', alist='mka', vlist='mka', audio_only=True)
  363.        
  364.         # group: ------------------------------
  365.         OutContainers = (CONTmkv, CONTmp4, CONTavi, CONTmka)
  366.        
  367.         OutContainers_default = OutContainers.index(CONTmkv)
  368.        
  369.         ### VIDEO RATE CONTROL ################################
  370.         VRCcrf = VideoRC(label='crf')
  371.         VRCbr = VideoRC(label='bitrate kb/s')
  372.         VRCq = VideoRC(label='qscale (1-31)')
  373.        
  374.         # groups: ------------------------------
  375.         VRCall = (VRCcrf, VRCbr, VRCq)
  376.         VRCx264 = (VRCcrf, VRCbr)
  377.         VRCx265 = (VRCcrf, VRCbr)
  378.         VRCmpeg4 = (VRCbr, VRCq)
  379.  
  380.         ### PRESET ################################
  381.         x264_preset = [
  382.                 "ultrafast",
  383.                 "superfast",
  384.                 "veryfast",
  385.                 "faster",
  386.                 "fast",
  387.                 "medium",
  388.                 "slow",
  389.                 "veryslow"
  390.                 ]
  391.        
  392.         x264_preset_default = x264_preset.index('faster')
  393.        
  394.         x265_preset = x264_preset
  395.        
  396.         x265_preset_default = x265_preset.index('superfast')
  397.        
  398.         ### TUNE ###################################
  399.         x264_tune = [
  400.                 "none",
  401.                 "film",
  402.                 "animation",
  403.                 "grain",
  404.                 "stillimage"
  405.                 ]
  406.        
  407.         x264_tune_default = x264_tune.index('film')
  408.        
  409.         x265_tune = [
  410.                 "none",
  411.                 "grain",
  412.                 "fastdecode",
  413.                 "zerolatency"
  414.                 ]
  415.        
  416.         x265_tune_default = x265_tune.index('none')
  417.        
  418. ###############################################################################
  419.  
  420. class ReuseInit(object):
  421.  
  422.         def make_label(self, text):
  423.                 label = Gtk.Label(text)
  424.                 label.set_use_underline(True)
  425.                 label.set_alignment(1.0, 0.5)
  426.                 label.show()
  427.                 return label
  428.  
  429.         def make_slider_and_spinner(self, init, min, max, step, page, digits):
  430.                 controls = {'adj':Gtk.Adjustment(init, min, max, step, page), 'slider':Gtk.HScale(), 'spinner':Gtk.SpinButton()}
  431.                 controls['slider'].set_adjustment(controls['adj'])
  432.                 controls['slider'].set_draw_value(False)
  433.                 controls['spinner'].set_adjustment(controls['adj'])
  434.                 controls['spinner'].set_digits(digits)
  435.                 controls['slider'].show()
  436.                 controls['spinner'].show()
  437.                 return controls
  438.        
  439.         def make_frame_ag(self, f_shadow_type, f_label, alig_pad, gri_row_sp, gri_colu_sp, gri_homog):
  440.                 controls =  {'frame':Gtk.Frame(), 'ali':Gtk.Alignment(), 'grid':Gtk.Grid()}
  441.                 controls['frame'].set_shadow_type(f_shadow_type) # 3 GTK_SHADOW_ETCHED_IN , 1 GTK_SHADOW_IN
  442.                 controls['frame'].set_label(f_label)
  443.                 controls['ali'].set_padding(alig_pad, alig_pad, alig_pad, alig_pad)
  444.                 controls['frame'].add(controls['ali'])
  445.                 controls['grid'].set_row_spacing(gri_row_sp)
  446.                 controls['grid'].set_column_spacing(gri_colu_sp)
  447.                 controls['grid'].set_column_homogeneous(gri_homog) # True
  448.                 controls['ali'].add(controls['grid'])
  449.                 controls['frame'].show()
  450.                 controls['ali'].show()
  451.                 controls['grid'].show()
  452.                 return controls
  453.        
  454.         def make_spinbut(self, init, min, max, step, page, digits, numeric):
  455.                 controls = {'adj':Gtk.Adjustment(init, min, max, step, page), 'spinner':Gtk.SpinButton()}
  456.                 controls['spinner'].set_adjustment(controls['adj'])
  457.                 controls['spinner'].set_digits(digits)
  458.                 controls['spinner'].set_numeric(numeric)
  459.                 controls['spinner'].show()
  460.                 return controls
  461.        
  462.         def make_combobox(self, *vals):
  463.                 controls = {'list':Gtk.ListStore(str), 'cbox':Gtk.ComboBox(), 'cellr':Gtk.CellRendererText()}
  464.                 for i, v in enumerate(vals):
  465.                         controls['list'].append([v])
  466.                 controls['cbox'].set_model(controls['list'])      
  467.                 controls['cbox'].pack_start(controls['cellr'], True)
  468.                 controls['cbox'].add_attribute(controls['cellr'], "text", 0)
  469.                 controls['cbox'].set_active(0)
  470.                 controls['cbox'].show()
  471.                 return controls
  472.        
  473.         def make_combobox_list(self, list):
  474.                 controls = {'list':Gtk.ListStore(str), 'cbox':Gtk.ComboBox(), 'cellr':Gtk.CellRendererText()}
  475.                 for i, v in enumerate(list):
  476.                         controls['list'].append([v])
  477.                 controls['cbox'].set_model(controls['list'])      
  478.                 controls['cbox'].pack_start(controls['cellr'], True)
  479.                 controls['cbox'].add_attribute(controls['cellr'], "text", 0)
  480.                 controls['cbox'].set_active(0)
  481.                 controls['cbox'].show()
  482.                 return controls
  483.        
  484.         def make_comboboxtext(self, list):
  485.                 ### list = [str, str]
  486.                 comboboxtext = Gtk.ComboBoxText()
  487.                 for i, v in enumerate(list):
  488.                         comboboxtext.append_text(v)
  489.                 comboboxtext.set_active(0)
  490.                 return comboboxtext
  491.        
  492.         def make_comboboxtext2(self, list):
  493.                 ### list = (obj, obj) min. 2 obj w .label property
  494.                 comboboxtext = Gtk.ComboBoxText()
  495.                 for i, v in enumerate(list):
  496.                         comboboxtext.append_text(v.label)
  497.                 comboboxtext.set_active(0)
  498.                 return comboboxtext
  499.        
  500.  
  501. class MyUtility():
  502.        
  503.         def hms2sec(self, hms):
  504.                 result = 0
  505.                 listin = hms.split(':')
  506.                 listin.reverse()
  507.                 for i in range(len(listin)):
  508.                         if listin[i].isdigit():
  509.                                 if i == 0:
  510.                                         mult = 1
  511.                                 if i == 1:
  512.                                         mult = 60
  513.                                 if i == 2:
  514.                                         mult = 3600
  515.                                 result += (int(listin[i])*mult)            
  516.                 return result
  517.        
  518.         def sec2hms(self, seconds):
  519.                 seconds = float(seconds)
  520.                 h = int(seconds/3600)
  521.                 if (h > 0):
  522.                         seconds = seconds - (h * 3600)
  523.                 m = int(seconds / 60)
  524.                 s = int(seconds - (m * 60))
  525.                 hms = "{0:0=2d}:{1:0=2d}:{2:0=2d}".format(h,m,s)
  526.                 return hms
  527.        
  528.         def check_out_file(self):
  529.                
  530.                 def check_codec_in_name(nameck):
  531.                         #
  532.                         if not(Vars.XvCheck.no_video_enc): # no vcopy or vn
  533.                                 namcodec = Vars.XvCheck.codec
  534.                                 clist = ('x265-10b', 'x265', 'x264', 'mpeg4', 'xvid', 'divx', 'XviD', 'DivX')
  535.                                 if self.check_3v_10bit.get_active() and self.check_3v_10bit.get_sensitive():
  536.                                         namcodec += '-10b'
  537.                                 for i in range(0,len(clist)):
  538.                                         if clist[i] in nameck:
  539.                                                 nameck = nameck.replace(clist[i], namcodec)
  540.                                                 break
  541.                                 if not(namcodec in nameck):
  542.                                         nameck = nameck + '.' + namcodec
  543.                                 ###
  544.                                 ###
  545.                         return nameck
  546.                
  547.                 name = os.path.splitext(Vars.basename)[0]
  548.                 name = check_codec_in_name(name)
  549.                 newname = Vars.outdir + '/' + name + Vars.ext
  550.                 if os.path.exists(newname):                    
  551.                         for i in range(2,20):
  552.                                 newname = Vars.outdir + '/' + name + '._' + str(i) + '_' + Vars.ext
  553.                                 if os.path.exists(newname) == False:
  554.                                         break
  555.                 Vars.newname = newname
  556.                 self.f3_run_outdir_label.set_tooltip_text(Vars.newname)
  557.                
  558.         def humansize(self, namefile):
  559.                 try:
  560.                         nbytes = os.path.getsize(namefile)
  561.                 except:
  562.                         return '0'
  563.                 suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
  564.                 if nbytes == 0: return '0 B'
  565.                 i = 0
  566.                 while nbytes >= 1024 and i < len(suffixes)-1:
  567.                         nbytes /= 1024.
  568.                         i += 1
  569.                 f = "{0:0.1f}".format(nbytes)
  570.                 return "{0:>5s} {1:2s}".format(f, suffixes[i])
  571.        
  572.         def version_from_filename(self):
  573.                 '''
  574.                filename must be:
  575.                4FFmpeg-n.nnn.py
  576.                '''
  577.                 try:
  578.                         #version = str(sys.argv[0])
  579.                         #version = os.path.basename(sys.argv[0])
  580.                         version = os.path.realpath(sys.argv[0]) # work w symlink
  581.                         version = os.path.basename(version)
  582.                 except:
  583.                         version = 'N/A'
  584.                         return version
  585.                 try:
  586.                         version = version.split('-')[1]
  587.                 except:
  588.                         version = 'N/A'
  589.                         return version
  590.                 if version[-3:] == ".py":
  591.                         try:
  592.                                 version = version[:-3]
  593.                         except:
  594.                                 version = 'N/A'
  595.                                 return version          
  596.                 return version
  597.  
  598.         def is_number(self, string):
  599.                 num_format = re.compile("^[\-]?[1-9][0-9]*\.?[0-9]+$")
  600.                 isnumber = re.match(num_format,string)
  601.                 return isnumber
  602.  
  603.  
  604. class UiElemController():
  605.        
  606.         def adj_change(self, adjustment, value, lower, upper , step_increment, page_increment):
  607.                 adjustment.set_value(value)
  608.                 adjustment.set_lower(lower)
  609.                 adjustment.set_upper(upper)
  610.                 adjustment.set_step_increment(step_increment)
  611.                 adjustment.set_page_increment(page_increment)
  612.                 #adjustment.set_page_size(page_size)
  613.  
  614.         def adj_change2(self, adjustment, tuple_5values):
  615.                 '''
  616.                tuple_5values=
  617.                (value , lower, upper, step_increment, page_increment)
  618.                or
  619.                [value , lower, upper, step_increment, page_increment]
  620.                '''
  621.                 adjustment.set_value(tuple_5values[0])
  622.                 adjustment.set_lower(tuple_5values[1])
  623.                 adjustment.set_upper(tuple_5values[2])
  624.                 adjustment.set_step_increment(tuple_5values[3])
  625.                 adjustment.set_page_increment(tuple_5values[4])
  626.                 #adjustment.set_page_size(page_size)
  627.  
  628.         def cboxtxt_change(self, the_cboxtext, the_function, item_list, item_selected, global_list, list_in_use):
  629.                 ### item_list = [str, str]
  630.                 the_cboxtext.disconnect_by_func(the_function)
  631.                 the_cboxtext.remove_all()
  632.                 for i, v in enumerate(item_list):
  633.                                 the_cboxtext.append_text(v)
  634.                 the_cboxtext.connect("changed", the_function)
  635.                 the_cboxtext.set_active(item_selected)
  636.                 objname = global_list.split('.')[0]
  637.                 glist = global_list.split('.')[1]
  638.                 setattr(globals()[objname], glist, list_in_use)
  639.                
  640.         def cboxtxt_change2(self, the_cboxtext, the_function, obj_list, item_selected, global_list, list_in_use):
  641.                 ### obj_list = (obj, obj) min. 2 obj w .label property
  642.                 the_cboxtext.disconnect_by_func(the_function)
  643.                 the_cboxtext.remove_all()
  644.                 for i, v in enumerate(obj_list):
  645.                                 the_cboxtext.append_text(v.label)
  646.                 the_cboxtext.connect("changed", the_function)
  647.                 the_cboxtext.set_active(item_selected)
  648.                 objname = global_list.split('.')[0]
  649.                 glist = global_list.split('.')[1]
  650.                 setattr(globals()[objname], glist, list_in_use)
  651.                
  652.         # old way ------------------------------------------------------------
  653.         #def x265_opt_list(self, selected):
  654.         #       self.box_3v_x264opts.disconnect_by_func(self.on_codec_clicked)
  655.         #       self.box_3v_x264opts.remove_all()
  656.         #       for i, v in enumerate(Vars.x265_opt):
  657.         #               self.box_3v_x264opts.append_text(v)
  658.         #       self.box_3v_x264opts.set_active(selected)
  659.         #       self.box_3v_x264opts.connect("changed", self.on_codec_clicked)
  660.         #       Vars.opt_list = 'x265'
  661.  
  662. #### MAIN #################################################################################################
  663.        
  664. class ProgrammaGTK(ReuseInit, UiElemController, MyUtility, AudioEncoder, VideoEncoder, VcodecOptions, VcodecOther):
  665.  
  666.         def __init__(self):
  667.                
  668.                 if Vars.version == '':
  669.                         Vars.version = self.version_from_filename()
  670.  
  671.                 self.make_ui()
  672.                 # initialization
  673.                 Vars.outdir = os.getcwd()
  674.                 Vars.indir = Vars.outdir
  675.                 Vars.XaCheck = AudioEncoder.AEall[0]
  676.                 Vars.XvCheck = VideoEncoder.VEall[0]
  677.                 self.on_codec_audio_changed(0)
  678.                 self.on_codec_video_changed(0)
  679.                 self.on_f3_other_clicked(0)
  680.                 self.on_container_changed(0)
  681.                
  682.                 if len(sys.argv) == 2:
  683.                         try:
  684.                                 Vars.filename = str(sys.argv[1])
  685.                                 self.file_changed()
  686.                         except:
  687.                                 pass
  688.  
  689.         def make_ui(self):
  690.  
  691.                 # ---------------------
  692.                 self.window =  Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
  693.                 self.window.connect("destroy", self.on_window_destroy)
  694.                 self.window.set_title("4FFmpeg")
  695.                 self.window.set_position(1) # 1 center, 0 none,
  696.                 self.window.set_border_width(3)
  697.                 self.window.set_default_size(500,-1)
  698.                 #----------------------------------
  699.                
  700.                 #page1 stuff VIDEO FILTERS------------------------------------------
  701.                                
  702.                 # page1 VBox -------------------------
  703.                 self.vbox1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
  704.                 #self.vbox1.set_orientation(Gtk.Orientation.VERTICAL) # Gtk.Orientation.HORIZONTAL
  705.                 #self.vbox1.set_spacing(2)
  706.                
  707.                 # map --------------------------------------
  708.                 self.make_map()        
  709.                 # add map frame
  710.                 self.vbox1.pack_start(self.f_map['frame'], 1, 0, 0)
  711.                
  712.                 #time cut ------------------------------------
  713.                 self.make_time_cut()
  714.                 # add time frame
  715.                 self.vbox1.pack_start(self.f_time['frame'], 1, 0, 0)
  716.                
  717.                 # deinterlace -----------------------
  718.                 self.make_deinterlace()
  719.                 # add deinterlace frame
  720.                 self.vbox1.pack_start(self.f_deint['frame'], 1, 0, 0)
  721.                
  722.                 # crop ----------------------------------------
  723.                 self.make_crop()        
  724.                 # add crop frame -------------------
  725.                 self.vbox1.pack_start(self.frame_crop['frame'], 1, 0, 0)
  726.        
  727.                 # scale ------------------------------
  728.                 self.make_scale()
  729.                 # add scale frame------------------
  730.                 self.vbox1.pack_start(self.frame_scale['frame'], 1, 0, 0)
  731.  
  732.                 # denoise ----------------------------
  733.                 self.make_denoise()
  734.                 # add denoise frame------------------------
  735.                 self.vbox1.pack_start(self.frame_dn['frame'], 1, 0, 0)
  736.                
  737.                 # page 1 filters------------------------
  738.                 self.frame_out = self.make_frame_ag(3, '  FFmpeg video filter string:  ' , 12, 8, 8, True)
  739.                 self.labelout = Gtk.Label("")
  740.                 self.labelout.set_selectable(1)
  741.                 self.labelout.set_width_chars(120)
  742.                 self.labelout.set_max_width_chars(130)
  743.                 self.labelout.set_line_wrap(True)
  744.                 self.frame_out['grid'].attach(self.labelout, 0, 0, 1 ,1)
  745.                 # add output frame ---------------------
  746.                 self.vbox1.pack_start(self.frame_out['frame'], 1, 0, 0)
  747.                 # end page1
  748.                
  749.                 # page2 stuff  UTILITY ------------------------------------------
  750.                
  751.                 # page2 VBox -------------------------
  752.                 self.vbox_pg2 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
  753.                
  754.                 #volumedetect ------------------------------------
  755.                 self.make_volume_det()
  756.                 # add volumedetect frame        
  757.                 self.vbox_pg2.pack_start(self.f_volume_det['frame'], 1, 0, 0)
  758.                
  759.                 #frames detect
  760.                 self.make_frames_det()
  761.                 # add  frames detect frame      
  762.                 self.vbox_pg2.pack_start(self.f_frames_det['frame'], 1, 0, 0)
  763.                
  764.                
  765.                 #drc ------------------------------------
  766.                 self.make_volume_drc()
  767.                 # add volumedetect frame        
  768.                 self.vbox_pg2.pack_start(self.f_volume_drc['frame'], 1, 0, 0)
  769.                
  770.                 #compand ---------------------------------------
  771.                 self.make_compand()
  772.                 # add frame
  773.                 self.vbox_pg2.pack_start(self.f_compand['frame'], 1, 0, 0)
  774.                
  775.                 #dynaudnorm-------------------
  776.                 self.make_dynaudnorm()
  777.                 # add frame
  778.                 self.vbox_pg2.pack_start(self.f_dynaudnorm['frame'], 1, 0, 0)
  779.                
  780.                 # black detect ----------------------------------
  781.                 self.make_black_detect()
  782.                 # add black_detect frame
  783.                 self.vbox_pg2.pack_start(self.f_blackd['frame'], 1, 0, 0)
  784.                
  785.                 # info frame----------------------
  786.                 self.make_info_frame()
  787.                 # add info frame
  788.                 self.vbox_pg2.pack_start(self.f_info['frame'], 1, 0, 0)
  789.                
  790.                 # end page2 stuff
  791.                
  792.                 # page 3 stuff  ffmpeg commands -----------------------------------------
  793.                
  794.                 # page3 VBox -------------------------
  795.                 self.vbox_pg3 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
  796.                
  797.                 # audio codec -------------------
  798.                 self.make_audio_codec()
  799.                 #add frame audio codec
  800.                 self.vbox_pg3.pack_start(self.f_3acodec['frame'], 1, 0, 0)
  801.                
  802.                 # video codec -------------------
  803.                 self.make_video_codec()
  804.                 #add frame video codec
  805.                 self.vbox_pg3.pack_start(self.f_3vcodec['frame'], 1, 0, 0)
  806.                
  807.                 # other options ----------------
  808.                 self.make_other_opts()
  809.                 #add frame other options
  810.                 self.vbox_pg3.pack_start(self.f3_oth['frame'], 1, 0, 0)
  811.                
  812.                 # page3 output ---------------------
  813.                 self.f3_out = self.make_frame_ag(3, "  FFmpeg command  " , 6, 8, 8, True)
  814.                 self.f3_out_label = Gtk.Label("")
  815.                 self.f3_out_label.set_width_chars(106)
  816.                 self.f3_out_label.set_max_width_chars(106)
  817.                 self.f3_out_label.set_line_wrap(True)
  818.                 self.f3_out_label.set_selectable(1)
  819.                 self.f3_out['grid'].attach(self.f3_out_label, 0, 0, 1, 1)
  820.                 # add frame page3 output
  821.                 self.vbox_pg3.pack_start(self.f3_out['frame'], 1, 0, 0)
  822.                
  823.                 # run ffmpeg ---------------------------------
  824.                 self.make_run_ffmpeg()
  825.                 # add frame run ffmpeg
  826.                 self.vbox_pg3.pack_start(self.f3_run['frame'], 1, 0, 0)
  827.                
  828.                
  829.                 #---------------------------------------------------
  830.                 # main vbox
  831.                 self.main_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
  832.                
  833.                 # notebook      
  834.                 self.notebook = Gtk.Notebook()
  835.                 self.notebook.set_tab_pos(Gtk.PositionType.TOP)  #GTK_POS_LEFT = 0
  836.                 self.notebook.set_show_border (False)
  837.                 self.main_vbox.pack_start(self.notebook, 1, 0, 0)
  838.                
  839.                 #page 1
  840.                 self.tab1label = Gtk.Label("Video filters")
  841.                 self.page1_ali = Gtk.Alignment()
  842.                 self.page1_ali.set_padding(0, 6, 6, 6)
  843.                 self.page1_ali.add(self.vbox1)
  844.                 self.notebook.append_page(self.page1_ali, self.tab1label)
  845.                
  846.                 #page 2
  847.                 self.tab2label = Gtk.Label("Utility")
  848.                 self.page2_ali = Gtk.Alignment()
  849.                 self.page2_ali.set_padding(0, 6, 6, 6)
  850.                 self.page2_ali.add(self.vbox_pg2)
  851.                 self.notebook.append_page(self.page2_ali, self.tab2label)
  852.                
  853.                 #page 3
  854.                 self.tab3label = Gtk.Label("Encode")
  855.                 self.page3_ali = Gtk.Alignment()
  856.                 self.page3_ali.set_padding(0, 6, 6, 6)
  857.                 self.page3_ali.add(self.vbox_pg3)
  858.                 self.notebook.append_page(self.page3_ali, self.tab3label)
  859.                
  860.                 #---------------------------------------------------
  861.                
  862.                 # low part BUTTONS AND TERM --------------------------
  863.                 self.make_low_part()
  864.                 # add low part-----------------
  865.                 self.main_vbox.pack_start(self.gridterm, 1, 1, 0)
  866.                
  867.                 #---------------------------------------------------------
  868.                 self.window.add (self.main_vbox)
  869.                 #---------------------------------
  870.                 self.window.show_all()          
  871.  
  872.         def make_deinterlace(self):
  873.                 self.f_deint = self.make_frame_ag(3, "" , 6, 8, 8, True)
  874.                 self.checkdeint = Gtk.CheckButton("deinterlace")
  875.                 self.checkdeint.connect("toggled", self.on_deint_clicked)
  876.                 self.f_deint['grid'].attach(self.checkdeint, 0, 0, 1, 1)
  877.                
  878.                 self.box_deint = self.make_combobox(
  879.                   "yadif",
  880.                   "postprocessing linear blend",
  881.                   "detect (use only with Test)"
  882.                   )
  883.                 self.f_deint['grid'].attach(self.box_deint['cbox'], 1, 0, 1, 1)
  884.                 self.box_deint['cbox'].connect("changed", self.on_deint_clicked)
  885.                 #
  886.                 self.f_deint['grid'].attach(self.make_label(""), 2, 0, 1, 1)
  887.        
  888.         def make_map(self):
  889.                 #
  890.                 self.f_map = self.make_frame_ag(3, "" , 6, 8, 8, False)
  891.                 #
  892.                 self.check_map = Gtk.CheckButton("map")
  893.                 self.check_map.connect("toggled", self.on_map_clicked) # toggled or activate (enter)
  894.                 self.f_map['grid'].attach(self.check_map, 0, 0, 1, 1)
  895.                 #
  896.                 self.mapstream_label = self.make_label("streams: ")
  897.                 self.f_map['grid'].attach(self.mapstream_label, 1, 0, 1, 1)
  898.                 #
  899.                 self.entry_map = Gtk.Entry()
  900.                 self.entry_map.set_tooltip_text(Tips.map_tooltip_str)
  901.                 self.entry_map.connect("changed", self.on_map_clicked)
  902.                 self.f_map['grid'].attach(self.entry_map, 2, 0, 1, 1)
  903.                 #
  904.                 self.map_label = Gtk.Label("")
  905.                 self.map_label.set_width_chars(70)
  906.                 self.f_map['grid'].attach(self.map_label, 3, 0, 2, 1)
  907.                 # placeholder
  908.                 self.f_map['grid'].attach(self.make_label("Version: " + Vars.version + "   "), 5, 0, 1, 1)
  909.                
  910.         def make_time_cut(self):
  911.                 #
  912.                 self.f_time = self.make_frame_ag(3, "" , 6, 8, 8, True)
  913.                 #
  914.                 self.check_time = Gtk.CheckButton("time")
  915.                 self.check_time.connect("toggled", self.on_time_clicked) # toggled or activate (enter)
  916.                 self.f_time['grid'].attach(self.check_time, 0, 0, 1, 1)
  917.                 #
  918.                 self.label_time_in = self.make_label("from: ")
  919.                 self.f_time['grid'].attach(self.label_time_in, 1, 0, 1, 1)
  920.                 self.entry_timein = Gtk.Entry()
  921.                 self.entry_timein.set_tooltip_text(Tips.time_tooltip_str)
  922.                 self.entry_timein.set_max_length(12)
  923.                 self.entry_timein.set_max_width_chars(12)
  924.                 self.entry_timein.set_width_chars(12)
  925.                 #self.entry_timein.set_halign(1)
  926.                 self.entry_timein.connect("changed", self.on_time_clicked)
  927.                 self.f_time['grid'].attach(self.entry_timein, 2, 0, 1, 1)
  928.                
  929.                 self.label_time_out = self.make_label("to: ")
  930.                 self.f_time['grid'].attach(self.label_time_out, 3, 0, 1, 1)
  931.                 self.entry_timeout = Gtk.Entry()
  932.                 self.entry_timeout.set_tooltip_text(Tips.time_tooltip_str)
  933.                 self.entry_timeout.set_max_length(12)
  934.                 self.entry_timeout.set_max_width_chars(12)
  935.                 self.entry_timeout.set_width_chars(12)
  936.                 self.entry_timeout.connect("changed", self.on_time_clicked)
  937.                 self.f_time['grid'].attach(self.entry_timeout, 4, 0, 1, 1)
  938.                 self.time_label = Gtk.Label('')
  939.                 self.f_time['grid'].attach(self.time_label, 5, 0, 2, 1)
  940.        
  941.         def make_scale(self):
  942.                 self.frame_scale = self.make_frame_ag(3, '  scale  ' , 6, 8, 8, False)
  943.                 # ------------------------------
  944.                 self.box_scale_side = self.make_combobox(
  945.                         "None",
  946.                         "W",
  947.                         "H"
  948.                         )
  949.                 self.box_scale_side['cbox'].set_size_request(180,-1)
  950.                 self.frame_scale['grid'].attach(self.box_scale_side['cbox'], 0, 0, 1, 1)
  951.                 self.box_scale_side['cbox'].connect("changed", self.on_scale_clicked)
  952.                 #------------------------------------
  953.                 self.box_scale_ar = self.make_combobox(
  954.                         "16/9",
  955.                         "4/3",
  956.                         "2.35/1"
  957.                         )
  958.                 self.frame_scale['grid'].attach(self.box_scale_ar['cbox'], 0, 1, 1, 1)
  959.                 self.box_scale_ar['cbox'].connect("changed", self.on_scale_clicked)
  960.                 #-----------------------------------------
  961.                 self.size_spinner = self.make_slider_and_spinner(720, 200, 2000, 8, 32, 0)
  962.                 self.frame_scale['grid'].attach(self.size_spinner['slider'], 1, 0, 1, 1)
  963.                 self.frame_scale['grid'].attach(self.size_spinner['spinner'], 2, 0, 1, 1)
  964.                 self.size_spinner['slider'].set_size_request(180,-1)
  965.                 self.size_spinner['adj'].set_value(720.001) #mettere decimali se no non si vede
  966.                 self.size_spinner['adj'].connect("value-changed", self.on_scale_clicked)
  967.                 #-------------------------------------------------------
  968.                 self.check_round = Gtk.CheckButton("round 8")
  969.                 self.check_round.connect("toggled", self.on_scale_clicked)
  970.                 self.frame_scale['grid'].attach(self.check_round, 1, 1, 1, 1)
  971.                 #
  972.                 self.check = Gtk.CheckButton("zscale")
  973.                 self.check.set_tooltip_text("  HQ resize with libzimg  ")
  974.                 self.check.connect("toggled", self.on_scale_clicked)
  975.                 self.frame_scale['grid'].attach(self.check, 2, 1, 1, 1)
  976.                 #custom scale string
  977.                 self.label_scalecustom = self.make_label("Custom filters (override all scale settings):")
  978.                 self.label_scalecustom.set_alignment(0.5, 0.5)
  979.                 self.frame_scale['grid'].attach(self.label_scalecustom, 3, 0, 1, 1)
  980.                 self.entry_scalecustom = Gtk.Entry()
  981.                 self.entry_scalecustom.set_tooltip_text(Tips.customscale_str)
  982.                 self.entry_scalecustom.connect("activate", self.on_scale_clicked)
  983.                 self.entry_scalecustom.set_max_length(250)
  984.                 self.entry_scalecustom.set_max_width_chars(57)
  985.                 self.frame_scale['grid'].attach(self.entry_scalecustom, 3, 1, 1, 1)
  986.                 self.entry_scalecustom_clean_button = Gtk.Button('<- Clear')
  987.                 self.entry_scalecustom_clean_button.connect("clicked", self.on_entry_scalecustom_clean_button)
  988.                 self.entry_scalecustom_clean_button.set_sensitive(False)
  989.                 self.frame_scale['grid'].attach(self.entry_scalecustom_clean_button, 4, 1, 1, 1)
  990.        
  991.         def make_crop(self):
  992.                 self.frame_crop = self.make_frame_ag(3, '' , 6, 2, 0, True)
  993.                 # -------
  994.                 self.checkcr = Gtk.CheckButton("crop")
  995.                 self.checkcr.connect("toggled", self.on_crop_clicked)
  996.                 self.frame_crop['grid'].attach(self.checkcr, 0, 0, 1, 1)
  997.                 #----------
  998.                 self.butcrode = Gtk.Button(label="Crop detect")
  999.                 self.butcrode.connect("clicked", self.on_butcrode_clicked)
  1000.                 self.butcrode.set_sensitive(False)
  1001.                 self.frame_crop['grid'].attach(self.butcrode, 0, 1, 1, 1)
  1002.                 #-----------
  1003.                 self.labelcropinw = self.make_label("input W: ")
  1004.                 self.frame_crop['grid'].attach(self.labelcropinw, 1, 0, 1, 1)
  1005.                 self.labelcropinh = self.make_label("input H: ")
  1006.                 self.frame_crop['grid'].attach(self.labelcropinh, 1, 1, 1, 1)
  1007.                 #
  1008.                 self.spincw = self.make_spinbut(640 , 100 , 1920 , 10 , 1 , 0, True )
  1009.                 self.spincw["adj"].connect("value-changed", self.on_crop_clicked)
  1010.                 self.frame_crop['grid'].attach(self.spincw["spinner"], 2, 0, 1, 1)
  1011.                 #
  1012.                 self.spinch = self.make_spinbut(480 , 100 , 1280 , 10 , 1 , 0, True )
  1013.                 self.spinch["adj"].connect("value-changed", self.on_crop_clicked)
  1014.                 self.frame_crop['grid'].attach(self.spinch["spinner"], 2, 1, 1, 1)
  1015.                 #
  1016.                
  1017.                 self.labelcroptop = self.make_label("crop Top: ")
  1018.                 self.frame_crop['grid'].attach(self.labelcroptop, 3, 0, 1, 1)
  1019.                 self.labelcropbot = self.make_label("crop Bottom: ")
  1020.                 self.frame_crop['grid'].attach(self.labelcropbot, 3, 1, 1, 1)
  1021.                 #
  1022.                
  1023.                 self.spinct = self.make_spinbut(0 , 0 , 600 , 1 , 10 , 0, True )
  1024.                 self.spinct["adj"].connect("value-changed", self.on_crop_clicked)
  1025.                 self.frame_crop['grid'].attach(self.spinct["spinner"], 4, 0, 1, 1)
  1026.                 #
  1027.                 self.spincb = self.make_spinbut(0 , 0 , 600 , 1 , 10 , 0, True )
  1028.                 self.spincb["adj"].connect("value-changed", self.on_crop_clicked)
  1029.                 self.frame_crop['grid'].attach(self.spincb["spinner"], 4, 1, 1, 1)
  1030.                 #
  1031.                
  1032.                 self.labelcroplef = self.make_label("crop Left: ")
  1033.                 self.frame_crop['grid'].attach(self.labelcroplef, 5, 0, 1, 1)
  1034.                 self.labelcroprig = self.make_label("crop Right: ")
  1035.                 self.frame_crop['grid'].attach(self.labelcroprig, 5, 1, 1, 1)
  1036.                 #
  1037.                 self.spincl = self.make_spinbut(0 , 0 , 600 , 1 , 10 , 0, True )
  1038.                 self.spincl["adj"].connect("value-changed", self.on_crop_clicked)
  1039.                 self.frame_crop['grid'].attach(self.spincl["spinner"], 6, 0, 1, 1)
  1040.                 #
  1041.                 self.spincr = self.make_spinbut(0 , 0 , 600 , 1 , 10 , 0, True )
  1042.                 self.spincr["adj"].connect("value-changed", self.on_crop_clicked)
  1043.                 self.frame_crop['grid'].attach(self.spincr["spinner"], 6, 1, 1, 1)
  1044.  
  1045.         def make_denoise(self):
  1046.                 self.frame_dn = self.make_frame_ag(3, '  denoise / unsharp luma chroma / frame rate   ' , 6, 8, 8, True)
  1047.                 # denoise ----------------------
  1048.                 self.checkdn = Gtk.CheckButton("hqdn3d:")
  1049.                 self.checkdn.set_alignment(1.0, 0.5)
  1050.                 self.checkdn.set_halign(2)
  1051.                 self.checkdn.connect("toggled", self.on_dn_clicked)
  1052.                 self.frame_dn['grid'].attach(self.checkdn, 0, 0, 1, 1)
  1053.                 #
  1054.                 self.spindn = self.make_spinbut(4 , 2 , 8 , 1 , 10 , 0, True )
  1055.                 self.spindn["adj"].connect("value-changed", self.on_dn_clicked)
  1056.                 #self.spindn['spinner'].set_max_length(1)
  1057.                 #self.spindn['spinner'].set_width_chars(1)
  1058.                 self.frame_dn['grid'].attach(self.spindn["spinner"], 1, 0, 1, 1)
  1059.                 # -----------------------
  1060.                 # unsharp unsharp=5:5:luma:5:5:chroma, luma chroma -1.5 to 1.5
  1061.                 self.checkuns = Gtk.CheckButton("unsharp l/c:")
  1062.                 self.checkuns.set_alignment(1.0, 0.5)
  1063.                 self.checkuns.set_halign(2)
  1064.                 self.checkuns.connect("toggled", self.on_uns_clicked)
  1065.                 self.frame_dn['grid'].attach(self.checkuns, 2, 0, 1, 1)
  1066.                 self.spinunsl = self.make_spinbut(0.0 , -1.5 , 1.5 , .1 , .01 , 2, True )
  1067.                 self.spinunsl["adj"].connect("value-changed", self.on_uns_clicked)
  1068.                 self.frame_dn['grid'].attach(self.spinunsl["spinner"], 3, 0, 1, 1)
  1069.                 self.spinunsc = self.make_spinbut(0.0 , -1.5 , 1.5 , .1 , .01 , 2, True )
  1070.                 self.spinunsc["adj"].connect("value-changed", self.on_uns_clicked)
  1071.                 self.frame_dn['grid'].attach(self.spinunsc["spinner"], 4, 0, 1, 1)
  1072.                 # framerate --------------------------
  1073.                 self.checkfr = Gtk.CheckButton("frame rate:")
  1074.                 self.checkfr.set_alignment(1.0, 0.5)
  1075.                 self.checkfr.set_halign(2)
  1076.                 self.checkfr.connect("toggled", self.on_fr_clicked)
  1077.                 self.frame_dn['grid'].attach(self.checkfr, 5, 0, 1, 1)
  1078.                 self.spinfr = self.make_spinbut(0 , 0 , 100 , 1 , 10 , 2, True )
  1079.                 self.spinfr["adj"].connect("value-changed", self.on_fr_clicked)
  1080.                 self.frame_dn['grid'].attach(self.spinfr["spinner"], 6, 0, 1, 1)
  1081.  
  1082.         def make_low_part(self):
  1083.                 # grid
  1084.                 self.gridterm = Gtk.Grid()
  1085.                 self.gridterm.set_row_spacing(2)
  1086.                 self.gridterm.set_column_spacing(2)
  1087.                 self.gridterm.set_column_homogeneous(True) # True
  1088.                 # filechooserbutton
  1089.                 self.but_file = Gtk.Button("Choose File")
  1090.                 self.but_file.connect("clicked", self.on_but_file)
  1091.                 self.but_file.set_tooltip_text(Tips.but_file_str)
  1092.                 #ff command button
  1093.                 self.butplay = Gtk.Button(label="FFplay")
  1094.                 self.butplay.connect("clicked", self.on_butplay_clicked)
  1095.                 self.butplay.set_sensitive(False)
  1096.                 self.butplay.set_tooltip_text(Tips.ffplay_tooltip_str)
  1097.                 #
  1098.                 self.butprobe = Gtk.Button(label="FFprobe")
  1099.                 self.butprobe.connect("clicked", self.on_butprobe_clicked)
  1100.                 self.butprobe.set_sensitive(False)
  1101.                 #
  1102.                 self.buttest = Gtk.Button(label="Test")
  1103.                 self.buttest.connect("clicked", self.on_buttest_clicked)
  1104.                 self.buttest.set_sensitive(False)
  1105.                 #
  1106.                 self.buttestspl = Gtk.Button(label="Test split")
  1107.                 self.buttestspl.connect("clicked", self.on_buttestspl_clicked)
  1108.                 self.buttestspl.set_sensitive(False)
  1109.                 # copy term button
  1110.                 self.butt_vtecopy = Gtk.Button(label="Copy term")
  1111.                 self.butt_vtecopy.connect("clicked", self.on_butt_vtecopy_clicked)
  1112.                 # vte terminal
  1113.                 self.terminal     = Vte.Terminal()
  1114.                 try: # vte 2.90
  1115.                         self.terminal.fork_command_full(
  1116.                                 Vte.PtyFlags.DEFAULT, #default is fine
  1117.                                 os.getcwd(), #where to start the command?   os.environ['HOME']
  1118.                                 ["/bin/sh"], #where is the emulator?
  1119.                                 [], #it's ok to leave this list empty
  1120.                                 GLib.SpawnFlags.DO_NOT_REAP_CHILD,
  1121.                                 None, #at least None is required
  1122.                                 None,
  1123.                         )
  1124.                 except: # vte 2.91
  1125.                         self.terminal.spawn_sync(
  1126.                                 Vte.PtyFlags.DEFAULT, #default is fine
  1127.                                 os.getcwd(), #where to start the command?   os.environ['HOME']
  1128.                                 ["/bin/sh"], #where is the emulator?
  1129.                                 [], #it's ok to leave this list empty
  1130.                                 GLib.SpawnFlags.DO_NOT_REAP_CHILD,
  1131.                                 None, #at least None is required
  1132.                                 None,
  1133.                                 )
  1134.                 # scroller
  1135.                 self.scroller = Gtk.ScrolledWindow()
  1136.                 self.scroller.set_hexpand(True)
  1137.                 self.scroller.set_vexpand(True)
  1138.                 self.scroller.set_min_content_height(90)
  1139.                 self.scroller.add(self.terminal)
  1140.                 # attach to grid
  1141.                 self.gridterm.attach(self.but_file, 0, 0, 2, 1)
  1142.                 self.gridterm.attach(self.butprobe, 2, 0, 1, 1)
  1143.                 self.gridterm.attach(self.butplay, 3, 0, 1, 1)
  1144.                 self.gridterm.attach(self.buttest, 4, 0, 1, 1)
  1145.                 self.gridterm.attach(self.buttestspl, 5, 0, 1, 1)
  1146.                 self.gridterm.attach(self.butt_vtecopy, 6, 0, 1, 1)
  1147.                 self.gridterm.attach(self.scroller, 0, 1, 7, 1)
  1148.  
  1149.         def make_volume_det(self):
  1150.                 self.f_volume_det = self.make_frame_ag(3, "" , 6, 8, 8, True)
  1151.                 #
  1152.                 self.but_volume_det = Gtk.Button(label="Volume detect")
  1153.                 self.but_volume_det.connect("clicked", self.on_but_volume_det_clicked)
  1154.                 self.f_volume_det['grid'].attach(self.but_volume_det, 0, 0, 1, 1)
  1155.                 self.but_volume_det.set_sensitive(False)
  1156.                 #
  1157.                 self.voldet_spin = Gtk.Spinner()
  1158.                 self.voldet_spin.set_sensitive(False)
  1159.                 self.f_volume_det['grid'].attach(self.voldet_spin, 1, 0, 1, 1)
  1160.                 #
  1161.                 self.label_maxvol = Gtk.Label("")
  1162.                 self.f_volume_det['grid'].attach(self.label_maxvol, 2, 0, 1, 1)
  1163.                 self.label_meanvol = Gtk.Label("")
  1164.                 self.f_volume_det['grid'].attach(self.label_meanvol, 3, 0, 1, 1)
  1165.                 #
  1166.                 self.check_vol = Gtk.CheckButton("volume")
  1167.                 self.check_vol.connect("toggled", self.on_volume_clicked)
  1168.                 self.f_volume_det['grid'].attach(self.check_vol, 0, 1, 1, 1)
  1169.                 #
  1170.                 self.label_db = self.make_label("dB: ")
  1171.                 self.f_volume_det['grid'].attach(self.label_db, 1, 1, 1, 1)
  1172.                 self.spin_db = self.make_spinbut(0 , -6 , 20 , 0.1 , 1 , 2, True )
  1173.                 self.spin_db["adj"].connect("value-changed", self.on_volume_clicked)
  1174.                 self.f_volume_det['grid'].attach(self.spin_db["spinner"], 2, 1, 1, 1)
  1175.                 self.label_ratio = self.make_label("ratio: ")
  1176.                 self.f_volume_det['grid'].attach(self.label_ratio, 3, 1, 1, 1)
  1177.                 self.label_ratio_val = Gtk.Label("1")
  1178.                 self.f_volume_det['grid'].attach(self.label_ratio_val, 4, 1, 1, 1)
  1179.  
  1180.         def make_frames_det(self):
  1181.                 self.f_frames_det = self.make_frame_ag(3, "" , 6, 8, 8, True)
  1182.                 #
  1183.                 self.but_frames_det = Gtk.Button(label="Total frames detect")
  1184.                 self.but_frames_det.connect("clicked", self.on_but_frames_det_clicked)
  1185.                 self.f_frames_det['grid'].attach(self.but_frames_det, 0, 0, 1, 1)
  1186.                 self.but_frames_det.set_sensitive(False)
  1187.                 #
  1188.                 self.framesdet_spin = Gtk.Spinner()
  1189.                 self.framesdet_spin.set_sensitive(False)
  1190.                 self.f_frames_det['grid'].attach(self.framesdet_spin, 1, 0, 1, 1)
  1191.                 #
  1192.                 self.label_framesdet = Gtk.Label("N/A")
  1193.                 self.f_frames_det['grid'].attach(self.label_framesdet, 2, 0, 1, 1)
  1194.                 self.label_framesdet.set_selectable(True)
  1195.                 #
  1196.                 #placeholder
  1197.                 #self.f_frames_det['grid'].attach(Gtk.Label(''), 3, 0, 2, 1)
  1198.                 ###
  1199.                 self.entry_time2frame = Gtk.Entry()
  1200.                 self.entry_time2frame.set_tooltip_text(Tips.time2frame_str)
  1201.                 self.entry_time2frame.set_max_length(12)
  1202.                 self.entry_time2frame.set_max_width_chars(12)
  1203.                 self.entry_time2frame.set_width_chars(12)
  1204.                 self.entry_time2frame.connect("changed", self.on_time2frame_clicked)
  1205.                 self.f_frames_det['grid'].attach(self.entry_time2frame, 3, 0, 1, 1)
  1206.                 self.label_time2frame = Gtk.Label('')
  1207.                 self.label_time2frame.set_selectable(True)
  1208.                 self.label_time2frame.set_tooltip_text(" calculated frames  ")
  1209.                 self.f_frames_det['grid'].attach(self.label_time2frame, 4, 0, 2, 1)
  1210.  
  1211.         def make_volume_drc(self):
  1212.                 self.f_volume_drc = self.make_frame_ag(3, "" , 6, 8, 8, True)
  1213.                 self.check_drc = Gtk.CheckButton("ac3 input drc scale")
  1214.                 self.check_drc.connect("toggled", self.on_drc_clicked)
  1215.                 self.f_volume_drc['grid'].attach(self.check_drc, 0, 0, 1, 1)
  1216.                 self.check_drc.set_sensitive(False)
  1217.                 #
  1218.                 self.spin_drc = self.make_spinbut(1 , 0 , 6 , 1 , 1 , 0, True )
  1219.                 self.spin_drc["adj"].connect("value-changed", self.on_drc_clicked)
  1220.                 self.spin_drc['spinner'].set_tooltip_text(Tips.drc_str)
  1221.                 self.f_volume_drc['grid'].attach(self.spin_drc["spinner"], 1, 0, 1, 1)
  1222.                 self.spin_drc["spinner"].set_sensitive(False)
  1223.                 #
  1224.                 #placeholder
  1225.                 self.f_volume_drc['grid'].attach(Gtk.Label(''), 2, 0, 3, 1)
  1226.  
  1227.         def make_compand(self):
  1228.                 #
  1229.                 self.f_compand = self.make_frame_ag(3, "" , 6, 8, 8, False)
  1230.                 #
  1231.                 self.check_compand = Gtk.CheckButton("compand")
  1232.                 self.check_compand.connect("toggled", self.on_compand_clicked)
  1233.                 self.f_compand['grid'].attach(self.check_compand, 0, 0, 1, 1)
  1234.                 #
  1235.                 self.entry_compand = Gtk.Entry()
  1236.                 self.entry_compand.set_text(Vars.compinit)
  1237.                 self.entry_compand.set_width_chars(60)
  1238.                 self.entry_compand.connect("changed", self.on_compand_clicked)
  1239.                 self.entry_compand.set_tooltip_text(Tips.compad_str)
  1240.                 self.f_compand['grid'].attach(self.entry_compand, 1, 0, 2, 1)
  1241.                 #
  1242.                 self.compand_reset = Gtk.Button(label="reset")
  1243.                 self.compand_reset.set_size_request(110,-1)
  1244.                 self.compand_reset.connect("clicked", self.on_compand_reset)
  1245.                 self.f_compand['grid'].attach(self.compand_reset, 3, 0, 1, 1)
  1246.                 self.compand_test = Gtk.Button(label="test ebur128")
  1247.                 self.compand_test.set_size_request(110,-1)
  1248.                 self.compand_test.set_sensitive(False)
  1249.                 self.compand_test.connect("clicked", self.on_compand_test)
  1250.                 self.f_compand['grid'].attach(self.compand_test, 4, 0, 1, 1)
  1251.                 self.compand_volume = Gtk.Button(label="test volume")
  1252.                 self.compand_volume.set_size_request(110,-1)
  1253.                 self.compand_volume.set_sensitive(False)
  1254.                 self.compand_volume.connect("clicked", self.on_compand_volume)
  1255.                 self.f_compand['grid'].attach(self.compand_volume, 5, 0, 1, 1)
  1256.  
  1257.         def make_dynaudnorm(self):
  1258.                 #
  1259.                 self.f_dynaudnorm = self.make_frame_ag(3, "" , 6, 8, 8, False)
  1260.                 #
  1261.                 self.check_dynaudnorm = Gtk.CheckButton("dynaudnorm")
  1262.                 self.check_dynaudnorm.connect("toggled", self.on_dynaudnorm_clicked)
  1263.                 self.f_dynaudnorm['grid'].attach(self.check_dynaudnorm, 0, 0, 1, 1)
  1264.                 #
  1265.                 self.entry_dynaudnorm = Gtk.Entry()
  1266.                 self.entry_dynaudnorm.set_text(Vars.dynaudnorm)
  1267.                 self.entry_dynaudnorm.set_width_chars(57)
  1268.                 self.entry_dynaudnorm.connect("changed", self.on_dynaudnorm_clicked)
  1269.                 self.entry_dynaudnorm.set_tooltip_text(Tips.dynaudnorm_str)
  1270.                 self.f_dynaudnorm['grid'].attach(self.entry_dynaudnorm, 1, 0, 2, 1)
  1271.                 #
  1272.                 self.compand_dynaudnorm = Gtk.Button(label="reset")
  1273.                 self.compand_dynaudnorm.set_size_request(110,-1)
  1274.                 self.compand_dynaudnorm.connect("clicked", self.on_dynaudnorm_reset)
  1275.                 self.f_dynaudnorm['grid'].attach(self.compand_dynaudnorm, 3, 0, 1, 1)
  1276.                 self.dynaudnorm_test = Gtk.Button(label="test ebur128")
  1277.                 self.dynaudnorm_test.set_size_request(110,-1)
  1278.                 self.dynaudnorm_test.set_sensitive(False)
  1279.                 self.dynaudnorm_test.connect("clicked", self.on_dynaudnorm_test)
  1280.                 self.f_dynaudnorm['grid'].attach(self.dynaudnorm_test, 4, 0, 1, 1)
  1281.                 self.dynaudnorm_volume = Gtk.Button(label="test volume")
  1282.                 self.dynaudnorm_volume.set_size_request(110,-1)
  1283.                 self.dynaudnorm_volume.set_sensitive(False)
  1284.                 self.dynaudnorm_volume.connect("clicked", self.on_dynaudnorm_volume)
  1285.                 self.f_dynaudnorm['grid'].attach(self.dynaudnorm_volume, 5, 0, 1, 1)
  1286.  
  1287.         def make_black_detect(self):
  1288.                 self.f_blackd = self.make_frame_ag(3, "" , 6, 8, 8, True)
  1289.                 #
  1290.                 self.but_black_det = Gtk.Button(label="Black detect")
  1291.                 self.but_black_det.connect("clicked", self.on_but_black_det_clicked)
  1292.                 self.but_black_det.set_sensitive(False)
  1293.                 self.f_blackd['grid'].attach(self.but_black_det, 0, 0, 1, 1)
  1294.                 #
  1295.                 self.blackdet_spin = Gtk.Spinner()
  1296.                 self.blackdet_spin.set_sensitive(False)
  1297.                 self.f_blackd['grid'].attach(self.blackdet_spin, 1, 0, 1, 1)
  1298.                 #
  1299.                 scrolledwindow = Gtk.ScrolledWindow()
  1300.                 #scrolledwindow.set_hexpand(True)
  1301.                 scrolledwindow.set_vexpand(True)
  1302.                 scrolledwindow.set_min_content_height(60)
  1303.                 self.textview = Gtk.TextView()
  1304.                 self.textbuffer = self.textview.get_buffer()
  1305.                 self.textview.set_editable(False)
  1306.                 self.textview.set_cursor_visible(False)
  1307.                 self.textview.modify_font(Pango.font_description_from_string('Monospace 9'))
  1308.                 scrolledwindow.add(self.textview)
  1309.                 self.textbuffer.set_text(Tips.black_dt_init_str)
  1310.                 self.f_blackd['grid'].attach(scrolledwindow, 2, 0, 3, 3)
  1311.                 #
  1312.                 self.progressbar_black_det = Gtk.ProgressBar()
  1313.                 self.f_blackd['grid'].attach(self.progressbar_black_det, 0, 1, 1, 1)
  1314.  
  1315.         def make_info_frame(self):
  1316.                 self.f_info = self.make_frame_ag(3, "  info  " , 6, 8, 8, True)
  1317.                 scrolledwindow1 = Gtk.ScrolledWindow()
  1318.                 scrolledwindow1.set_hexpand(True)
  1319.                 scrolledwindow1.set_vexpand(True)
  1320.                 scrolledwindow1.set_min_content_height(50)
  1321.                 self.textview_info = Gtk.TextView()
  1322.                 self.textbuffer_info = self.textview_info.get_buffer()
  1323.                 self.textview_info.set_editable(False)
  1324.                 self.textview_info.set_cursor_visible(False)
  1325.                 self.textview_info.modify_font(Pango.font_description_from_string('Monospace 9'))
  1326.                 scrolledwindow1.add(self.textview_info)
  1327.                 self.f_info['grid'].attach(scrolledwindow1, 0, 0, 3, 3)
  1328.  
  1329.         def make_audio_codec(self):
  1330.                 #
  1331.                 self.f_3acodec = self.make_frame_ag(3, "  audio codec  " , 6, 8, 8, False)
  1332.                 #
  1333.                 self.box_ac = self.make_comboboxtext2(AudioEncoder.AEmp4)
  1334.                 self.box_ac.set_active(AudioEncoder.AEmp4_default)
  1335.                 self.f_3acodec['grid'].attach(self.box_ac, 0, 0, 1, 1)
  1336.                 self.box_ac.connect("changed", self.on_codec_audio_changed)
  1337.                 #
  1338.                 self.spin_ac = self.make_spinbut(100 , 80 , 160 , 10 , 1 , 0, True )
  1339.                 self.spin_ac["adj"].connect("value-changed", self.on_audio_clicked)
  1340.                 self.f_3acodec['grid'].attach(self.spin_ac["spinner"], 1, 0, 1, 1)
  1341.                 #
  1342.                 label = self.make_label('sample: ')
  1343.                 self.f_3acodec['grid'].attach(label, 3, 0, 1, 1)
  1344.                 self.box_audio_rate = self.make_comboboxtext(AudioEncoder.AEaudio_sample)
  1345.                 self.box_audio_rate.set_tooltip_text(Tips.audio_samp_str)
  1346.                 self.box_audio_rate.connect("changed", self.on_codec_audio_changed)
  1347.                 self.f_3acodec['grid'].attach(self.box_audio_rate, 4, 0, 1, 1)
  1348.                 #
  1349.                 self.check_soxr = Gtk.CheckButton("soxr")
  1350.                 self.check_soxr.set_tooltip_text('  use SoX Resampler (libsoxr)   ')
  1351.                 self.check_soxr.set_active(False)
  1352.                 self.check_soxr.set_sensitive(False)
  1353.                 self.check_soxr.connect("toggled", self.on_codec_audio_changed)
  1354.                 self.f_3acodec['grid'].attach(self.check_soxr, 5, 0, 1, 1)
  1355.                 #
  1356.                 #
  1357.                 label = self.make_label('ch: ')
  1358.                 self.f_3acodec['grid'].attach(label, 6, 0, 1, 1)
  1359.                 self.box_audio_ch = self.make_comboboxtext(AudioEncoder.AEaudio_channels)
  1360.                 self.box_audio_ch.set_tooltip_text(Tips.audio_channels_str)
  1361.                 self.box_audio_ch.connect("changed", self.on_codec_audio_changed)
  1362.                 self.f_3acodec['grid'].attach(self.box_audio_ch, 7, 0, 1, 1)
  1363.                 self.check_prologic = Gtk.CheckButton("prologic2")
  1364.                 self.check_prologic.set_sensitive(False)
  1365.                 self.check_prologic.connect("toggled", self.on_codec_audio_changed)
  1366.                 self.f_3acodec['grid'].attach(self.check_prologic, 8, 0, 1, 1)
  1367.                 self.check_afterb = Gtk.CheckButton("fdk afterburner")
  1368.                 self.check_afterb.set_active(True)
  1369.                 self.check_afterb.set_sensitive(False)
  1370.                 self.check_afterb.connect("toggled", self.on_codec_audio_changed)
  1371.                 self.f_3acodec['grid'].attach(self.check_afterb, 9, 0, 1, 1)
  1372.  
  1373.         def make_video_codec(self):
  1374.                 self.f_3vcodec = self.make_frame_ag(3, "  video codec  " , 6, 8, 8, False)
  1375.                 self.box_vcodec = self.make_comboboxtext2(VideoEncoder.VEmp4)
  1376.                 self.box_vcodec.set_active(VideoEncoder.VEmp4_default)
  1377.                 self.box_vcodec.set_size_request(180,-1)
  1378.                 self.f_3vcodec['grid'].attach(self.box_vcodec, 0, 0, 1, 1)
  1379.                 self.box_vcodec.connect("changed", self.on_codec_video_changed)
  1380.                 #
  1381.                 self.box_vrc = self.make_comboboxtext2(VcodecOther.VRCall)
  1382.                 self.box_vrc.set_size_request(180,-1)
  1383.                 self.f_3vcodec['grid'].attach(self.box_vrc, 1, 0, 1, 1)
  1384.                 self.box_vrc.connect("changed", self.on_codec_vrc_changed)
  1385.                 #
  1386.                 self.spin_vc = self.make_spinbut(21.3 , 15 , 40 , 0.1 , 1 , 1, True )
  1387.                 self.spin_vc["adj"].connect("value-changed", self.on_codec_vrc_value_change)
  1388.                 self.f_3vcodec['grid'].attach(self.spin_vc["spinner"], 2, 0, 1, 1)
  1389.                 #
  1390.                 # x265 pools 3 x264 threads
  1391.                 self.check_3v_pool = Gtk.CheckButton("threads/pools 3")
  1392.                 self.check_3v_pool.connect("toggled", self.on_codec_clicked)
  1393.                 self.f_3vcodec['grid'].attach(self.check_3v_pool, 3, 0, 1, 1)
  1394.                 # x26510bit
  1395.                 self.check_3v_10bit = Gtk.CheckButton("x265 10bit")
  1396.                 self.check_3v_10bit.connect("toggled", self.on_codec_clicked)
  1397.                 self.f_3vcodec['grid'].attach(self.check_3v_10bit, 4, 0, 1, 1)
  1398.                 # opencl
  1399.                 self.check_3v_opencl = Gtk.CheckButton("opencl")
  1400.                 self.check_3v_opencl.connect("toggled", self.on_codec_clicked)
  1401.                 self.f_3vcodec['grid'].attach(self.check_3v_opencl, 5, 0, 1, 1)
  1402.                 # x264 preset
  1403.                 self.box_3v_preset = self.make_comboboxtext(VcodecOther.x264_preset)
  1404.                 #self.box_3v_preset.set_active(3)
  1405.                 self.box_3v_preset.set_tooltip_text(Tips.preset_tooltip_str)
  1406.                 self.f_3vcodec['grid'].attach(self.box_3v_preset, 0, 1, 1, 1)
  1407.                 self.box_3v_preset.connect("changed", self.on_preset_changed)
  1408.                 # x264 tune
  1409.                 self.box_3v_tune = self.make_comboboxtext(VcodecOther.x264_tune) # film,animation,grain,stillimage
  1410.                 self.box_3v_tune.set_tooltip_text(Tips.tune_tooltip_str)
  1411.                 self.f_3vcodec['grid'].attach(self.box_3v_tune, 1, 1, 1, 1)
  1412.                 self.box_3v_tune.connect("changed", self.on_preset_changed)
  1413.                 # x264 opts
  1414.                 self.box_3v_x264opts = self.make_comboboxtext2(VcodecOptions.OPTx264)
  1415.                 self.box_3v_x264opts.set_tooltip_text(Tips.opt_tooltip_str)
  1416.                 self.box_3v_x264opts.set_size_request(180,-1)
  1417.                 self.f_3vcodec['grid'].attach(self.box_3v_x264opts, 2, 1, 1, 1)
  1418.                 self.box_3v_x264opts.connect("changed", self.on_codec_clicked)
  1419.                 #opts custom
  1420.                 self.entry_optscustom = Gtk.Entry()
  1421.                 self.entry_optscustom.set_max_length(250)
  1422.                 #self.entry_optscustom.set_tooltip_text(Tips.x265_optscustom_str)
  1423.                 self.entry_optscustom.set_text("")
  1424.                 self.entry_optscustom.connect("activate", self.on_codec_clicked)
  1425.                 self.f_3vcodec['grid'].attach(self.entry_optscustom, 3, 1, 3, 1)
  1426.                 #
  1427.                 self.entry_optscustom_clear_button = Gtk.Button('<- Clear')
  1428.                 self.entry_optscustom_clear_button.connect("clicked", self.on_entry_optscustom_clear_button)
  1429.                 self.f_3vcodec['grid'].attach(self.entry_optscustom_clear_button, 6, 1, 3, 1)
  1430.  
  1431.         def make_other_opts(self):
  1432.                 #
  1433.                 self.f3_oth = self.make_frame_ag(3, "  other options  " , 6, 8, 8, True)
  1434.                 #
  1435.                 self.check_2pass = Gtk.CheckButton("2 pass")
  1436.                 self.check_2pass.connect("toggled", self.on_f3_other_clicked)
  1437.                 self.f3_oth['grid'].attach(self.check_2pass, 0, 0, 1, 1)
  1438.                 self.check_2pass.set_sensitive(False)
  1439.                 #
  1440.                 self.check_nometa = Gtk.CheckButton("no metatag")
  1441.                 self.check_nometa.set_active(True)
  1442.                 self.check_nometa.connect("toggled", self.on_f3_other_clicked)
  1443.                 self.check_nometa.set_tooltip_text(Tips.nometa_tooltip_srt)
  1444.                 self.f3_oth['grid'].attach(self.check_nometa, 1, 0, 1, 1)
  1445.                 #
  1446.                 #
  1447.                 self.check_scopy = Gtk.CheckButton("sub copy")
  1448.                 self.check_scopy.connect("toggled", self.on_f3_other_clicked)
  1449.                 self.check_scopy.set_tooltip_text(Tips.subcopy_tooltip_srt)
  1450.                 self.f3_oth['grid'].attach(self.check_scopy, 2, 0, 1, 1)
  1451.                 #
  1452.                 self.check_debug = Gtk.CheckButton("debug")
  1453.                 self.check_debug.connect("toggled", self.on_f3_other_clicked)
  1454.                 self.check_debug.set_tooltip_text(Tips.debug_tooltip_srt)
  1455.                 self.f3_oth['grid'].attach(self.check_debug, 4, 0, 1, 1)
  1456.                 #
  1457.                 self.box_oth_container = self.make_comboboxtext2(VcodecOther.OutContainers)
  1458.                 self.box_oth_container.set_active(VcodecOther.OutContainers_default)
  1459.                 self.box_oth_container.set_tooltip_text(Tips.container_tooltip_srt)
  1460.                 self.f3_oth['grid'].attach(self.box_oth_container, 5, 0, 1, 1)
  1461.                 self.box_oth_container.connect("changed", self.on_container_changed)
  1462.  
  1463.         def make_run_ffmpeg(self):
  1464.                 self.f3_run = self.make_frame_ag(3, "  execute in terminal  " , 6, 8, 8, True)
  1465.                 #
  1466.                 self.f3_run_indir_label = Gtk.Label("")
  1467.                 self.f3_run_indir_label.set_margin_left(6)
  1468.                 self.f3_run_indir_label.set_halign(1) # 1 left 2 right 3 center
  1469.                 self.f3_run_indir_label.set_ellipsize(2) # need for set_max_width_chars: 1 start 2 middle 3 end
  1470.                 self.f3_run_indir_label.set_max_width_chars(30)
  1471.                 self.f3_run['grid'].attach(self.f3_run_indir_label, 0, 0, 1, 1)
  1472.                 #
  1473.                 self.f3_run_file = Gtk.Label("no input file")
  1474.                 self.f3_run_file.set_margin_left(6)
  1475.                 self.f3_run_file.set_halign(3) # 1 left 2 right 3 center
  1476.                 self.f3_run_file.set_ellipsize(2) # need for set_max_width_chars: 1 start 2 middle 3 end
  1477.                 self.f3_run_file.set_max_width_chars(42)
  1478.                 self.f3_run_file.set_tooltip_text('')
  1479.                 self.f3_run['grid'].attach(self.f3_run_file, 1, 0, 2, 1)
  1480.                 self.f3_dur_file = Gtk.Label("")
  1481.                 self.f3_run['grid'].attach(self.f3_dur_file, 3, 0, 1, 1)
  1482.                 #
  1483.                 self.but_f3_run = Gtk.Button(label="ENCODE")
  1484.                 self.but_f3_run.connect("clicked", self.on_but_f3_run_clicked)
  1485.                 self.but_f3_run.set_sensitive(False)
  1486.                 self.f3_run['grid'].attach(self.but_f3_run, 3, 1, 1, 1)
  1487.                 #
  1488.                 self.f3_run_outdir_label = Gtk.Label("")
  1489.                 self.f3_run_outdir_label.set_margin_left(6)
  1490.                 self.f3_run_outdir_label.set_halign(1)
  1491.                 self.f3_run_outdir_label.set_ellipsize(2) # need for set_max_width_chars: 1 start 2 middle 3 end
  1492.                 self.f3_run_outdir_label.set_max_width_chars(54)
  1493.                 self.f3_run_outdir_label.set_markup("<b>out dir:  </b>" + os.getcwd())
  1494.                 self.f3_run['grid'].attach(self.f3_run_outdir_label, 0, 1, 2, 1)
  1495.                 #
  1496.                 # filechooserbutton
  1497.                 self.but_folder = Gtk.Button("Choose out dir")
  1498.                 self.but_folder.set_tooltip_text(Tips.out_dir_tooltip_str)
  1499.                 self.but_folder.connect("clicked", self.on_folder_clicked)
  1500.                 self.f3_run['grid'].attach(self.but_folder, 2, 1, 1, 1)
  1501.                 #
  1502.                 self.reportdata = Gtk.Label('')
  1503.                 self.f3_run['grid'].attach(self.reportdata, 0, 3, 4, 1)
  1504.  
  1505.         # event handlers -----------------------------------------------
  1506.  
  1507.         def on_window_destroy(self, *args):
  1508.                 Gtk.main_quit(*args)
  1509.  
  1510.         def on_map_clicked(self, button):
  1511.                 self.map_label.set_label("")
  1512.                 Vars.maps_str = ""
  1513.                 if self.check_map.get_active():
  1514.                         map_in = self.entry_map.get_chars(0, -1)
  1515.                         if map_in != "":
  1516.                                 map_l = map_in.split(",")
  1517.                                 for i in range(len(map_l)):
  1518.                                         if map_l[i] in Vars.maps_ch:
  1519.                                                 if Vars.maps_str != "":
  1520.                                                         Vars.maps_str += " "
  1521.                                                 Vars.maps_str += "-map " + map_l[i]
  1522.                                 self.map_label.set_label(Vars.maps_str)
  1523.                 self.outfilter()
  1524.                 self.make_p3_out_command()
  1525.  
  1526.         def on_time_clicked(self, button):
  1527.                 Vars.time_final_str = ""
  1528.                 Vars.time_start = 0
  1529.                 if self.check_time.get_active():
  1530.                         timein = 0
  1531.                         timeout = 0
  1532.                         timedur = 0
  1533.                         timein_ent = self.entry_timein.get_chars(0, -1)
  1534.                         if timein_ent != "":
  1535.                                 if self.is_number(timein_ent):
  1536.                                         timein = float(timein_ent.split('.')[0])
  1537.                                         if len(timein_ent.split('.')) == 2:
  1538.                                                 decimal = timein_ent.split('.')[1][:3]
  1539.                                                 decimal = float('0.' + decimal)
  1540.                                                 timein += decimal
  1541.                                         if Vars.duration_in_sec != 0:
  1542.                                                 if timein > Vars.duration_in_sec:
  1543.                                                         self.entry_timein.set_text(str(Vars.duration_in_sec -1))
  1544.                                                         return
  1545.                                 else:  
  1546.                                         timein = float(self.hms2sec(timein_ent.split('.')[0]))
  1547.                                         if len(timein_ent.split('.')) == 2:
  1548.                                                 decimal = timein_ent.split('.')[1][:3]
  1549.                                                 decimal = float('0.' + decimal)
  1550.                                                 timein += decimal
  1551.                                         if Vars.duration_in_sec != 0:
  1552.                                                 if timein > Vars.duration_in_sec:
  1553.                                                         self.entry_timein.set_text(str(self.sec2hms(Vars.duration_in_sec -1)))
  1554.                                                         return
  1555.                         timeout_ent = self.entry_timeout.get_chars(0, -1)
  1556.                         if timeout_ent != "":
  1557.                                 if self.is_number(timeout_ent):
  1558.                                         timeout = float(timeout_ent.split('.')[0])
  1559.                                         if len(timeout_ent.split('.')) == 2:
  1560.                                                 decimal = timeout_ent.split('.')[1][:3]
  1561.                                                 decimal = float('0.' + decimal)
  1562.                                                 timeout += decimal
  1563.                                         if Vars.duration_in_sec != 0:
  1564.                                                 if timeout > Vars.duration_in_sec:
  1565.                                                         self.entry_timeout.set_text(str(Vars.duration_in_sec))
  1566.                                                         return
  1567.                                                 if timeout == Vars.duration_in_sec:
  1568.                                                         timeout = 0
  1569.                                         timedur = timeout - timein
  1570.                                 else:  
  1571.                                         timeout = float(self.hms2sec(timeout_ent.split('.')[0]))
  1572.                                         if len(timeout_ent.split('.')) == 2:
  1573.                                                 decimal = timeout_ent.split('.')[1][:3]
  1574.                                                 decimal = float('0.' + decimal)
  1575.                                                 timeout += decimal
  1576.                                         if Vars.duration_in_sec != 0:
  1577.                                                 if timeout > Vars.duration_in_sec:
  1578.                                                         self.entry_timeout.set_text(Vars.duration)
  1579.                                                         return
  1580.                                                 if timeout == Vars.duration_in_sec:
  1581.                                                         timeout = 0
  1582.                                         timedur = timeout - timein
  1583.                         if timein != 0:
  1584.                                 Vars.time_final_str += " -ss " + str(timein)
  1585.                                 Vars.time_start = timein
  1586.                         if timedur > 0:
  1587.                                 Vars.time_final_str += " -t " + str(timedur)
  1588.                 self.time_label.set_text(Vars.time_final_str)
  1589.                 self.outfilter()
  1590.                 self.make_p3_out_command()
  1591.  
  1592.         def on_deint_clicked(self, button):
  1593.                 Vars.deint_str = ""
  1594.                 if self.checkdeint.get_active():
  1595.                         deint_val = self.box_deint['cbox'].get_active()
  1596.                         if deint_val == 0:
  1597.                                 Vars.deint_str = "yadif"
  1598.                         elif deint_val == 1:
  1599.                                 Vars.deint_str = "pp=lb"
  1600.                         elif deint_val == 2:
  1601.                                 Vars.deint_str = "idet"
  1602.                 self.outfilter()
  1603.  
  1604.         def on_scale_clicked(self, button):
  1605.                 customscale_in = ""
  1606.                 customscale_in = self.entry_scalecustom.get_chars(0, -1)
  1607.                 if customscale_in != "":
  1608.                         self.entry_scalecustom_clean_button.set_sensitive(True)
  1609.                         Vars.scalestr = customscale_in
  1610.                         self.outfilter()
  1611.                 elif self.box_scale_side['cbox'].get_active() != 0:
  1612.                         self.entry_scalecustom_clean_button.set_sensitive(False)
  1613.                         self.scale_calc()
  1614.                 else:
  1615.                         self.entry_scalecustom_clean_button.set_sensitive(False)
  1616.                         Vars.scalestr = ""
  1617.                         self.outfilter()
  1618.  
  1619.         def on_entry_scalecustom_clean_button(self, button):
  1620.                 self.entry_scalecustom.set_text('')
  1621.                 self.on_scale_clicked(0)
  1622.  
  1623.         def on_dn_clicked(self, button):
  1624.                 Vars.dn_str = ""
  1625.                 if self.checkdn.get_active():
  1626.                         dn_val = int(self.spindn['adj'].get_value())
  1627.                         Vars.dn_str = "hqdn3d=" + str(dn_val)
  1628.                 self.outfilter()
  1629.  
  1630.         def on_uns_clicked(self, button):
  1631.                 Vars.uns_str = ""
  1632.                 if self.checkuns.get_active():
  1633.                         luma = self.spinunsl['adj'].get_value()
  1634.                         chroma = self.spinunsc['adj'].get_value()
  1635.                         Vars.uns_str = "unsharp=5:5:" + "{0:0.2f}".format(luma) + ":5:5:" + "{0:0.2f}".format(chroma)
  1636.                 self.outfilter()
  1637.  
  1638.         def on_fr_clicked(self, button):
  1639.                 Vars.fr_str = ""
  1640.                 if self.checkfr.get_active():
  1641.                         fr_val = self.spinfr['adj'].get_value()
  1642.                         Vars.fr_str = "-r " + "{0:0.2f}".format(fr_val)
  1643.                 self.outfilter()
  1644.  
  1645.         def on_crop_clicked(self, button):
  1646.                 ok = 0
  1647.                 Vars.crop_str = ""
  1648.                 if self.checkcr.get_active():
  1649.                         ok = 1
  1650.                 if ok:
  1651.                         inW = int(self.spincw['adj'].get_value())
  1652.                         inH = int(self.spinch['adj'].get_value())
  1653.                         crT = int(self.spinct['adj'].get_value())
  1654.                         crB = int(self.spincb['adj'].get_value())
  1655.                         crL = int(self.spincl['adj'].get_value())
  1656.                         crR = int(self.spincr['adj'].get_value())      
  1657.                         finW = inW - crL - crR
  1658.                         finH = inH - crT - crB
  1659.                         if ( (finW < 100) or (finH < 100) ):
  1660.                                 Vars.crop_str = ""
  1661.                         else:
  1662.                                 Vars.crop_str = "crop=" + str(finW) + ":" \
  1663.                                  + str(finH) + ":" \
  1664.                                  + str(crL)  + ":" \
  1665.                                  + str(crT)
  1666.                 if self.box_scale_ar['cbox'].get_active() != 2:
  1667.                         self.outfilter()
  1668.                 else:
  1669.                         self.on_scale_clicked(button)
  1670.  
  1671.         def on_but_file(self,button):
  1672.                 if Vars.ENCODING:
  1673.                                 return
  1674.                 dialog = Gtk.FileChooserDialog("Please choose a file", self.window,
  1675.                 Gtk.FileChooserAction.OPEN,
  1676.                 ("_Cancel", Gtk.ResponseType.CANCEL,
  1677.                 "_Open", Gtk.ResponseType.OK))
  1678.                 #
  1679.                 filter = Gtk.FileFilter()
  1680.                 filter.set_name("Video")
  1681.                 filter.add_mime_type("video/x-matroska")
  1682.                 filter.add_mime_type("video/mp4")
  1683.                 filter.add_mime_type("video/x-flv")
  1684.                 filter.add_mime_type("video/avi")
  1685.                 filter.add_mime_type("video/mpg")
  1686.                 filter.add_mime_type("video/mpeg")
  1687.                 filter.add_mime_type("video/x-ms-wmv")
  1688.                 filter.add_mime_type("video/webm")
  1689.                 filter.add_mime_type("video/ogg")
  1690.                 filter.add_mime_type("video/quicktime")
  1691.                 dialog.add_filter(filter)
  1692.                 #
  1693.                 dialog.set_current_folder(Vars.indir)
  1694.                 response = dialog.run()
  1695.                 if response == Gtk.ResponseType.OK:
  1696.                         Vars.filename = dialog.get_filename()
  1697.                         self.file_changed()
  1698.                 dialog.destroy()
  1699.  
  1700.         def file_changed(self):
  1701.                
  1702.                 #def reduce_string(the_string, left_part, right_part):
  1703.                         #a = the_string[:left_part]
  1704.                         #b = '...'
  1705.                         #c = the_string[-right_part:]
  1706.                         #rlabel = a + b + c
  1707.                         #return rlabel
  1708.                
  1709.                 self.butplay.set_sensitive(True) # low part ---------
  1710.                 self.butprobe.set_sensitive(True)
  1711.                 self.preview_logic() # test and testsplit
  1712.                 self.check_time.set_active(False)
  1713.                 self.butcrode.set_sensitive(True) # crop ----------
  1714.                 self.spinct['adj'].set_value(0)
  1715.                 self.spincb['adj'].set_value(0)
  1716.                 self.spincl['adj'].set_value(0)
  1717.                 self.spincr['adj'].set_value(0)                
  1718.                 self.but_volume_det.set_sensitive(True) # volume detect
  1719.                 Vars.VOLDT_DONE = False
  1720.                 #self.but_volume_det.set_label("Volume detect")
  1721.                 self.label_meanvol.set_label("")
  1722.                 self.label_maxvol.set_label("")
  1723.                 self.check_vol.set_active(False) #volume
  1724.                 self.spin_db["adj"].set_value(0)
  1725.                 # framesdet
  1726.                 Vars.FRAMDT_DONE = False
  1727.                 self.but_frames_det.set_sensitive(True)
  1728.                 self.label_framesdet.set_label("N/A")
  1729.                 self.label_time2frame.set_label('')
  1730.                 #
  1731.                 self.check_drc.set_active(False) #drc
  1732.                 self.check_drc.set_sensitive(False)
  1733.                 self.spin_drc["adj"].set_value(1)
  1734.                 self.spin_drc["spinner"].set_sensitive(False)
  1735.                 Vars.ac3_drc = ""
  1736.                 self.compand_test.set_sensitive(True) #compand test
  1737.                 self.compand_volume.set_sensitive(True)
  1738.                 if self.check_compand.get_active():
  1739.                         self.check_compand.set_active(False)
  1740.                 self.dynaudnorm_test.set_sensitive(True) #dynaudnorm test
  1741.                 self.dynaudnorm_volume.set_sensitive(True)
  1742.                 if self.check_dynaudnorm.get_active():
  1743.                         self.check_dynaudnorm.set_active(False)
  1744.                 self.but_black_det.set_sensitive(True) # black  detect
  1745.                 self.but_black_det.set_label("Black detect")
  1746.                 self.textbuffer.set_text(Tips.black_dt_init_str)
  1747.                 self.progressbar_black_det.set_fraction(0.0)
  1748.                 self.check_prologic.set_sensitive(False) #check_prologic
  1749.                 self.check_prologic.set_active(False)
  1750.                 self.but_f3_run.set_sensitive(True) # ffmpeg run
  1751.                 Vars.BLACKDT_DONE = False
  1752.                 Vars.have_subs = False # subs
  1753.                 self.check_map.set_active(False) # map
  1754.                 #
  1755.                 command = "clear" + "\n"
  1756.                 length = len(command)
  1757.                 self.terminal.feed_child(command, length)
  1758.                 Vars.dirname = os.path.dirname(Vars.filename)
  1759.                 Vars.basename = os.path.basename(Vars.filename)
  1760.                 Vars.indir = os.path.dirname(Vars.filename)
  1761.                 #out same as in
  1762.                 Vars.outdir = Vars.indir
  1763.                 command = "cd " + "\"" + Vars.outdir + "\"" + "\n"
  1764.                 length = len(command)
  1765.                 self.terminal.feed_child(command, length)
  1766.                 # label outdir
  1767.                 self.f3_run_outdir_label.set_markup("<b>out dir:  </b>" + Vars.outdir)
  1768.                 #
  1769.                 self.check_out_file()
  1770.                 # label indir
  1771.                 self.f3_run_indir_label.set_label(Vars.dirname)
  1772.                 self.f3_run_indir_label.set_tooltip_text(Vars.dirname)
  1773.                 # label filename
  1774.                 self.f3_run_file.set_label(Vars.basename)
  1775.                 # label button openfile
  1776.                 if len(Vars.basename) > 36:
  1777.                         self.but_file.set_label(Vars.basename[0:33] + '...')
  1778.                 else:
  1779.                         self.but_file.set_label(Vars.basename)
  1780.                 #
  1781.                 self.but_f3_run.set_tooltip_text("")
  1782.                 self.reportdata.set_text('')
  1783.                 command = [Vars.ffprobe_ex, '-show_format', '-show_streams', '-pretty', '-loglevel', 'quiet', Vars.filename]
  1784.                 p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  1785.                 out, err =  p.communicate()
  1786.                 out = out.decode() # python3
  1787.                 self.get_info(out)
  1788.  
  1789.         def get_info(self, out):
  1790.                
  1791.                 def form_to_3(in_str):
  1792.                         '''
  1793.                        bitrate and size info formatting
  1794.                        '''
  1795.                         a = in_str.split(' ')[0]
  1796.                        
  1797.                         if len(in_str.split(' ')) == 2:
  1798.                                 b = in_str.split(' ')[1]
  1799.                                 a = float(a)
  1800.                                 result = "{0:.3f}".format(a ) + " " + b
  1801.                         else:
  1802.                                 result = 'N/A'
  1803.                         return result
  1804.  
  1805.                 def set_w_h_video_scale():
  1806.                         self.spincw['adj'].set_value(float(Vars.video_width)) #mettere decimali se no non si vede
  1807.                         self.spincw['spinner'].set_sensitive(False)
  1808.                         self.spinch['adj'].set_value(float(Vars.video_height)) #mettere decimali se no non si vede
  1809.                         self.spinch['spinner'].set_sensitive(False)
  1810.                         if Vars.add_1_1_dar:
  1811.                                 self.box_scale_ar['list'].append(["as input"])
  1812.                         Vars.add_1_1_dar = False        
  1813.                
  1814.                 def set_dar_in(info):
  1815.                         try:
  1816.                                 darw = info.split(':')[0]
  1817.                                 darh = info.split(':')[1]
  1818.                                 darw = int(darw)
  1819.                                 darh = int(darh)
  1820.                                 if darh > 0 and darw > 0:
  1821.                                         darin = float(darw)/darh
  1822.                                         Vars.darin = "{0:.3f}".format(darin)
  1823.                                 else:
  1824.                                         darin = float(Vars.video_width)/float(Vars.video_height)
  1825.                                         Vars.darin = "{0:.3f}".format(darin)
  1826.                         except:
  1827.                                 darin = float(Vars.video_width)/float(Vars.video_height)
  1828.                                 Vars.darin = "{0:.3f}".format(darin)
  1829.                
  1830.                 def maps_choises(num_streams):
  1831.                         maps = []
  1832.                         for i in range(0,num_streams):
  1833.                                 m = '0:' + str(i)
  1834.                                 maps.append(m)
  1835.                         Vars.maps_ch = maps
  1836.                
  1837.                 #x Vars.info_str
  1838.                 Vars.info_str = ""
  1839.                 is_stream = 0
  1840.                 is_format = 0
  1841.                 is_video = 0
  1842.                 for line in out.split('\n'):
  1843.                         line = line.strip()
  1844.                         if line.startswith('[STREAM]'):
  1845.                                 Vars.info_str += "STREAM "
  1846.                                 is_stream = 1
  1847.                         elif line.startswith('[/STREAM]'):
  1848.                                 Vars.info_str += "\n"
  1849.                                 is_stream = 0
  1850.                         elif line.startswith('index=') and is_stream == 1:
  1851.                                 s = line
  1852.                                 info = s.split('=')[1]  
  1853.                                 Vars.info_str += info + ": "
  1854.                         elif line.startswith('codec_name=') and is_stream == 1:
  1855.                                 s = line
  1856.                                 info = s.split('=')[1]
  1857.                                 if info == 'ac3':
  1858.                                         self.check_drc.set_sensitive(True)
  1859.                                         self.spin_drc["spinner"].set_sensitive(True)
  1860.                                 Vars.info_str += info + "  "
  1861.                         elif line.startswith('profile=') and is_stream == 1:
  1862.                                 s = line
  1863.                                 info = s.split('=')[1]  
  1864.                                 Vars.info_str = Vars.info_str + "profile=" +info + "  "
  1865.                         elif line.startswith('codec_type=') and is_stream == 1:
  1866.                                 s = line
  1867.                                 info = s.split('=')[1]
  1868.                                 if info == 'video':
  1869.                                         is_video = 1
  1870.                                 else:
  1871.                                         is_video = 0
  1872.                                 Vars.info_str += info + "  "
  1873.                                 # auto -c:s copy if subtitles streams
  1874.                                 if info == 'subtitle':
  1875.                                         Vars.have_subs = True
  1876.                                 self.on_container_changed(0)
  1877.                         elif line.startswith('width=') and is_stream == 1:
  1878.                                 s = line
  1879.                                 info = s.split('=')[1]
  1880.                                 if is_video:
  1881.                                         Vars.video_width = info
  1882.                                         Vars.info_str += info + "x"
  1883.                         elif line.startswith('height=') and is_stream == 1:
  1884.                                 s = line
  1885.                                 info = s.split('=')[1]
  1886.                                 if is_video:
  1887.                                         Vars.video_height = info
  1888.                                         Vars.info_str += info + "  "
  1889.                         elif line.startswith('sample_aspect_ratio=') and is_stream == 1:
  1890.                                 s = line
  1891.                                 if is_video:
  1892.                                         info = s.split('=')[1]  
  1893.                                         Vars.info_str += "SAR=" + info + "  "
  1894.                         elif line.startswith('display_aspect_ratio=') and is_stream == 1:
  1895.                                 s = line
  1896.                                 if is_video:
  1897.                                         info = s.split('=')[1]  
  1898.                                         Vars.info_str += "DAR=" + info + "  "
  1899.                                         set_dar_in(info)
  1900.                         elif line.startswith('pix_fmt=') and is_stream == 1:
  1901.                                 s = line
  1902.                                 if is_video:
  1903.                                         info = s.split('=')[1]  
  1904.                                         Vars.info_str += info + "  "
  1905.                         elif line.startswith('sample_rate=') and is_stream == 1:
  1906.                                 s = line
  1907.                                 info = s.split('=')[1]
  1908.                                 info = form_to_3(info)
  1909.                                 Vars.audio_srate_in = info
  1910.                                 Vars.info_str += "samplerate=" + info + "  "
  1911.                                 if Vars.audio_srate_in == '44.100 KHz':
  1912.                                         self.box_audio_rate.set_active(1)
  1913.                                 else:
  1914.                                         self.box_audio_rate.set_active(0)
  1915.                                 self.on_audio_clicked(1)
  1916.                         elif line.startswith('channels=') and is_stream == 1:
  1917.                                 s = line
  1918.                                 info = s.split('=')[1]
  1919.                                 Vars.audio_channels = int(info)
  1920.                                 Vars.info_str += "channels=" + info + "  "
  1921.                                 if Vars.audio_channels == 6:
  1922.                                         self.check_prologic.set_sensitive(True)
  1923.                                         self.check_prologic.set_active(True)
  1924.                         elif line.startswith('r_frame_rate=') and is_stream == 1:
  1925.                                 if is_video:
  1926.                                         s = line
  1927.                                         info = s.split('=')[1]
  1928.                                         a = info.split('/')[0]
  1929.                                         b = info.split('/')[1]
  1930.                                         a = float(a)
  1931.                                         b = float(b)
  1932.                                         if (a > 0) and (b > 0):
  1933.                                                 c = float(a)/float(b)
  1934.                                                 Vars.framerate = c
  1935.                                                 info = "{0:0.2f}".format(c)
  1936.                                                 self.spinfr["adj"].set_value(c)
  1937.                                                 Vars.info_str += info + " fps  "
  1938.                         elif line.startswith('bit_rate=') and is_stream == 1:
  1939.                                 s = line
  1940.                                 info = s.split('=')[1]
  1941.                                 info = form_to_3(info)
  1942.                                 Vars.info_str += "bitrate=" + info + "  "
  1943.                         elif line.startswith('nb_frames=') and is_stream == 1:
  1944.                                 s = line
  1945.                                 info = s.split('=')[1]
  1946.                                 if is_video:
  1947.                                         if self.is_number(info):
  1948.                                                 self.label_framesdet.set_label(info)
  1949.                         elif line.startswith('TAG:NUMBER_OF_FRAMES=') and is_stream == 1:
  1950.                                 s = line
  1951.                                 info = s.split('=')[1]
  1952.                                 if is_video:
  1953.                                         if self.is_number(info):
  1954.                                                 self.label_framesdet.set_label(info)
  1955.                         elif line.startswith('TAG:language=') and is_stream == 1:
  1956.                                 s = line
  1957.                                 info = s.split('=')[1]  
  1958.                                 Vars.info_str += "lang=" + info + "  "
  1959.                         elif line.startswith('[FORMAT]'):
  1960.                                 Vars.info_str = Vars.info_str + "FORMAT "
  1961.                                 is_format = 1
  1962.                         elif line.startswith('[/FORMAT]'):
  1963.                                 is_format = 0
  1964.                         elif line.startswith('nb_streams=') and is_format == 1:
  1965.                                 s = line
  1966.                                 info = s.split('=')[1]
  1967.                                 Vars.info_str += "streams=" + info + "  "
  1968.                                 # possible map [tuple] Vars.maps_ch
  1969.                                 maps_choises(int(info))
  1970.                         elif line.startswith('duration=') and is_format == 1:
  1971.                                 s = line
  1972.                                 infoor = s.split('=')[1]        
  1973.                                 info = infoor.split('.')[0]
  1974.                                 Vars.duration_in_sec = self.hms2sec(info)
  1975.                                 Vars.duration = info
  1976.                                 if len (infoor.split('.')) == 2:
  1977.                                         decimal = infoor.split('.')[1][:3]
  1978.                                         info += '.' + decimal
  1979.                                         Vars.duration = info
  1980.                                         decimal = float('0.' + decimal)
  1981.                                         Vars.duration_in_sec += decimal
  1982.                                 self.entry_timein.set_text('0')
  1983.                                 self.entry_timeout.set_text(info)
  1984.                                 Vars.info_str += "duration=" + info + "  "
  1985.                         elif line.startswith('size=') and is_format == 1:
  1986.                                 s = line
  1987.                                 info = s.split('=')[1]
  1988.                                 info = form_to_3(info)
  1989.                                 Vars.info_str += "size=" + info + "  "
  1990.                         elif line.startswith('bit_rate=') and is_format == 1:
  1991.                                 s = line
  1992.                                 info = s.split('=')[1]
  1993.                                 info = form_to_3(info)
  1994.                                 Vars.info_str += "bitrate=" + info
  1995.                                
  1996.                 set_w_h_video_scale()
  1997.                 self.f3_dur_file.set_label(Vars.duration)
  1998.                 self.textbuffer_info.set_text(Vars.info_str)
  1999.                 self.f3_run_file.set_tooltip_text(Vars.info_str)
  2000.                 self.check_map.set_tooltip_text(Vars.info_str)
  2001.                 self.check_time.set_tooltip_text(Vars.info_str)
  2002.                 Vars.in_file_size = self.humansize(Vars.filename)
  2003.  
  2004.         def on_butplay_clicked(self, button):
  2005.                 if Vars.ENCODING:
  2006.                         return
  2007.                 command = Vars.ffplay_ex + " -hide_banner" + " \"" + Vars.filename + "\""\
  2008.                         + " -window_title \"FFplay input file\"" +"\n"
  2009.                 length = len(command)
  2010.                 self.terminal.feed_child(command, length)
  2011.  
  2012.         def on_butprobe_clicked(self, button):
  2013.                 if Vars.ENCODING:
  2014.                         return
  2015.                 command = Vars.ffprobe_ex + " \"" + Vars.filename + "\""  + " 2>&1 | grep 'Input\|Duration\|Stream'" + "\n"
  2016.                 length = len(command)
  2017.                 self.terminal.feed_child(command, length)        
  2018.  
  2019.         def on_butcrode_clicked(self, button):
  2020.                 self.butcrode.set_sensitive(False)
  2021.                 if Vars.time_start == 0:
  2022.                         command = Vars.ffmpeg_ex + " -i " + "\"" + Vars.filename + "\"" + " -ss 60 -t 1 -vf cropdetect -f null - 2>&1 | awk \'/crop/ { print $NF }\' | tail -1"
  2023.                 else:
  2024.                         command = Vars.ffmpeg_ex + " -i " + "\"" + Vars.filename + "\"" + " -ss " + str(Vars.time_start) + " -t 1 -vf cropdetect -f null - 2>&1 | awk \'/crop/ { print $NF }\' | tail -1"
  2025.                 p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  2026.                 out, err =  p.communicate()
  2027.                 out = out.decode()
  2028.                 for line in out.split('\n'):
  2029.                         line = line.strip()
  2030.                         if "crop=" in line:  
  2031.                                 aa = line.split('crop=', 1)
  2032.                                 aaa = aa[1]
  2033.                                 listdata = aaa.split(':')
  2034.                                 w = listdata[0]
  2035.                                 h = listdata[1]
  2036.                                 offx = listdata[2]
  2037.                                 offy = listdata[3]
  2038.                                 ctop = int(offy)
  2039.                                 cbot = int(Vars.video_height) - int(offy) -int(h)
  2040.                                 cleft = int(offx)
  2041.                                 cright = int(Vars.video_width) - int(offx) -int(w)
  2042.                                 self.spinct['adj'].set_value(float(ctop))
  2043.                                 self.spincb['adj'].set_value(float(cbot))
  2044.                                 self.spincl['adj'].set_value(float(cleft))
  2045.                                 self.spincr['adj'].set_value(float(cright))  
  2046.                                 break
  2047.                 self.butcrode.set_sensitive(True)
  2048.  
  2049.         def on_buttest_clicked(self, button):
  2050.                 if Vars.ENCODING:
  2051.                         return
  2052.                 # -map preview: only with none -vf option  
  2053.                 if Vars.maps_str == "": # command in terminal
  2054.                         command = Vars.ffplay_ex + " -hide_banner" + " \"" + Vars.filename + "\" " \
  2055.                                 + " " + Vars.time_final_str + " " \
  2056.                                 + "-vf "  + Vars.filter_test_str\
  2057.                                 + " -window_title \"Test\"" + "\n"
  2058.                         length = len(command)
  2059.                         self.terminal.feed_child(command, length)
  2060.                 else: # command in subprocess, terminal no ideal for pipe
  2061.                         # clean terminal
  2062.                         command = "clear" + "\n"
  2063.                         length = len(command)
  2064.                         self.terminal.feed_child(command, length)
  2065.                         # subprocess
  2066.                         command = Vars.ffmpeg_ex + ' -hide_banner -nostats -loglevel 0 '\
  2067.                                 + " -i \"" + Vars.filename + "\" " \
  2068.                                 + Vars.maps_str  + " " + Vars.time_final_str + " "
  2069.                         if (Vars.filter_test_str != ""):
  2070.                                 command += " -vf "  + Vars.filter_test_str
  2071.                         command += " -c copy -f matroska - | ffplay"\
  2072.                                 + " -hide_banner -nostats -loglevel 0 " + "-"\
  2073.                                 + " -window_title \"Test maps\""
  2074.                         p = subprocess.Popen(command, shell=True)
  2075.  
  2076.         def on_buttestspl_clicked(self, button):
  2077.                 if Vars.ENCODING:
  2078.                         return
  2079.                 command = Vars.ffplay_ex + " -hide_banner" + " \"" + Vars.filename + "\" " \
  2080.                         + " " + Vars.time_final_str + " " \
  2081.                         + " -vf \"split[a][b]; [a]pad=iw:(ih*2)+4:color=888888 [src]; [b]" \
  2082.                         + Vars.filter_test_str + " [filt]; [src][filt]overlay=((main_w - w)/2):main_h/2\""\
  2083.                         + " -window_title \"Test split\"" + "\n"
  2084.                 length = len(command)
  2085.                 self.terminal.feed_child(command, length)
  2086.                
  2087.         def on_butt_vtecopy_clicked(self, widget):
  2088.                 self.terminal.select_all()
  2089.                 self.terminal.copy_clipboard()
  2090.                 try: # only vte2.9
  2091.                         self.terminal.select_none()
  2092.                 except:
  2093.                         return
  2094.  
  2095.         def on_but_volume_det_clicked(self, button):
  2096.                
  2097.                 def set_other_butt(boolean):
  2098.                         if Vars.FRAMDT_DONE != True:
  2099.                                 self.but_frames_det.set_sensitive(boolean)
  2100.                         if Vars.BLACKDT_DONE != True:
  2101.                                 self.but_black_det.set_sensitive(boolean)
  2102.  
  2103.                 def finish_voldet(meanv, maxv, max_vol_det):
  2104.                         self.voldet_spin.stop()
  2105.                         self.voldet_spin.set_sensitive(False)
  2106.                         self.but_volume_det.set_label("Volume detect")
  2107.                         set_other_butt(True)
  2108.                         self.label_meanvol.set_label(meanv)
  2109.                         self.label_maxvol.set_label(maxv)
  2110.                         max_vol_det = max_vol_det.split(' ')[1]
  2111.                         volgain = float(max_vol_det) + 0.9
  2112.                         if volgain < -0.75:
  2113.                                 volgain=abs(volgain)
  2114.                                 volgain=float(volgain)
  2115.                                 self.spin_db["adj"].set_value(volgain)
  2116.                
  2117.                 def my_thread_voldet():
  2118.                         command = [Vars.ffmpeg_ex, '-i', Vars.filename, '-vn', '-af', 'volumedetect', '-f', 'null', '/dev/null']
  2119.                         p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
  2120.                         GLib.idle_add(self.but_volume_det.set_label, "Wait")
  2121.                         GLib.idle_add(set_other_butt, False)
  2122.                         time.sleep(0.02)
  2123.                         while True:
  2124.                                 line = p.stderr.read()
  2125.                                 if not line:
  2126.                                         break
  2127.                                 out = line.decode()
  2128.                                 for line in out.split('\n'):
  2129.                                         line = line.strip()
  2130.                                         if "mean_volume:" in line:  
  2131.                                                 aa = line.split('mean_volume:', 1)
  2132.                                                 mea_vol_det = aa[1]
  2133.                                                 meanv = "Mean vol: " + mea_vol_det
  2134.                                         if "max_volume:" in line:  
  2135.                                                 aa = line.split('max_volume:', 1)
  2136.                                                 max_vol_det = aa[1]
  2137.                                                 maxv = "Max vol: " + max_vol_det
  2138.                         p.communicate()
  2139.                         GLib.idle_add(finish_voldet, meanv, maxv, max_vol_det)
  2140.                         time.sleep(0.1)
  2141.                
  2142.                 if Vars.VOLDT_DONE:
  2143.                         return
  2144.                 Vars.VOLDT_DONE = True
  2145.                 self.voldet_spin.set_sensitive(True)
  2146.                 self.voldet_spin.start()
  2147.                 thread=threading.Thread(target=my_thread_voldet)
  2148.                 thread.daemon = True
  2149.                 thread.start()
  2150.  
  2151.         def on_but_frames_det_clicked(self, button):
  2152.                        
  2153.                 def finish_framesdet(frames):
  2154.                         self.label_framesdet.set_label(frames)
  2155.                         self.framesdet_spin.stop()
  2156.                         self.framesdet_spin.set_sensitive(False)
  2157.                         self.but_frames_det.set_label("Total frames detect")
  2158.                         set_other_butt(True)
  2159.  
  2160.                 def set_other_butt(boolean):
  2161.                         if Vars.VOLDT_DONE != True:
  2162.                                 self.but_volume_det.set_sensitive(boolean)
  2163.                         if Vars.BLACKDT_DONE != True:
  2164.                                 self.but_black_det.set_sensitive(boolean)
  2165.  
  2166.                 def my_thread_framedet():
  2167.                         #ffprobe2 -show_packets  ac3-sd.mkv  2>/dev/null | grep video | wc -l
  2168.                         command = Vars.ffprobe_ex + " -show_packets  \"" + Vars.filename + "\" 2>/dev/null | grep video | wc -l"
  2169.                         p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
  2170.                         GLib.idle_add(self.but_frames_det.set_label, "Wait")
  2171.                         GLib.idle_add(set_other_butt, False)
  2172.                         time.sleep(0.02)
  2173.                         while True:
  2174.                                 line = p.stdout.read()
  2175.                                 if not line:
  2176.                                         break
  2177.                                 out = line.decode()
  2178.                                 for line in out.split('\n'):
  2179.                                         if line != "":
  2180.                                                 line = line.strip()
  2181.                                                 frames = line
  2182.                         p.communicate()
  2183.                         GLib.idle_add(finish_framesdet, frames)
  2184.                         time.sleep(0.3)
  2185.                
  2186.                 if Vars.FRAMDT_DONE:
  2187.                         return
  2188.                 Vars.FRAMDT_DONE = True
  2189.                 self.framesdet_spin.set_sensitive(True)
  2190.                 self.framesdet_spin.start()    
  2191.                 thread=threading.Thread(target=my_thread_framedet)
  2192.                 thread.daemon = True
  2193.                 thread.start()
  2194.  
  2195.         def on_time2frame_clicked(self, button):
  2196.                 timein_ent = self.entry_time2frame.get_chars(0, -1)
  2197.                 if timein_ent != "":                    
  2198.                         if self.is_number(timein_ent):
  2199.                                 timein = float(timein_ent.split('.')[0])
  2200.                                 if len(timein_ent.split('.')) == 2:
  2201.                                         decimal = timein_ent.split('.')[1][:3]
  2202.                                         decimal = float('0.' + decimal)
  2203.                                         timein += decimal
  2204.                                 if Vars.duration_in_sec != 0:
  2205.                                         if timein > Vars.duration_in_sec:
  2206.                                                 self.entry_timein.set_text(str(Vars.duration_in_sec -1))
  2207.                                                 return
  2208.                         else:  
  2209.                                 timein = float(self.hms2sec(timein_ent.split('.')[0]))
  2210.                                 if len(timein_ent.split('.')) == 2:
  2211.                                         decimal = timein_ent.split('.')[1][:3]
  2212.                                         decimal = float('0.' + decimal)
  2213.                                         timein += decimal
  2214.                                 if Vars.duration_in_sec != 0:
  2215.                                         if timein > Vars.duration_in_sec:
  2216.                                                 self.entry_timein.set_text(str(self.sec2hms(Vars.duration_in_sec -1)))
  2217.                                                 return
  2218.                         t2frames = int(round(float(timein)*Vars.framerate))
  2219.                         self.label_time2frame.set_label(str(t2frames))
  2220.  
  2221.         def on_volume_clicked(self, button):
  2222.                 ratio = 1
  2223.                 self.label_ratio_val.set_label("1")
  2224.                 Vars.final_af_str = ""
  2225.                 db = self.spin_db["adj"].get_value()
  2226.                 if db != 0.00:
  2227.                         ratio = pow(10, (db/20.0))
  2228.                         ratio = float("{0:.3f}".format(ratio))    
  2229.                         self.label_ratio_val.set_label(str(ratio))
  2230.                         if self.check_vol.get_active():
  2231.                                 Vars.final_af_str = "volume=" + str(ratio)
  2232.                         else:
  2233.                                 Vars.final_af_str = ""
  2234.                 self.make_p3_out_command()
  2235.  
  2236.         def on_drc_clicked(self, buttom):
  2237.                 Vars.ac3_drc = ""
  2238.                 if self.check_drc.get_active():
  2239.                         val = self.spin_drc["adj"].get_value()
  2240.                         Vars.ac3_drc = "-drc_scale " + str(int(val))
  2241.  
  2242.         def on_compand_reset(self, button):
  2243.                 self.entry_compand.set_text(Vars.compinit)
  2244.                 self.on_compand_clicked(button)
  2245.  
  2246.         def on_compand_clicked(self, button):
  2247.                 Vars.compand_data = ""
  2248.                 if self.check_compand.get_active():
  2249.                         if self.check_dynaudnorm.get_active():
  2250.                                 self.check_dynaudnorm.set_active(False)
  2251.                         compand_data = self.entry_compand.get_chars(0, -1)
  2252.                         if Vars.audio_channels == 6:
  2253.                                 Vars.compand_data = "aformat=channel_layouts=stereo,aresample=matrix_encoding=dplii,compand=" + compand_data
  2254.                         else:
  2255.                                 Vars.compand_data = "aformat=channel_layouts=stereo,compand=" + compand_data
  2256.                 self.make_p3_out_command()
  2257.  
  2258.         def on_compand_test(self, button):
  2259.                 if Vars.compand_data != "":
  2260.                         command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'amovie=" + Vars.filename + " :sp=" + str(Vars.time_start) + " , " + Vars.compand_data + "  ,ebur128=video=1:meter=18:peak=true [out0][out1]\'" + "\n"
  2261.                 else:
  2262.                         command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'amovie=" + Vars.filename + " :sp=" + str(Vars.time_start) + "  ,ebur128=video=1:meter=18:peak=true [out0][out1]\'" + "\n"
  2263.                 length = len(command)
  2264.                 self.terminal.feed_child(command, length)
  2265.  
  2266.         def on_compand_volume(self, button):
  2267.                 if Vars.compand_data != "":                    
  2268.                         command = \
  2269.                         Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'movie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[vid];"\
  2270.                         + "amovie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[aud];"\
  2271.                         + "[aud]asplit=[2][3];"\
  2272.                         + "[2]aformat=channel_layouts=stereo,showvolume=h=20:t=0[volin];"\
  2273.                         + "[3]" + Vars.compand_data + ",asplit[c2][out1];"\
  2274.                         + "[c2]showvolume=h=40[volout];"\
  2275.                         + "[vid][volin]overlay=6:6[int1];"\
  2276.                         + "[int1][volout]overlay=6:56,setdar=" + Vars.darin + "[out]\'"\
  2277.                         + " -window_title \"compand test, volume in,out\"" + "\n"
  2278.                 else:
  2279.                         command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'movie=" + Vars.filename + ":sp=" + str(Vars.time_start)\
  2280.                         + "[vid];amovie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[aud];"\
  2281.                         + "[aud]aformat=channel_layouts=stereo,"\
  2282.                         + "asplit[out1][2] ; [2]showvolume=h=60[3]; [vid][3]overlay=6:6,setdar=" + Vars.darin + "[out]\'"\
  2283.                         + " -window_title \"input volume\"" + "\n"
  2284.                 length = len(command)
  2285.                 self.terminal.feed_child(command, length)
  2286.  
  2287.         def on_dynaudnorm_reset(self, button):
  2288.                 self.entry_dynaudnorm.set_text(Vars.dynaudnorm)
  2289.                 self.on_dynaudnorm_clicked(button)
  2290.  
  2291.         def on_dynaudnorm_clicked(self, button):
  2292.                 Vars.dynaudnorm_data = ""
  2293.                 if self.check_dynaudnorm.get_active():
  2294.                         if self.check_compand.get_active():
  2295.                                 self.check_compand.set_active(False)
  2296.                         dynaudnorm_data = self.entry_dynaudnorm.get_chars(0, -1)
  2297.                         if Vars.audio_channels == 6:
  2298.                                 Vars.dynaudnorm_data = "aformat=channel_layouts=stereo,aresample=matrix_encoding=dplii,dynaudnorm=" + dynaudnorm_data
  2299.                         else:
  2300.                                 Vars.dynaudnorm_data = "aformat=channel_layouts=stereo,dynaudnorm=" + dynaudnorm_data
  2301.                 self.make_p3_out_command()
  2302.  
  2303.         def on_dynaudnorm_test(self, button):
  2304.                 if Vars.dynaudnorm_data != "":
  2305.                         command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'amovie=" + Vars.filename + " :sp=" + str(Vars.time_start) + " , " + Vars.dynaudnorm_data + "  ,ebur128=video=1:meter=18:peak=true [out0][out1]\'" + "\n"
  2306.                 else:
  2307.                         command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'amovie=" + Vars.filename + " :sp=" + str(Vars.time_start) + "  ,ebur128=video=1:meter=18:peak=true [out0][out1]\'" + "\n"
  2308.                 length = len(command)
  2309.                 self.terminal.feed_child(command, length)
  2310.  
  2311.         def on_dynaudnorm_volume(self, button):
  2312.                 if Vars.dynaudnorm_data != "":
  2313.                         command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'movie=" + Vars.filename + ":sp=" + str(Vars.time_start)\
  2314.                         + "[vid];amovie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[aud];"\
  2315.                         + "[aud]" + Vars.dynaudnorm_data \
  2316.                         + ", asplit[out1][2];"\
  2317.                         + "[2]showvolume=h=15:w=240:f=120:r=15:t=0,"\
  2318.                         + "drawgrid=width=15:height=30:thickness=2:color=white@0.2,crop=225:31:0:0[3];"\
  2319.                         + "[vid][3]overlay=6:6:format=yuv420,setdar=" + Vars.darin +"[out]\'"\
  2320.                         + " -window_title \"dynaudnorm test, volume out\"" + "\n"
  2321.                 else:
  2322.                         command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'movie=" + Vars.filename + ":sp=" + str(Vars.time_start)\
  2323.                         + "[vid];amovie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[aud];"\
  2324.                         + "[aud]aformat=channel_layouts=stereo,"\
  2325.                         + "asplit[out1][2] ; [2]showvolume=h=60[3]; [vid][3]overlay=6:6,setdar=" + Vars.darin +"[out]\'"\
  2326.                         + " -window_title \"input volume\"" + "\n"
  2327.                 length = len(command)
  2328.                 self.terminal.feed_child(command, length)
  2329.  
  2330.         def on_audio_clicked(self, button):
  2331.                 #audio
  2332.                 Vars.audio_codec_str = self.audio_codec()
  2333.                 self.make_p3_out_command()
  2334.  
  2335.         def on_codec_audio_changed(self, button):
  2336.                
  2337.                 def no_afterburn():
  2338.                         if self.check_afterb.get_sensitive():
  2339.                                 self.check_afterb.set_active(True)
  2340.                                 self.check_afterb.set_sensitive(False)
  2341.                
  2342.                 def yes_afterburn():
  2343.                         self.check_afterb.set_sensitive(True)
  2344.  
  2345.                 #prologic2
  2346.                 if Vars.audio_channels == 6 and self.box_audio_ch.get_active_text() == '2':
  2347.                         self.check_prologic.set_sensitive(True)
  2348.                 else:
  2349.                         self.check_prologic.set_sensitive(False)
  2350.                 #
  2351.                 selected_audio_codec = self.box_ac.get_active_text()
  2352.                
  2353.                 for i in range(0,len(AudioEncoder.AEall)):
  2354.                         if AudioEncoder.AEall[i].label == selected_audio_codec:
  2355.                                 Vars.XaCheck = AudioEncoder.AEall[i]
  2356.                                 #Vars.XaCheck now is the selected AEobject
  2357.                                 break
  2358.                
  2359.                 if Vars.acodec_is != Vars.XaCheck.codec:
  2360.                         self.box_audio_ch.set_sensitive(True)
  2361.                         self.box_audio_rate.set_sensitive(True)
  2362.                         #
  2363.                         if Vars.XaCheck.value:
  2364.                                 self.spin_ac['spinner'].set_sensitive(True)
  2365.                                 self.adj_change2(self.spin_ac['adj'], Vars.XaCheck.value)
  2366.                                 self.spin_ac['adj'].set_value(Vars.XaCheck.value[0])
  2367.                         else:
  2368.                                 self.spin_ac['spinner'].set_sensitive(False)
  2369.                         #
  2370.                         if Vars.XaCheck.toolt:
  2371.                                 self.spin_ac['spinner'].set_tooltip_text(Vars.XaCheck.toolt)
  2372.                         else:
  2373.                                 self.spin_ac['spinner'].set_tooltip_text('')
  2374.                         #
  2375.                         if Vars.XaCheck.afterbrn:
  2376.                                 yes_afterburn()
  2377.                         else:
  2378.                                 no_afterburn()
  2379.                         #
  2380.                         if Vars.XaCheck.no_audio_enc:
  2381.                                 self.box_audio_ch.set_sensitive(False)
  2382.                                 self.box_audio_rate.set_sensitive(False)
  2383.                                 self.check_prologic.set_sensitive(False)
  2384.                                 self.check_soxr.set_sensitive(False)
  2385.                         elif Vars.XaCheck.force_stereo: # aacplus
  2386.                                 self.box_audio_ch.set_sensitive(False)
  2387.                                 self.box_audio_ch.set_active(0)
  2388.                         #
  2389.                         Vars.acodec_is = Vars.XaCheck.codec
  2390.                 self.on_audio_clicked(button)  
  2391.  
  2392.         def audio_codec(self):
  2393.                 # channels
  2394.                 audio_codec_str = ""
  2395.                 channel_str = "-ac 2"
  2396.                 channel = self.box_audio_ch.get_active_text()
  2397.                 if channel == "1":
  2398.                         channel_str = "-ac 1"
  2399.                 # sample rate e soxr
  2400.                 sample_str = ""
  2401.                 sample = self.box_audio_rate.get_active_text()
  2402.                 if not(Vars.XaCheck.no_audio_enc):
  2403.                         if sample == "44100":
  2404.                                 out_s = '44.100 KHz'
  2405.                                 if out_s != Vars.audio_srate_in:
  2406.                                         sample_str = "-ar 44.1k"
  2407.                                         self.check_soxr.set_sensitive(True)
  2408.                                 else:
  2409.                                         self.check_soxr.set_sensitive(False)
  2410.                         elif sample == "48000":
  2411.                                 out_s = '48.000 KHz'
  2412.                                 if out_s != Vars.audio_srate_in:
  2413.                                         sample_str = "-ar 48k"
  2414.                                         self.check_soxr.set_sensitive(True)
  2415.                                 else:
  2416.                                         self.check_soxr.set_sensitive(False)
  2417.                 # acodec
  2418.                 def on_afterburner(ac_str):
  2419.                         if (self.check_afterb.get_active() == False):
  2420.                                 ac_str = ac_str + " -afterburner 0 "
  2421.                         return ac_str
  2422.                
  2423.                 audio_codec_str = Vars.XaCheck.comm_str
  2424.                 if not(Vars.XaCheck.no_audio_enc):
  2425.                         if Vars.XaCheck.value != None:
  2426.                                 input_par = self.spin_ac['adj'].get_value()
  2427.                                 audio_codec_str += str(int(input_par))
  2428.                         if Vars.XaCheck.kb:
  2429.                                 audio_codec_str += 'k '
  2430.                         else:
  2431.                                 audio_codec_str = audio_codec_str + ' '
  2432.                         audio_codec_str += sample_str + " " + channel_str
  2433.                         if Vars.XaCheck.afterbrn:
  2434.                                 audio_codec_str = on_afterburner(audio_codec_str)
  2435.                 return audio_codec_str
  2436.  
  2437.         def on_codec_video_changed(self, button):
  2438.                 self.on_codec_clicked(button)
  2439.  
  2440.         def on_preset_changed(self, button):
  2441.                 self.on_codec_clicked(button)
  2442.  
  2443.         def on_codec_clicked(self, button):
  2444.                 Vars.final_codec_str = ""
  2445.                 # video codec
  2446.                 selected_video_codec = self.box_vcodec.get_active_text()
  2447.                 for i in range(0,len(VideoEncoder.VEall)):
  2448.                         if VideoEncoder.VEall[i].label == selected_video_codec:
  2449.                                 Vars.XvCheck = VideoEncoder.VEall[i]
  2450.                                 #Vars.XvCheck now is the selected VEobject
  2451.                                 break
  2452.                 self.set_video_encoder()
  2453.                 Vars.video_codec_str_more = self.make_video_codec_str()
  2454.                 self.check_out_file()
  2455.                 self.on_codec_vrc_value_change(button)
  2456.  
  2457.         def on_codec_vrc_changed(self, button):
  2458.                 video_rc = self.box_vrc.get_active_text()
  2459.                 if not(Vars.XvCheck.no_video_enc):
  2460.                         if video_rc == VcodecOther.VRCcrf.label: # crf
  2461.                                 self.adj_change2(self.spin_vc['adj'], Vars.XvCheck.crf_val)
  2462.                                 self.spin_vc['adj'].set_value(Vars.XvCheck.crf_val[0])
  2463.                                 self.check_2pass.set_active(False)
  2464.                                 self.check_2pass.set_sensitive(False)
  2465.                         elif video_rc == VcodecOther.VRCbr.label: # bitrate
  2466.                                 self.adj_change2(self.spin_vc['adj'], Vars.XvCheck.br_val)
  2467.                                 self.spin_vc['adj'].set_value(Vars.XvCheck.br_val[0])
  2468.                                 if Vars.XvCheck.br2pass:
  2469.                                         self.check_2pass.set_sensitive(True)
  2470.                                 else:
  2471.                                         self.check_2pass.set_sensitive(False)
  2472.                         elif video_rc == VcodecOther.VRCq.label: # q-scale
  2473.                                 self.adj_change2(self.spin_vc['adj'], Vars.XvCheck.q_val)
  2474.                                 self.spin_vc['adj'].set_value(Vars.XvCheck.q_val[0])
  2475.                                 self.check_2pass.set_active(False)
  2476.                                 self.check_2pass.set_sensitive(False)
  2477.  
  2478.         def on_codec_vrc_value_change(self, button):
  2479.                 Vars.video_codec_str = ""
  2480.                 video_rc = self.box_vrc.get_active_text() #0 crf, 1 kb/s
  2481.                 if not(Vars.XvCheck.no_video_enc):
  2482.                         in_data = str(self.spin_vc['adj'].get_value())
  2483.                         if video_rc == VcodecOther.VRCcrf.label: #crf
  2484.                                 crf_comm = '-crf:v ' # default ffmpeg
  2485.                                 video_codec_str = Vars.XvCheck.comm_str + crf_comm + in_data + ' '
  2486.                         elif video_rc == VcodecOther.VRCbr.label: #bitrate
  2487.                                 in_data = str(int(self.spin_vc['adj'].get_value()))
  2488.                                 br_comm = '-b:v ' # default ffmpeg
  2489.                                 video_codec_str = Vars.XvCheck.comm_str + br_comm + in_data
  2490.                                 if Vars.XvCheck.kb:
  2491.                                         video_codec_str += 'k '
  2492.                                 else:
  2493.                                         video_codec_str += ' '
  2494.                         elif video_rc == VcodecOther.VRCq.label: #q scale
  2495.                                 q_comm = '-q:v '
  2496.                                 video_codec_str = Vars.XvCheck.comm_str + q_comm + in_data
  2497.                         video_codec_str += Vars.video_codec_str_more
  2498.                 else:
  2499.                         video_codec_str = Vars.video_codec_str_more
  2500.  
  2501.                 Vars.video_codec_str = video_codec_str
  2502.                 self.make_p3_out_command()
  2503.  
  2504.         def set_video_encoder(self):
  2505.                 if Vars.vcodec_is != Vars.XvCheck.codec:
  2506.                         Vars.vcodec_is = Vars.XvCheck.codec
  2507.                         # no video encoding
  2508.                         if Vars.XvCheck.no_video_enc:
  2509.                                 self.video_ui_widg_false_all()
  2510.                                 return
  2511.                         # set ui widgets
  2512.                         if Vars.XvCheck.is10bit:
  2513.                                 self.check_3v_10bit.set_sensitive(True)
  2514.                         else:
  2515.                                 self.check_3v_10bit.set_sensitive(False)
  2516.                         if Vars.XvCheck.pool or Vars.XvCheck.threads:
  2517.                                 self.check_3v_pool.set_sensitive(True)
  2518.                         else:
  2519.                                 self.check_3v_pool.set_active(False)
  2520.                                 self.check_3v_pool.set_sensitive(False)
  2521.                         if Vars.XvCheck.opencl:
  2522.                                 self.check_3v_opencl.set_sensitive(True)
  2523.                         else:
  2524.                                 self.check_3v_opencl.set_active(False)
  2525.                                 self.check_3v_opencl.set_sensitive(False)
  2526.                         # vrc
  2527.                         if Vars.XvCheck.vrc:
  2528.                                 self.box_vrc.set_sensitive(True)
  2529.                                 self.spin_vc['spinner'].set_sensitive(True)
  2530.                                 self.cboxtxt_change2(
  2531.                                         self.box_vrc,
  2532.                                         self.on_codec_vrc_changed,
  2533.                                         eval('VcodecOther.VRC' + Vars.XvCheck.codec),
  2534.                                         0,
  2535.                                         'Vars.vrc_list',
  2536.                                         Vars.XvCheck.codec)
  2537.                         else:
  2538.                                 self.spin_vc['spinner'].set_sensitive(False)
  2539.                                 self.box_vrc.set_sensitive(False)
  2540.                         # preset
  2541.                         if Vars.XvCheck.preset:
  2542.                                 self.box_3v_preset.set_sensitive(True)
  2543.                                 self.cboxtxt_change(
  2544.                                         self.box_3v_preset,
  2545.                                         self.on_preset_changed,
  2546.                                         eval('VcodecOther.' + Vars.XvCheck.codec + '_preset'),
  2547.                                         eval('VcodecOther.' + Vars.XvCheck.codec + '_preset_default'),
  2548.                                         'Vars.preset_list',
  2549.                                         Vars.XvCheck.codec)
  2550.                         else:
  2551.                                 self.box_3v_preset.set_sensitive(False)
  2552.                         # tune
  2553.                         if Vars.XvCheck.tune:
  2554.                                 self.box_3v_tune.set_sensitive(True)
  2555.                                 self.cboxtxt_change(
  2556.                                         self.box_3v_tune,
  2557.                                         self.on_preset_changed,
  2558.                                         eval('VcodecOther.' + Vars.XvCheck.codec + '_tune'),
  2559.                                         eval('VcodecOther.' + Vars.XvCheck.codec + '_tune_default'),
  2560.                                         'Vars.tune_list',
  2561.                                         Vars.XvCheck.codec)
  2562.                         else:
  2563.                                 self.box_3v_tune.set_sensitive(False)
  2564.                         # opts
  2565.                         if Vars.XvCheck.opts:
  2566.                                 self.box_3v_x264opts.set_sensitive(True)
  2567.                                 self.cboxtxt_change2(
  2568.                                         self.box_3v_x264opts,
  2569.                                         self.on_codec_clicked,
  2570.                                         eval('VcodecOptions.OPT' + Vars.XvCheck.codec),
  2571.                                         eval('VcodecOptions.OPT' + Vars.XvCheck.codec + '_default'),
  2572.                                         'Vars.opt_list',
  2573.                                         Vars.XvCheck.codec)
  2574.                         else:
  2575.                                 self.box_3v_x264opts.set_sensitive(False)
  2576.  
  2577.         def make_video_codec_str(self):
  2578.                 video_codec_str = ""
  2579.                 ## no video encoding
  2580.                 if Vars.XvCheck.no_video_enc:
  2581.                                 video_codec_str = Vars.XvCheck.comm_str
  2582.                                 return video_codec_str
  2583.                 # opts
  2584.                 if Vars.XvCheck.opts:
  2585.                         selected_opt = self.box_3v_x264opts.get_active_text()
  2586.                         options_obj = eval('VcodecOptions.OPT' + Vars.XvCheck.codec)
  2587.                         for i in range(0,len(options_obj)):
  2588.                                 if options_obj[i].label == selected_opt:
  2589.                                         XoptCheck = options_obj[i]
  2590.                                         break
  2591.                                 else:
  2592.                                         XoptCheck = options_obj[0]
  2593.                                         # protection on OPT change
  2594.                                         # next ui main loop will find selected_opt label
  2595.                         if XoptCheck.text_entry:
  2596.                                 self.entry_optscustom.set_sensitive(True)
  2597.                                 self.entry_optscustom.set_tooltip_text(Tips.x265_optscustom_str)
  2598.                                 if self.entry_optscustom.get_chars(0, -1) != '':
  2599.                                         self.entry_optscustom_clear_button.set_sensitive(True)
  2600.                                         overr_parms = self.parms_overr_add(
  2601.                                                 XoptCheck.comm_str,
  2602.                                                 self.entry_optscustom.get_chars(0, -1)
  2603.                                                 )
  2604.                                         video_codec_str += Vars.XvCheck.opts_comm + overr_parms
  2605.                                 else:
  2606.                                         self.entry_optscustom_clear_button.set_sensitive(False)
  2607.                                         video_codec_str += Vars.XvCheck.opts_comm + XoptCheck.comm_str
  2608.                         else:
  2609.                                 self.entry_optscustom.set_sensitive(False)
  2610.                                 self.entry_optscustom.set_tooltip_text('')
  2611.                                 self.entry_optscustom_clear_button.set_sensitive(False)
  2612.                                 video_codec_str += Vars.XvCheck.opts_comm + XoptCheck.comm_str
  2613.                         # pools 3
  2614.                         if Vars.XvCheck.pool:
  2615.                                 if self.check_3v_pool.get_active():
  2616.                                         video_codec_str += ":pools=3"
  2617.                         # opencl
  2618.                         if Vars.XvCheck.opencl:
  2619.                                 if self.check_3v_opencl.get_active():
  2620.                                         video_codec_str += ":opencl"
  2621.                 # preset
  2622.                 if Vars.XvCheck.preset:
  2623.                         preset = self.box_3v_preset.get_active_text()
  2624.                         video_codec_str += " -preset " + preset + " "
  2625.                 # tune
  2626.                 if Vars.XvCheck.tune:
  2627.                         tune = self.box_3v_tune.get_active_text()
  2628.                         if tune != "none":
  2629.                                 video_codec_str += "-tune " + tune
  2630.                 # threads
  2631.                 if Vars.XvCheck.threads:
  2632.                         if self.check_3v_pool.get_active():
  2633.                                 video_codec_str += " -threads 3"
  2634.                 # 10bit -pix_fmt yuv420p10le
  2635.                 if Vars.XvCheck.is10bit:
  2636.                         if self.check_3v_10bit.get_active():
  2637.                                 video_codec_str += " -pix_fmt yuv420p10le "
  2638.                 ##
  2639.                 return video_codec_str
  2640.  
  2641.         def video_ui_widg_false_all(self):
  2642.                 # deactivate widget
  2643.                 self.box_vrc.set_sensitive(False)
  2644.                 self.spin_vc['spinner'].set_sensitive(False)
  2645.                 self.box_3v_preset.set_sensitive(False)
  2646.                 self.box_3v_tune.set_sensitive(False)
  2647.                 self.box_3v_x264opts.set_sensitive(False)
  2648.                 self.entry_optscustom.set_sensitive(False)
  2649.                 self.check_3v_opencl.set_active(False)
  2650.                 self.check_3v_opencl.set_sensitive(False)
  2651.                 self.check_2pass.set_active(False)
  2652.                 self.check_2pass.set_sensitive(False)
  2653.                 self.check_3v_10bit.set_sensitive(False)
  2654.                 self.check_3v_pool.set_sensitive(False)
  2655.                 self.entry_optscustom_clear_button.set_sensitive(False)
  2656.  
  2657.         def parms_overr_add(self, parms_str, input_str):
  2658.                 out_parms = parms_str
  2659.                 inlist = input_str.split(':')
  2660.                 parmlist = parms_str.split(':')
  2661.                 for i in range (0,len(inlist)):
  2662.                         in_parm = inlist[i].split('=')[0]
  2663.                         if in_parm in VcodecOptions.OPTx265_keys:
  2664.                                 for x in range (0,len(parmlist)):
  2665.                                         parm = parmlist[x].split('=')[0]
  2666.                                         if parm == in_parm:
  2667.                                                 out_parms = out_parms.replace(parmlist[x], inlist[i])
  2668.                                                 break
  2669.                                         if x == len(parmlist)-1:
  2670.                                                 out_parms += ':' + inlist[i]
  2671.                 return out_parms
  2672.  
  2673.         def on_entry_optscustom_clear_button(self, button):
  2674.                 self.entry_optscustom.set_text('')
  2675.                 self.on_codec_clicked(0)
  2676.  
  2677.         def on_f3_other_clicked(self, button):
  2678.                 Vars.final_other_str = ""
  2679.                 Vars.debug = 0
  2680.                 Vars.first_pass = 0
  2681.                 Vars.n_pass = 1
  2682.                 if self.check_nometa.get_active():
  2683.                         Vars.final_other_str = "-map_metadata -1"
  2684.                 if self.check_2pass.get_active():
  2685.                                 Vars.first_pass = 1
  2686.                                 Vars.n_pass = 2
  2687.                 if self.check_scopy.get_active():
  2688.                         if (Vars.final_other_str == ""):
  2689.                                 Vars.final_other_str = "-c:s copy"
  2690.                         else:
  2691.                                 Vars.final_other_str += " " + "-c:s copy"      
  2692.                 if self.check_debug.get_active():
  2693.                                 Vars.debug = 1
  2694.                 self.make_p3_out_command()
  2695.  
  2696.         def on_container_changed(self,button):
  2697.                
  2698.                 selected_container = self.box_oth_container.get_active_text()
  2699.                 for i in range(0,len(VcodecOther.OutContainers)):
  2700.                         if VcodecOther.OutContainers[i].label == selected_container:
  2701.                                 XocCheck = VcodecOther.OutContainers[i]
  2702.                                 #XocCheck now is the selected container obj
  2703.                                 break
  2704.                 #set generals
  2705.                 Vars.container_str = XocCheck.comm_str
  2706.                 Vars.ext = XocCheck.ext
  2707.                 if XocCheck.sub_stream and Vars.have_subs:
  2708.                         self.check_scopy.set_sensitive(True)
  2709.                         self.check_scopy.set_active(True)
  2710.                 else:  
  2711.                         self.check_scopy.set_active(False)
  2712.                         self.check_scopy.set_sensitive(False)
  2713.                 #set audio choises
  2714.                 if Vars.acodec_list != XocCheck.alist: # alist is changed
  2715.                         self.cboxtxt_change2(
  2716.                                 self.box_ac,
  2717.                                 self.on_codec_audio_changed,
  2718.                                 eval('AudioEncoder.AE' + XocCheck.alist),
  2719.                                 eval('AudioEncoder.AE' + XocCheck.alist + '_default'),
  2720.                                 'Vars.acodec_list',
  2721.                                 XocCheck.alist
  2722.                                 )
  2723.                         ########### OLD WAY ####################
  2724.                         #self.cboxtxt_change2(
  2725.                                 #self.box_ac,
  2726.                                 #self.on_codec_audio_changed,
  2727.                                 #AudioEncoder.AEmp4,
  2728.                                 #AudioEncoder.AEmp4_default,
  2729.                                 #'Vars.acodec_list',
  2730.                                 #"mp4")
  2731.                         ########################################
  2732.                 #set video choises
  2733.                 if Vars.vcodec_list != XocCheck.vlist: # vlist is changed
  2734.                         self.cboxtxt_change2(
  2735.                                 self.box_vcodec,
  2736.                                 self.on_codec_video_changed,
  2737.                                 eval('VideoEncoder.VE' + XocCheck.vlist),
  2738.                                 eval('VideoEncoder.VE' + XocCheck.vlist + '_default'),
  2739.                                 'Vars.vcodec_list',
  2740.                                 XocCheck.vlist
  2741.                                 )
  2742.                         if XocCheck.audio_only:
  2743.                                 self.box_vcodec.set_sensitive(False)
  2744.                         else:
  2745.                                 self.box_vcodec.set_sensitive(True)
  2746.                 self.check_out_file()
  2747.                 self.make_p3_out_command()
  2748.  
  2749.         def on_but_f3_run_clicked(self, button):
  2750.                                
  2751.                 def clear_ff_file():
  2752.                         if os.path.exists(Vars.outdir + '/' + 'ffmpeg2pass-0.log'):
  2753.                                 os.remove(Vars.outdir + '/' + 'ffmpeg2pass-0.log')
  2754.                         if os.path.exists(Vars.outdir + '/' + 'ffmpeg2pass-0.log.mbtree'):
  2755.                                 os.remove(Vars.outdir + '/' + 'ffmpeg2pass-0.log.mbtree')
  2756.                         if os.path.exists(Vars.outdir + '/' + 'x264_lookahead.clbin'):
  2757.                                 os.remove(Vars.outdir + '/' + 'x264_lookahead.clbin')
  2758.                         if os.path.exists(Vars.outdir + '/' + 'x265_2pass.log'):
  2759.                                 os.remove(Vars.outdir + '/' + 'x265_2pass.log')
  2760.                
  2761.                 def end_run():
  2762.                         if Vars.eff_pass == 0 and Vars.final_command1 == "":
  2763.                                 Vars.out_file_size = self.humansize(Vars.newname)
  2764.                                 stri = " Done in: " + self.sec2hms(Vars.time_done) + " " + "\n"\
  2765.                                         + " in:  " + Vars.in_file_size + "\n"\
  2766.                                         + " out: " + Vars.out_file_size
  2767.                                 self.but_f3_run.set_tooltip_text(stri)
  2768.                                 stri2 = " Done in: " + self.sec2hms(Vars.time_done) + " "\
  2769.                                         + " input size:  " + Vars.in_file_size + " "\
  2770.                                         + " output size: " + Vars.out_file_size
  2771.                                 self.reportdata.set_text(stri2)
  2772.                                 self.but_f3_run.set_label('ENCODE')
  2773.                                 self.window.set_deletable(True)
  2774.                                 clear_ff_file()
  2775.                                 Vars.ENCODING = False
  2776.                         elif Vars.eff_pass == 0 and Vars.final_command1 != "":
  2777.                                 Vars.eff_pass = 1
  2778.                                 Vars.ENCODING = False
  2779.                                 self.on_but_f3_run_clicked(1)
  2780.                         elif Vars.eff_pass == 1:
  2781.                                 Vars.out_file_size = self.humansize(Vars.newname)
  2782.                                 stri = " Done in: " + self.sec2hms(Vars.time_done + Vars.time_done_1) + " " + "\n"\
  2783.                                         + " pass 1: " + self.sec2hms(Vars.time_done) + " " + "\n"\
  2784.                                         + " pass 2: " + self.sec2hms(Vars.time_done_1) + " " + "\n"\
  2785.                                         + " in:  " + Vars.in_file_size + "\n"\
  2786.                                         + " out: " + Vars.out_file_size
  2787.                                 self.but_f3_run.set_tooltip_text(stri)
  2788.                                 stri2 = " Done in: " + self.sec2hms(Vars.time_done + Vars.time_done_1) + " "\
  2789.                                         + " pass 1: " + self.sec2hms(Vars.time_done) + " "\
  2790.                                         + " pass 2: " + self.sec2hms(Vars.time_done_1) + " "\
  2791.                                         + " input size:  " + Vars.in_file_size + " "\
  2792.                                         + " output size: " + Vars.out_file_size
  2793.                                 self.reportdata.set_text(stri2)
  2794.                                 Vars.eff_pass = 0
  2795.                                 self.but_f3_run.set_label('ENCODE')
  2796.                                 self.window.set_deletable(True)
  2797.                                 clear_ff_file()
  2798.                                 Vars.ENCODING = False
  2799.                
  2800.                 def check_run(name):
  2801.                        
  2802.                         def win_controls(label, boolean):
  2803.                                 self.but_f3_run.set_label(label)
  2804.                                 self.window.set_deletable(boolean)
  2805.                                 self.but_f3_run.set_tooltip_text('  Abort current encoding  ')
  2806.  
  2807.                         def encod_time(startime):
  2808.                                 if Vars.time_done == 0:
  2809.                                         et = self.sec2hms(time.time() - startime)
  2810.                                 else:
  2811.                                         et = self.sec2hms((time.time() - startime) + Vars.time_done)
  2812.                                 self.but_f3_run.set_label(et + ' - ABORT' )
  2813.  
  2814.                         GLib.idle_add(win_controls, 'ENCODING ...' , False)
  2815.                         time.sleep(0.02)
  2816.                         t0 = time.time()
  2817.                         processname = name
  2818.                         for line in subprocess.Popen(["ps", "xa"], shell=False, stdout=subprocess.PIPE).stdout:
  2819.                                 line = line.decode()
  2820.                                 fields = line.split()
  2821.                                 pid = fields[0]
  2822.                                 process = fields[4]
  2823.                                 if process.find(processname) >= 0:              
  2824.                                         if line.find(Vars.filename) >= 0:
  2825.                                                 mypid = pid
  2826.                                                 break
  2827.                         finn = True
  2828.                         while finn == True:
  2829.                                 GLib.idle_add(encod_time, t0)
  2830.                                 time.sleep(1)
  2831.                                 try:
  2832.                                         finn = os.path.exists("/proc/" + mypid)
  2833.                                 except:
  2834.                                         Vars.eff_pass = 0
  2835.                                         GLib.idle_add(win_controls, 'ENCODE' , True)
  2836.                                         time.sleep(0.02)
  2837.                                         Vars.ENCODING = False
  2838.                                         return
  2839.                         if Vars.eff_pass == 0:  
  2840.                                 tfin = time.time() - t0
  2841.                                 Vars.time_done = int(tfin)
  2842.                         else:
  2843.                                 tfin = time.time() - t0
  2844.                                 Vars.time_done_1 = int(tfin)
  2845.                         GLib.idle_add(end_run)
  2846.                         time.sleep(0.5)
  2847.                        
  2848.                 if Vars.ENCODING: # STOP pressed
  2849.                         Vars.final_command1 = "" # prevent 2 pass start
  2850.                         command = "q"+ "\n"
  2851.                         length = len(command)
  2852.                         self.terminal.feed_child(command, length)
  2853.                         return
  2854.                
  2855.                 if Vars.eff_pass == 0:
  2856.                         self.check_out_file()
  2857.                         Vars.time_done = 0
  2858.                         Vars.time_done_1 = 0
  2859.                         if Vars.n_pass == 1:
  2860.                                 Vars.final_command1 = ""
  2861.                                 Vars.final_command2 = Vars.ffmpeg_ex + " -hide_banner"
  2862.                                 if Vars.ac3_drc != "":
  2863.                                         Vars.final_command2 += " " + Vars.ac3_drc
  2864.                                 Vars.final_command2 += " -i \"" \
  2865.                                         + Vars.filename + "\" " \
  2866.                                         + Vars.p3_command \
  2867.                                         +  " \"" + Vars.newname + "\"" \
  2868.                                         + "\n"
  2869.                                 command = Vars.final_command2
  2870.                        
  2871.                         if Vars.n_pass == 2:
  2872.                                 Vars.final_command1 = Vars.ffmpeg_ex + " -hide_banner" + " -i \"" \
  2873.                                         + Vars.filename + "\" " \
  2874.                                         + Vars.p3_comm_first_p \
  2875.                                         + "\n"
  2876.                                 Vars.final_command2 = Vars.ffmpeg_ex + " -hide_banner"
  2877.                                 if Vars.ac3_drc != "":
  2878.                                         Vars.final_command2 += " " + Vars.ac3_drc
  2879.                                 Vars.final_command2 += " -i \"" \
  2880.                                         + Vars.filename + "\" " \
  2881.                                         + Vars.p3_command \
  2882.                                         +  " \"" + Vars.newname + "\"" \
  2883.                                         + "\n"
  2884.                                 command = Vars.final_command1
  2885.                 else:
  2886.                         command = Vars.final_command2
  2887.                        
  2888.                 if Vars.debug == 1:
  2889.                         if Vars.n_pass == 1:
  2890.                                 command = "echo $\'\n\n\n" + Vars.final_command2  + "\' \n"
  2891.                         if Vars.n_pass == 2:
  2892.                                 command = "echo $\'\n\n\n" + Vars.final_command1 + "\n" + Vars.final_command2 + "\' \n"
  2893.                 length = len(command)
  2894.  
  2895.                 #
  2896.                 if Vars.debug == 0:
  2897.                         if Vars.eff_pass != 1:
  2898.                                 self.but_f3_run.set_tooltip_text('')
  2899.                                 self.reportdata.set_text('')
  2900.                         Vars.ENCODING = True
  2901.                
  2902.                 self.terminal.feed_child(command, length)
  2903.                
  2904.                 if Vars.debug == 0:
  2905.                         t = threading.Thread(name='child procs', target=check_run, args=(Vars.ffmpeg_ex,))
  2906.                         t.daemon = True
  2907.                         t.start()
  2908.                        
  2909.  
  2910.         def on_folder_clicked(self, button):
  2911.                 if Vars.ENCODING:
  2912.                         return
  2913.                 dialog = Gtk.FileChooserDialog("Please choose a folder", self.window,
  2914.                 Gtk.FileChooserAction.SELECT_FOLDER,
  2915.                 ("_Cancel", Gtk.ResponseType.CANCEL,
  2916.                 "_Select", Gtk.ResponseType.OK))
  2917.                 dialog.set_default_size(800, 400)
  2918.                 dialog.set_current_folder(Vars.outdir)
  2919.  
  2920.                 response = dialog.run()
  2921.                 if response == Gtk.ResponseType.OK:
  2922.                         Vars.outdir = dialog.get_filename()
  2923.                         command = "cd " + "\"" + Vars.outdir + "\"" + "\n"
  2924.                         length = len(command)
  2925.                         self.terminal.feed_child(command, length)
  2926.                         self.f3_run_outdir_label.set_markup("<b>out dir:  </b>" + Vars.outdir)
  2927.                         self.check_out_file()
  2928.                        
  2929.                 dialog.destroy()
  2930.  
  2931.         def on_but_black_det_clicked(self, button):
  2932.        
  2933.                 def update_progress(pprog):
  2934.                         self.progressbar_black_det.set_fraction(pprog)
  2935.                         return False
  2936.                
  2937.                 def update_textv(stri):
  2938.                         self.textbuffer.insert_at_cursor(stri, -1)
  2939.                         i = self.textbuffer.get_end_iter()
  2940.                         self.textview.scroll_to_iter(i, 0.0, True, 0.0, 1.0)
  2941.                         return False
  2942.  
  2943.                 def stopped():
  2944.                         stri = "Stopped by user.\n"
  2945.                         self.textbuffer.insert_at_cursor(stri, -1)
  2946.                         i = self.textbuffer.get_end_iter()
  2947.                         self.textview.scroll_to_iter(i, 0.0, True, 0.0, 1.0)
  2948.                         self.but_black_det.set_label("Black detect")
  2949.                         self.blackdet_spin.stop()
  2950.                         self.blackdet_spin.set_sensitive(False)
  2951.                         self.progressbar_black_det.set_fraction(0.0)
  2952.                         Vars.blackdet_is_run = False
  2953.                         set_other_butt(True)
  2954.                        
  2955.                 def bd_finish(detected):
  2956.                         if detected == 0:
  2957.                                 stri = "none black gap found"
  2958.                                 self.textbuffer.insert_at_cursor(stri, -1)
  2959.                         self.blackdet_spin.stop()
  2960.                         self.blackdet_spin.set_sensitive(False)
  2961.                         self.but_black_det.set_label("black detectet")
  2962.                         self.progressbar_black_det.set_fraction(1.0)
  2963.                         Vars.blackdet_is_run = False
  2964.                         Vars.BLACKDT_DONE = True
  2965.                         set_other_butt(True)
  2966.  
  2967.                 def set_other_butt(boolean):
  2968.                         if Vars.VOLDT_DONE != True:
  2969.                                 self.but_volume_det.set_sensitive(boolean)
  2970.                         if Vars.FRAMDT_DONE != True:
  2971.                                 self.but_frames_det.set_sensitive(boolean)
  2972.                
  2973.                 def my_thread_blackdet():
  2974.                         Vars.blackdet_is_run = True
  2975.                         command = [Vars.ffmpeg_ex, '-i', Vars.filename, '-y', '-an', '-vf', 'blackdetect=d=.5', '-f', 'null', '/dev/null']
  2976.                         p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, universal_newlines=True)
  2977.                         self.bd_th = False
  2978.                         detected = 0
  2979.                         time_step = 0
  2980.                         pprog = 0.0
  2981.                         stri = ""
  2982.                         GLib.idle_add(set_other_butt, False)
  2983.                         time.sleep(0.01)
  2984.                        
  2985.                         while True:
  2986.                                 line = p.stderr.readline()
  2987.                                
  2988.                                 if 'time=' in line:
  2989.                                         if time_step == 12:
  2990.                                                 tml = line.split('time=')[1]
  2991.                                                 tml2 = tml.split(' ')[0]
  2992.                                                 time_n = tml2.split('.')[0]
  2993.                                                 time_n = self.hms2sec(time_n)
  2994.                                                 time_step = 0
  2995.                                                 pprog = float(time_n)/Vars.duration_in_sec
  2996.                                                 GLib.idle_add(update_progress, pprog)
  2997.                                                 time.sleep(0.002)
  2998.                                         else:
  2999.                                                 time_step += 1
  3000.                                                
  3001.                                 if 'blackdetect ' in line:
  3002.                                                 a = line
  3003.                                                 b = a.split('black_start:')[1]
  3004.                                                 start = b.split(' ')[0]
  3005.                                                 st_in_s = float(start)
  3006.                                                 st_in_s = int(st_in_s)
  3007.                                                 start_in_s = ("%4.1i"% (st_in_s))  
  3008.                                                 start = self.sec2hms(start)
  3009.                                                 stri = "black start at: " + start_in_s + " s, " + start + " "
  3010.                                                 c = b.split('black_duration:')[1]
  3011.                                                 durat = c.split(' ')[0]
  3012.                                                 dur_s = float(durat)
  3013.                                                 dur_s = "{0:0=3.1f}".format(dur_s)
  3014.                                                 stri += "duration: " + dur_s + "s\n"
  3015.                                                 detected = 1
  3016.                                                 GLib.idle_add(update_textv, stri)
  3017.                                                 time.sleep(0.002)
  3018.                                 if line == '' and p.poll() != None:
  3019.                                         break
  3020.                                 if self.bd_th:
  3021.                                         p.communicate("q")
  3022.                                         break
  3023.                         try:
  3024.                                 p.communicate()
  3025.                         except:
  3026.                                 GLib.idle_add(stopped)
  3027.                                 time.sleep(0.1)
  3028.                                 return
  3029.                         GLib.idle_add(bd_finish, detected)
  3030.                         time.sleep(0.1)
  3031.                        
  3032.                 if Vars.BLACKDT_DONE:
  3033.                         return          
  3034.                        
  3035.                 if Vars.blackdet_is_run == False:
  3036.                         self.but_black_det.set_label("Stop")
  3037.                         self.textbuffer.set_text('') # clear for insert from start
  3038.                         stri = "Detected:\n\n"
  3039.                         start = self.textbuffer.get_start_iter()
  3040.                         self.textbuffer.insert(start, stri, -1)
  3041.                         self.blackdet_spin.set_sensitive(True)
  3042.                         self.blackdet_spin.start()                              
  3043.                         thread = threading.Thread(target=my_thread_blackdet)
  3044.                         thread.daemon = True
  3045.                         thread.start()
  3046.                        
  3047.                 elif Vars.blackdet_is_run == True:
  3048.                         self.bd_th = True
  3049.        
  3050.                
  3051.         # -------------------------------------  
  3052.        
  3053.         def preview_logic(self):
  3054.                 if not('-map ' in Vars.p3_command or '-vf ' in Vars.p3_command):
  3055.                         self.buttest.set_sensitive(False)
  3056.                         self.buttestspl.set_sensitive(False)
  3057.                 elif '-map ' in Vars.p3_command and '-vf ' in Vars.p3_command:
  3058.                         self.buttest.set_sensitive(False)
  3059.                         self.buttestspl.set_sensitive(False)
  3060.                 elif '-map ' in Vars.p3_command:
  3061.                         self.buttest.set_sensitive(True)
  3062.                         self.buttestspl.set_sensitive(False)
  3063.                 elif '-vf ' in Vars.p3_command:
  3064.                         self.buttest.set_sensitive(True)
  3065.                         self.buttestspl.set_sensitive(True)
  3066.  
  3067.         def scale_calc(self):
  3068.                 dim_round = 2
  3069.                 if self.check_round.get_active():
  3070.                         dim_round = 8
  3071.                 Vars.scalestr = ""
  3072.                 # dar
  3073.                 dar = self.box_scale_ar['cbox'].get_active()
  3074.                 if dar == 0: # 16/9
  3075.                         scale_factor = 1.777777778
  3076.                         setdar = ",setdar=16/9,setsar=1/1"
  3077.                 elif dar == 1: # 4/3
  3078.                         scale_factor = 1.333333333
  3079.                         setdar = ",setdar=4/3,setsar=1/1"
  3080.                 elif dar == 2: # 235/100
  3081.                         scale_factor = 2.35
  3082.                         setdar = ",setdar=235/100,setsar=1/1"
  3083.                 elif dar == 3: #1/1 same as input  
  3084.                         w = int(Vars.video_width)
  3085.                         h = int(Vars.video_height)
  3086.                         # cropped?
  3087.                         if self.checkcr.get_active():
  3088.                                 crT = int(self.spinct['adj'].get_value())
  3089.                                 crB = int(self.spincb['adj'].get_value())
  3090.                                 crL = int(self.spincl['adj'].get_value())
  3091.                                 crR = int(self.spincr['adj'].get_value())
  3092.                                 h = h - crT - crB
  3093.                                 w = w - crL - crR
  3094.                         scale_factor = (float(w) / h)
  3095.                         setdar = ""
  3096.                 #input number
  3097.                 num_in = self.size_spinner['adj'].get_value()
  3098.                 #side in
  3099.                 side = self.box_scale_side['cbox'].get_active() # 0 none, 1 W, 2 H
  3100.                 if side == 1:
  3101.                         wout = num_in
  3102.                         hout = wout / float(scale_factor)
  3103.                 elif side == 2:
  3104.                         hout = num_in
  3105.                         wout = hout * float(scale_factor)
  3106.                 wout = int(round(float(wout)/dim_round)*dim_round)
  3107.                 hout = int(round(float(hout)/dim_round)*dim_round)
  3108.                 # scale string
  3109.                 scalestr = str(wout) + ":" + str(hout)
  3110.                 #                    
  3111.                 zscale = self.check.get_active()  
  3112.                 if zscale:
  3113.                         Vars.scalestr = "zscale=" + scalestr + ":f=lanczos"  + setdar  
  3114.                 else:
  3115.                         Vars.scalestr = "scale=" + scalestr + ":flags=lanczos" + setdar  
  3116.                 self.outfilter()
  3117.    
  3118.         def outfilter(self):
  3119.                 final_str = ""
  3120.                 if Vars.deint_str != "":
  3121.                         final_str += Vars.deint_str
  3122.                 if Vars.crop_str != "":
  3123.                         if final_str == "":
  3124.                                 final_str += Vars.crop_str
  3125.                         else:
  3126.                                         final_str +=  "," + Vars.crop_str
  3127.                 if Vars.scalestr != "":
  3128.                         if final_str == "":
  3129.                                 final_str += Vars.scalestr
  3130.                         else:
  3131.                                 final_str += "," + Vars.scalestr
  3132.                 if Vars.dn_str != "":
  3133.                         if final_str == "":
  3134.                                 final_str += Vars.dn_str
  3135.                         else:
  3136.                                 final_str += "," + Vars.dn_str
  3137.                 if Vars.uns_str != "":
  3138.                         if final_str == "":
  3139.                                 final_str += Vars.uns_str
  3140.                         else:
  3141.                                 final_str += "," + Vars.uns_str
  3142.                 Vars.filter_test_str = final_str
  3143.                
  3144.                 if final_str != "":
  3145.                         Vars.final_vf_str = "-vf " + final_str
  3146.                 else:
  3147.                         Vars.final_vf_str = ""
  3148.                
  3149.                 label_str = ""          
  3150.                 if Vars.maps_str != "":
  3151.                         label_str += Vars.maps_str + " "  
  3152.                 if Vars.time_final_str != "":
  3153.                         label_str += Vars.time_final_str + " "
  3154.                 if Vars.fr_str != "":
  3155.                         label_str += Vars.fr_str + " "
  3156.                 if Vars.final_vf_str != "":
  3157.                         label_str += Vars.final_vf_str
  3158.                        
  3159.                 self.labelout.set_text(label_str)      
  3160.                 self.make_p3_out_command()
  3161.                 if Vars.info_str != "":
  3162.                         self.preview_logic()
  3163.  
  3164.         def make_p3_out_command(self):
  3165.                
  3166.                 def x265_pass_com(string_eval, npass): # string , int (1-2)
  3167.                         datainfo = string_eval.split(' ')
  3168.                         pointer = datainfo.index('-x265-params')
  3169.                         x265opts0 = datainfo[pointer+1]
  3170.                         x265opts1 = x265opts0 + ":pass=" + str(npass) + " "
  3171.                         string_eval = string_eval.replace(x265opts0, x265opts1)
  3172.                         return string_eval
  3173.                
  3174.                 def libsoxr_apply(string_eval):
  3175.                         if 'aresample=matrix_encoding=dplii' in string_eval:
  3176.                                 string_eval = string_eval.replace('aresample=matrix_encoding=dplii', 'aresample=matrix_encoding=dplii:resampler=soxr')
  3177.                         elif 'aformat=channel_layouts=stereo' in string_eval:
  3178.                                 string_eval = string_eval.replace('aformat=channel_layouts=stereo', 'aformat=channel_layouts=stereo,aresample=resampler=soxr')
  3179.                         else:
  3180.                                 string_eval = 'aresample=resampler=soxr,' + string_eval
  3181.                         return string_eval
  3182.                
  3183.                 # encoding video? audio?
  3184.                 v_encod = not(Vars.XvCheck.no_video_enc)  # not: vcopy vn
  3185.                 a_encod = not(Vars.XaCheck.no_audio_enc) # not: acopy an
  3186.                        
  3187.                 Vars.p3_command = ""
  3188.                 Vars.p3_comm_first_p = ""
  3189.                 self.f3_out_label.set_label("")
  3190.                
  3191.                 if Vars.maps_str != "":
  3192.                         Vars.p3_command = Vars.maps_str + " "  
  3193.                 if Vars.time_final_str != "":
  3194.                         Vars.p3_command += Vars.time_final_str + " "
  3195.                 if Vars.fr_str != "" and v_encod:
  3196.                         Vars.p3_command += Vars.fr_str + " "            
  3197.                 if Vars.final_vf_str != "" and v_encod: # check -vcopy
  3198.                         Vars.p3_command += Vars.final_vf_str + " "
  3199.                        
  3200.                 # first pass    
  3201.                 if Vars.first_pass:
  3202.                         Vars.p3_comm_first_p = Vars.p3_command + Vars.video_codec_str + " "
  3203.                         if Vars.vcodec_is == "x265":
  3204.                                 Vars.p3_comm_first_p = x265_pass_com(Vars.p3_comm_first_p, 1)
  3205.                         else:
  3206.                                 Vars.p3_comm_first_p += "-pass 1 "
  3207.                                 if Vars.vcodec_is == "x264":
  3208.                                         Vars.p3_comm_first_p += "-fastfirstpass 1 "
  3209.                         Vars.p3_comm_first_p += "-an -f null /dev/null"
  3210.                 else:
  3211.                         Vars.p3_comm_first_p = ""
  3212.                 # -af
  3213.                 audiof = ""
  3214.                 if Vars.final_af_str != "" and a_encod:  # check -acopy -an
  3215.                         audiof_1 = Vars.final_af_str
  3216.                 else:
  3217.                         audiof_1 = ""
  3218.                 if (Vars.compand_data != "" or Vars.dynaudnorm_data != "") and a_encod:  # check -acopy -an
  3219.                         if Vars.compand_data != "":
  3220.                                 audiof_2 = Vars.compand_data
  3221.                         elif Vars.dynaudnorm_data != "":
  3222.                                 audiof_2 = Vars.dynaudnorm_data
  3223.                 else:
  3224.                         audiof_2 = ""
  3225.                
  3226.                 if a_encod:
  3227.                         if audiof_1 != "" and audiof_2 != "":
  3228.                                 audiof = audiof_1 + "," + audiof_2
  3229.                         elif audiof_1 != "" and audiof_2 == "":
  3230.                                 if Vars.audio_channels == 6 and self.box_audio_ch.get_active_text() == '2' and self.check_prologic.get_active():
  3231.                                         audiof = 'aformat=channel_layouts=stereo,aresample=matrix_encoding=dplii,' + audiof_1
  3232.                                 else:
  3233.                                         audiof = audiof_1
  3234.                         elif audiof_1 == "" and audiof_2 != "":
  3235.                                 audiof = audiof_2
  3236.                         elif audiof_1 == "" and audiof_2 == "":
  3237.                                 if Vars.audio_channels == 6 and self.box_audio_ch.get_active_text() == '2' and self.check_prologic.get_active():
  3238.                                         audiof = 'aformat=channel_layouts=stereo,aresample=matrix_encoding=dplii'
  3239.                         # libsoxr              
  3240.                         if self.check_soxr.get_sensitive() and self.check_soxr.get_active():
  3241.                                 if audiof == "":
  3242.                                         audiof = 'aresample=resampler=soxr'
  3243.                                 else:
  3244.                                         audiof = libsoxr_apply(audiof)
  3245.                         #
  3246.                         if audiof != "":        
  3247.                                 Vars.p3_command += "-af \'" + audiof + "\' "
  3248.                        
  3249.                 Vars.final_codec_str = Vars.audio_codec_str + " " + Vars.video_codec_str
  3250.                 if Vars.final_codec_str != "":
  3251.                         Vars.p3_command += Vars.final_codec_str + " "
  3252.                
  3253.                 #second pass
  3254.                 if Vars.n_pass == 2:
  3255.                         if Vars.vcodec_is != "x265":
  3256.                                 Vars.p3_command += "-pass 2" + " "
  3257.                         elif Vars.vcodec_is == "x265":
  3258.                                 Vars.p3_command = x265_pass_com(Vars.p3_command, 2)
  3259.                 if Vars.container_str != "":
  3260.                         Vars.p3_command += Vars.container_str + " "
  3261.                 if Vars.final_other_str != "":
  3262.                         Vars.p3_command += Vars.final_other_str + " "
  3263.                 self.f3_out_label.set_label(Vars.p3_command)
  3264.  
  3265.         def main(self):
  3266.                 Gtk.main()
  3267.  
  3268. if __name__ == "__main__":
  3269.         GObject.threads_init()
  3270.         ProgrammaGTK()
  3271.         Gtk.main()
RAW Paste Data