Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- '''
- ---------------------------------
- work in python2.7/3
- os: gnu/linux only
- ---------------------------------
- need:
- python, gtk3 (3.14|3.16), cairo, pango, libvte (2.90|2.91)
- --------------------------------
- packages in debian could be:
- libgtk-3-0
- python-gi
- python-gi-cairo
- python-gobject
- gir1.2-pango-1.0
- libvte9
- libvte-2.90-9 | libvte-2.91-0
- gir1.2-vte-2.90 | gir1.2-vte-2.91
- ---------------------------------
- ffmpeg executables:
- ffmpeg, ffplay, ffprobe >= 2.8
- build with:
- libfaac, libaacplus, libfdk-aac, libmp3lame,
- postproc, avfilter,
- libx264, libx265 multilib (8-10bit),
- libsoxr, libzimg
- ---------------------------------
- '''
- import gi
- try:
- gi.require_version('Vte', '2.90')
- except:
- pass
- from gi.repository import Gtk, GObject, Vte, GLib, Pango
- import os, sys, subprocess, threading, time, re
- from subprocess import call
- from math import pow
- # Abstract struct class
- class Struct:
- def __init__ (self, *argv, **argd):
- if len(argd):
- # Update by dictionary
- self.__dict__.update (argd)
- else:
- # Update by position
- attrs = [x for x in dir(self) if x[0:2] != "__"]
- for n in range(len(argv)):
- setattr(self, attrs[n], argv[n])
- class Vars(Struct):
- version = "8.204"
- ffmpeg_ex = 'ffmpeg'
- ffplay_ex = 'ffplay'
- ffprobe_ex = 'ffprobe'
- final_vf_str = ""
- final_af_str = ""
- deint_str = ""
- crop_str = ""
- scalestr = ""
- dn_str = ""
- uns_str = ""
- fr_str = ""
- filter_test_str = ""
- video_width = "0"
- video_height = "0"
- darin = "1"
- add_1_1_dar = True
- framerate = 25
- maps_str = ""
- time_final_str = ""
- final_codec_str = ""
- final_other_str = ""
- acodec_is = ""
- audio_channels = 0
- audio_srate_in = ""
- audio_codec_str = ""
- vcodec_is = ""
- video_codec_str = ""
- video_codec_str_more = ""
- container_str = ""
- info_str = ''
- blackdet_is_run = False
- compinit = '.3 .3:1 1:-90/-90 -60/-40 -39/-30 -20/-14 -9/-9 0/-3:6:-5:0:.5'
- compand_data = ''
- compand_time = 0
- dynaudnorm = "f=500:g=31:s=18:p=0.80"
- dynaudnorm_data = ''
- time_start = 0 # for cropdetect and test
- p3_command = ""
- filename = ""
- dirname = ""
- basename = ""
- in_file_size = ""
- ext = ""
- outdir = ""
- indir = ""
- newname = ""
- duration = ""
- duration_in_sec = 0
- time_done = 0
- time_done_1 = 0
- out_file_size = ""
- debug = 0
- first_pass = 0
- n_pass = 1
- p3_comm_first_p = ""
- final_command1 = ""
- final_command2 = ""
- eff_pass = 0
- BLACKDT_DONE = False
- VOLDT_DONE = False
- FRAMDT_DONE = False
- ENCODING = False
- ac3_drc = ""
- have_subs = False
- maps_ch = ['0:0', '0:1', '0:2']
- XaCheck = ""
- XvCheck = ""
- acodec_list = ""
- vcodec_list = ""
- preset_list = ''
- tune_list = ''
- opt_list = ''
- vrc_list = ''
- class Tips(Struct):
- map_tooltip_str = ' use: 0:0 or 0:0,0:1,0:2 '
- time_tooltip_str = ' use: 90 or 90.555 or 00:01:30 or 00:01:30.555 '
- customscale_str = ' use: scale=1014:432,setdar=235/100,setsar=1/1 '
- time2frame_str = ' Convert time sec or hh:mm:ss (.decimal) to frames '
- black_dt_init_str = 'Detect black frames can take some time,\ndepending on the length of the video.'
- compad_str = ' attacks attacks:decays decays: points dbin/dbout dbin/dbout:soft-knee:gain:initial volume:delay '
- 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 '
- drc_str = ' -drc_scale percentage of dynamic range compression to apply (from 0 to 6) (default 1) '
- but_file_str = ' Choose input file '
- audio_samp_str = ' audio samplerate '
- audio_channels_str = ' audio channels '
- subcopy_tooltip_srt = ' false= srt->ass '
- nometa_tooltip_srt = ' true= --map_metadata -1 '
- debug_tooltip_srt = ' only print command in terminal '
- preset_tooltip_str = ' x264/5 preset '
- tune_tooltip_str = ' x264/5 tune '
- opt_tooltip_str = ' x264/5 options/params '
- x265_optscustom_str = ' x265 custom opts, use: rd=3:aq-mode=3:zones=300,1000,b=1.5\/5000,6000,q=50 '
- ffplay_tooltip_str = ' ffplay keys: \n f - full screen \n a - audio stream \n v - video stream \n s - sub stream \n arrows - seek '
- out_dir_tooltip_str = ' Change current out dir \n Default: same as input '
- container_tooltip_srt = ' Change out container '
- ################ AUDIO ##################################
- class ACodec(object):
- 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):
- self.label = label
- self.codec = codec
- self.toolt = toolt
- self.value = value
- self.comm_str = comm_str
- self.kb = kb
- self.afterbrn = afterbrn
- self.force_stereo = force_stereo
- self.no_audio_enc = no_audio_enc
- def __str__(self):
- return '{}, {}, {}'.format(self.label, self.codec, self.toolt)
- class AudioEncoder():
- # audio encoder
- # value=(defvalue, lower, upper, step_inc, page_inc)
- 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 ')
- 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)
- 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)
- 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)
- 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 ')
- 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)
- AEacopy = ACodec(label='Audio Copy', codec='acopy', no_audio_enc=True, comm_str='-c:a copy')
- AEanone = ACodec(label='No Audio', codec='anone', no_audio_enc=True, comm_str='-an')
- AEaap32 = ACodec(label='AAC-HEv1 (aac+ 32 Kb/s)', codec='aap32', comm_str='-c:a libaacplus -b:a 32k')
- AEaap64 = ACodec(label='AAC-HEv1 (aac+ 64 Kb/s)', codec='aap64', comm_str='-c:a libaacplus -b:a 64k', force_stereo=True)
- 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)
- 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)
- # groups: ------------------------------
- AEall = (AEfaaq, AEfaacb, AEfdkaac, AElame, AElameq, AEaacn, AEacopy, AEanone, AEaap32, AEaap64, AEfdkaac_he, AEfdkaac_vbr)
- #
- AEmp4 = (AEfaaq, AEfaacb, AEaacn, AEfdkaac, AEfdkaac_vbr, AEfdkaac_he, AEaap64, AEaap32, AElame, AElameq, AEacopy, AEanone)
- AEmp4_default = AEmp4.index(AEfdkaac_vbr)
- #
- AEmka = (AEfaaq, AEfaacb, AEaacn, AEfdkaac, AEfdkaac_vbr, AEfdkaac_he, AEaap64, AEaap32, AElame, AElameq, AEacopy)
- AEmka_default = AEmka.index(AEfaaq)
- #
- AEavi = (AElame, AElameq, AEacopy, AEanone)
- AEavi_default = AEavi.index(AElame)
- ######## AUDIO SAMPLE RATE ########################
- AEaudio_sample = [
- '48000',
- '44100'
- ]
- ######## AUDIO CHANNEL ############################
- AEaudio_channels = [
- "2",
- "1"
- ]
- # ########################## VIDEO #################################
- class VCodec(object):
- def __init__(self, label=None, codec=None, comm_str=None, crf_val=None, br_val=None, q_val=None, vrc_custom_comm=False, crf_comm=None, br_comm=None, q_comm=None, kb=False, vrc=False, br2pass=False, preset=False, tune=False, opts=False, opencl=False, is10bit=False, pool=False, threads=False, no_video_enc=False):
- self.label = label
- self.codec = codec
- self.comm_str = comm_str
- self.crf_val = crf_val
- self.br_val = br_val
- self.q_val = q_val
- self.vrc_custom_comm = vrc_custom_comm
- self.crf_comm = crf_comm
- self.br_comm = br_comm
- self.q_comm = q_comm
- self.kb = kb
- self.vrc = vrc
- self.br2pass = br2pass
- self.preset = preset
- self.tune = tune
- self.opts = opts
- self.opencl = opencl
- self.is10bit = is10bit
- self.pool = pool
- self.threads = threads
- self.no_video_enc = no_video_enc
- def __str__(self):
- return '{}, {}, {}'.format(self.label, self.codec, self.comm_str)
- class VideoEncoder():
- 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, opencl=True, threads=True )
- 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), vrc_custom_comm=True, crf_comm='-x265-params crf=', br_comm='-x265-params bitrate=', vrc=True, br2pass=True, preset=True, tune=True, opts=True, is10bit=True, pool=True )
- 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 )
- VEcopy = VCodec(label='Video Copy' , codec='vcopy', comm_str='-c:v copy', no_video_enc=True)
- VEnone = VCodec(label='No Video' , codec='none', comm_str='-vn', no_video_enc=True)
- # groups: ------------------------------
- VEall = (VEx264, VEx265, VEmpeg4, VEcopy, VEnone)
- #
- VEmp4 = (VEx265, VEx264, VEmpeg4, VEcopy, VEnone)
- VEmp4_default = VEmp4.index(VEx265)
- #
- VEavi = (VEmpeg4, VEcopy)
- VEavi_default = VEavi.index(VEmpeg4)
- #
- VEmka = (VEnone, VEnone) # min 2 obj for self.cboxtxt_change2()
- VEmka_default = 0
- ######################### OPTIONS ################################################
- class VcOptions(object):
- def __init__(self, label=None, comm_str=None, text_entry=False):
- self.label = label
- self.comm_str = comm_str
- self.text_entry = text_entry
- def __str__(self):
- return '{}, {}'.format(self.label, self.comm_str)
- class VcodecOptions():
- ### HEVC libx265 ############################################
- OPThevc1 = VcOptions(label='none (ssim psnr)', comm_str=':ssim=1:psnr=1')
- 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')
- OPThevc3 = VcOptions(label='db-3 no-sao', comm_str=':deblock=-3:no-sao=1:ssim=1:psnr=1')
- 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')
- 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')
- OPThevc6 = VcOptions(label='custom ->', text_entry=True)
- #
- OPTx265 = (OPThevc1, OPThevc2, OPThevc3, OPThevc4, OPThevc5, OPThevc6)
- OPTx265_default = OPTx265.index(OPThevc5)
- ### AVC libx264 #############################################
- OPTavc1 = VcOptions(label='opts 1', comm_str=' -x264opts ref=4:bframes=4:direct=auto:aq-strength=1.3:ssim:psnr')
- OPTavc2 = VcOptions(label='no opts (ssim)', comm_str=' -x264opts ssim')
- #
- OPTx264 = (OPTavc1, OPTavc2)
- OPTx264_default = OPTx264.index(OPTavc1)
- ########## PRESET # TUNE # OUT CONTAINER ##########################################
- class AVContainer(object):
- def __init__(self, label=None, cont=None, comm_str=None, ext=None, sub_stream=False, alist=None, vlist=None, audio_only=False):
- self.label = label
- self.cont = cont
- self.comm_str=comm_str
- self.ext = ext
- self.sub_stream = sub_stream
- self.alist = alist
- self.vlist = vlist
- self.audio_only = audio_only
- def __str__(self):
- return '{}, {}'.format(self.label, self.ext)
- class VideoRC(object):
- def __init__(self, label=None):
- self.label = label
- def __str__(self):
- return '{}'.format(self.label)
- class VcodecOther():
- ### OUT CONTAINER ############################
- CONTmkv = AVContainer(label='MKV', cont='mkv', comm_str='-f matroska', ext='.mkv', sub_stream=True, alist='mp4', vlist='mp4')
- CONTmp4 = AVContainer(label='MP4', cont='mp4', comm_str='-f mp4', ext='.mp4', alist='mp4', vlist='mp4')
- CONTavi = AVContainer(label='AVI', cont='avi', comm_str='-f avi', ext='.avi', alist='avi', vlist='avi')
- CONTmka = AVContainer(label='MKA', cont='mka', comm_str='-f matroska', ext='.mka', alist='mka', vlist='mka', audio_only=True)
- # group: ------------------------------
- OutContainers = (CONTmkv, CONTmp4, CONTavi, CONTmka)
- OutContainers_default = OutContainers.index(CONTmkv)
- ### VIDEO RATE CONTROL ################################
- VRCcrf = VideoRC(label='crf')
- VRCbr = VideoRC(label='bitrate kb/s')
- VRCq = VideoRC(label='qscale (1-31)')
- # groups: ------------------------------
- VRCall = (VRCcrf, VRCbr, VRCq)
- VRCx264 = (VRCcrf, VRCbr)
- VRCx265 = (VRCcrf, VRCbr)
- VRCmpeg4 = (VRCbr, VRCq)
- ### PRESET ################################
- x264_preset = [
- "ultrafast",
- "superfast",
- "veryfast",
- "faster",
- "fast",
- "medium",
- "slow",
- "veryslow"
- ]
- x264_preset_default = x264_preset.index('faster')
- x265_preset = x264_preset
- x265_preset_default = x265_preset.index('superfast')
- ### TUNE ###################################
- x264_tune = [
- "none",
- "film",
- "animation",
- "grain",
- "stillimage"
- ]
- x264_tune_default = x264_tune.index('film')
- x265_tune = [
- "none",
- "grain",
- "fastdecode",
- "zerolatency"
- ]
- x265_tune_default = x265_tune.index('none')
- ###############################################################################
- class ReuseInit(object):
- def make_label(self, text):
- label = Gtk.Label(text)
- label.set_use_underline(True)
- label.set_alignment(1.0, 0.5)
- label.show()
- return label
- def make_slider_and_spinner(self, init, min, max, step, page, digits):
- controls = {'adj':Gtk.Adjustment(init, min, max, step, page), 'slider':Gtk.HScale(), 'spinner':Gtk.SpinButton()}
- controls['slider'].set_adjustment(controls['adj'])
- controls['slider'].set_draw_value(False)
- controls['spinner'].set_adjustment(controls['adj'])
- controls['spinner'].set_digits(digits)
- controls['slider'].show()
- controls['spinner'].show()
- return controls
- def make_frame_ag(self, f_shadow_type, f_label, alig_pad, gri_row_sp, gri_colu_sp, gri_homog):
- controls = {'frame':Gtk.Frame(), 'ali':Gtk.Alignment(), 'grid':Gtk.Grid()}
- controls['frame'].set_shadow_type(f_shadow_type) # 3 GTK_SHADOW_ETCHED_IN , 1 GTK_SHADOW_IN
- controls['frame'].set_label(f_label)
- controls['ali'].set_padding(alig_pad, alig_pad, alig_pad, alig_pad)
- controls['frame'].add(controls['ali'])
- controls['grid'].set_row_spacing(gri_row_sp)
- controls['grid'].set_column_spacing(gri_colu_sp)
- controls['grid'].set_column_homogeneous(gri_homog) # True
- controls['ali'].add(controls['grid'])
- controls['frame'].show()
- controls['ali'].show()
- controls['grid'].show()
- return controls
- def make_spinbut(self, init, min, max, step, page, digits, numeric):
- controls = {'adj':Gtk.Adjustment(init, min, max, step, page), 'spinner':Gtk.SpinButton()}
- controls['spinner'].set_adjustment(controls['adj'])
- controls['spinner'].set_digits(digits)
- controls['spinner'].set_numeric(numeric)
- controls['spinner'].show()
- return controls
- def make_combobox(self, *vals):
- controls = {'list':Gtk.ListStore(str), 'cbox':Gtk.ComboBox(), 'cellr':Gtk.CellRendererText()}
- for i, v in enumerate(vals):
- controls['list'].append([v])
- controls['cbox'].set_model(controls['list'])
- controls['cbox'].pack_start(controls['cellr'], True)
- controls['cbox'].add_attribute(controls['cellr'], "text", 0)
- controls['cbox'].set_active(0)
- controls['cbox'].show()
- return controls
- def make_combobox_list(self, list):
- controls = {'list':Gtk.ListStore(str), 'cbox':Gtk.ComboBox(), 'cellr':Gtk.CellRendererText()}
- for i, v in enumerate(list):
- controls['list'].append([v])
- controls['cbox'].set_model(controls['list'])
- controls['cbox'].pack_start(controls['cellr'], True)
- controls['cbox'].add_attribute(controls['cellr'], "text", 0)
- controls['cbox'].set_active(0)
- controls['cbox'].show()
- return controls
- def make_comboboxtext(self, list):
- ### list = [str, str]
- comboboxtext = Gtk.ComboBoxText()
- for i, v in enumerate(list):
- comboboxtext.append_text(v)
- comboboxtext.set_active(0)
- return comboboxtext
- def make_comboboxtext2(self, list):
- ### list = (obj, obj) min. 2 obj w .label property
- comboboxtext = Gtk.ComboBoxText()
- for i, v in enumerate(list):
- comboboxtext.append_text(v.label)
- comboboxtext.set_active(0)
- return comboboxtext
- class MyUtility():
- def hms2sec(self, hms):
- result = 0
- listin = hms.split(':')
- listin.reverse()
- for i in range(len(listin)):
- if listin[i].isdigit():
- if i == 0:
- mult = 1
- if i == 1:
- mult = 60
- if i == 2:
- mult = 3600
- result += (int(listin[i])*mult)
- return result
- def sec2hms(self, seconds):
- seconds = float(seconds)
- h = int(seconds/3600)
- if (h > 0):
- seconds = seconds - (h * 3600)
- m = int(seconds / 60)
- s = int(seconds - (m * 60))
- hms = "{0:0=2d}:{1:0=2d}:{2:0=2d}".format(h,m,s)
- return hms
- def check_out_file(self):
- def check_codec_in_name(nameck):
- if not(Vars.XvCheck.no_video_enc): # no vcopy or vn
- if not(Vars.XvCheck.codec in nameck):
- clist = ('x265', 'x264', 'mpeg4', 'xvid', 'divx', 'XviD', 'DivX')
- for i in range(0,len(clist)):
- if clist[i] != Vars.XvCheck.codec:
- if clist[i] in nameck:
- nameck = nameck.replace(clist[i], Vars.XvCheck.codec)
- break
- if not(Vars.XvCheck.codec in nameck):
- nameck = nameck + '.' + Vars.XvCheck.codec
- return nameck
- name = os.path.splitext(Vars.basename)[0]
- name = check_codec_in_name(name)
- newname = Vars.outdir + '/' + name + Vars.ext
- if os.path.exists(newname):
- for i in range(2,20):
- newname = Vars.outdir + '/' + name + '._' + str(i) + '_' + Vars.ext
- if os.path.exists(newname) == False:
- break
- Vars.newname = newname
- self.f3_run_outdir_label.set_tooltip_text(Vars.newname)
- def humansize(self, namefile):
- try:
- nbytes = os.path.getsize(namefile)
- except:
- return '0'
- suffixes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
- if nbytes == 0: return '0 B'
- i = 0
- while nbytes >= 1024 and i < len(suffixes)-1:
- nbytes /= 1024.
- i += 1
- f = "{0:0.1f}".format(nbytes)
- return "{0:>5s} {1:2s}".format(f, suffixes[i])
- def version_from_filename(self):
- '''
- filename must be:
- 4FFmpeg-n.nnn.py
- '''
- try:
- #version = str(sys.argv[0])
- #version = os.path.basename(sys.argv[0])
- version = os.path.realpath(sys.argv[0]) # work w symlink
- version = os.path.basename(version)
- except:
- version = 'N/A'
- return version
- try:
- version = version.split('-')[1]
- except:
- version = 'N/A'
- return version
- if version[-3:] == ".py":
- try:
- version = version[:-3]
- except:
- version = 'N/A'
- return version
- return version
- def is_number(self, string):
- num_format = re.compile("^[\-]?[1-9][0-9]*\.?[0-9]+$")
- isnumber = re.match(num_format,string)
- return isnumber
- class UiElemController():
- def adj_change(self, adjustment, value, lower, upper , step_increment, page_increment):
- adjustment.set_value(value)
- adjustment.set_lower(lower)
- adjustment.set_upper(upper)
- adjustment.set_step_increment(step_increment)
- adjustment.set_page_increment(page_increment)
- #adjustment.set_page_size(page_size)
- def adj_change2(self, adjustment, tuple_5values):
- '''
- tuple_5values=
- (value , lower, upper, step_increment, page_increment)
- or
- [value , lower, upper, step_increment, page_increment]
- '''
- adjustment.set_value(tuple_5values[0])
- adjustment.set_lower(tuple_5values[1])
- adjustment.set_upper(tuple_5values[2])
- adjustment.set_step_increment(tuple_5values[3])
- adjustment.set_page_increment(tuple_5values[4])
- #adjustment.set_page_size(page_size)
- def cboxtxt_change(self, the_cboxtext, the_function, item_list, item_selected, global_list, list_in_use):
- ### item_list = [str, str]
- the_cboxtext.disconnect_by_func(the_function)
- the_cboxtext.remove_all()
- for i, v in enumerate(item_list):
- the_cboxtext.append_text(v)
- the_cboxtext.connect("changed", the_function)
- the_cboxtext.set_active(item_selected)
- objname = global_list.split('.')[0]
- glist = global_list.split('.')[1]
- setattr(globals()[objname], glist, list_in_use)
- def cboxtxt_change2(self, the_cboxtext, the_function, obj_list, item_selected, global_list, list_in_use):
- ### obj_list = (obj, obj) min. 2 obj w .label property
- the_cboxtext.disconnect_by_func(the_function)
- the_cboxtext.remove_all()
- for i, v in enumerate(obj_list):
- the_cboxtext.append_text(v.label)
- the_cboxtext.connect("changed", the_function)
- the_cboxtext.set_active(item_selected)
- objname = global_list.split('.')[0]
- glist = global_list.split('.')[1]
- setattr(globals()[objname], glist, list_in_use)
- # old way ------------------------------------------------------------
- #def x265_opt_list(self, selected):
- # self.box_3v_x264opts.disconnect_by_func(self.on_codec_clicked)
- # self.box_3v_x264opts.remove_all()
- # for i, v in enumerate(Vars.x265_opt):
- # self.box_3v_x264opts.append_text(v)
- # self.box_3v_x264opts.set_active(selected)
- # self.box_3v_x264opts.connect("changed", self.on_codec_clicked)
- # Vars.opt_list = 'x265'
- #### MAIN #################################################################################################
- class ProgrammaGTK(ReuseInit, UiElemController, MyUtility, AudioEncoder, VideoEncoder, VcodecOptions, VcodecOther):
- ## version ---------------------------------
- #Vars.version = '8.166s'
- ## -----------------------------------------
- def __init__(self):
- # initialize variables
- if Vars.version == '':
- Vars.version = self.version_from_filename()
- self.make_ui()
- Vars.outdir = os.getcwd()
- Vars.indir = Vars.outdir
- self.on_codec_audio_changed(0)
- self.on_codec_video_changed(0)
- self.on_f3_other_clicked(0)
- self.on_container_changed(0)
- if len(sys.argv) == 2:
- try:
- Vars.filename = str(sys.argv[1])
- self.file_changed()
- except:
- pass
- # ----------------------------
- def make_ui(self):
- # ---------------------
- self.window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
- self.window.connect("destroy", self.on_window_destroy)
- self.window.set_title("4FFmpeg")
- self.window.set_position(1) # 1 center, 0 none,
- self.window.set_border_width(3)
- self.window.set_default_size(500,-1)
- #----------------------------------
- #page1 stuff VIDEO FILTERS------------------------------------------
- # page1 VBox -------------------------
- self.vbox1 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
- #self.vbox1.set_orientation(Gtk.Orientation.VERTICAL) # Gtk.Orientation.HORIZONTAL
- #self.vbox1.set_spacing(2)
- # map --------------------------------------
- self.make_map()
- # add map frame
- self.vbox1.pack_start(self.f_map['frame'], 1, 0, 0)
- #time cut ------------------------------------
- self.make_time_cut()
- # add time frame
- self.vbox1.pack_start(self.f_time['frame'], 1, 0, 0)
- # deinterlace -----------------------
- self.make_deinterlace()
- # add deinterlace frame
- self.vbox1.pack_start(self.f_deint['frame'], 1, 0, 0)
- # crop ----------------------------------------
- self.make_crop()
- # add crop frame -------------------
- self.vbox1.pack_start(self.frame_crop['frame'], 1, 0, 0)
- # scale ------------------------------
- self.make_scale()
- # add scale frame------------------
- self.vbox1.pack_start(self.frame_scale['frame'], 1, 0, 0)
- # denoise ----------------------------
- self.make_denoise()
- # add denoise frame------------------------
- self.vbox1.pack_start(self.frame_dn['frame'], 1, 0, 0)
- # page 1 filters------------------------
- self.frame_out = self.make_frame_ag(3, ' FFmpeg video filter string: ' , 12, 8, 8, True)
- self.labelout = Gtk.Label("")
- self.labelout.set_selectable(1)
- self.labelout.set_width_chars(120)
- self.labelout.set_max_width_chars(130)
- self.labelout.set_line_wrap(True)
- self.frame_out['grid'].attach(self.labelout, 0, 0, 1 ,1)
- # add output frame ---------------------
- self.vbox1.pack_start(self.frame_out['frame'], 1, 0, 0)
- # end page1
- # page2 stuff UTILITY ------------------------------------------
- # page2 VBox -------------------------
- self.vbox_pg2 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
- #volumedetect ------------------------------------
- self.make_volume_det()
- # add volumedetect frame
- self.vbox_pg2.pack_start(self.f_volume_det['frame'], 1, 0, 0)
- #frames detect
- self.make_frames_det()
- # add frames detect frame
- self.vbox_pg2.pack_start(self.f_frames_det['frame'], 1, 0, 0)
- #drc ------------------------------------
- self.make_volume_drc()
- # add volumedetect frame
- self.vbox_pg2.pack_start(self.f_volume_drc['frame'], 1, 0, 0)
- #compand ---------------------------------------
- self.make_compand()
- # add frame
- self.vbox_pg2.pack_start(self.f_compand['frame'], 1, 0, 0)
- #dynaudnorm-------------------
- self.make_dynaudnorm()
- # add frame
- self.vbox_pg2.pack_start(self.f_dynaudnorm['frame'], 1, 0, 0)
- # black detect ----------------------------------
- self.make_black_detect()
- # add black_detect frame
- self.vbox_pg2.pack_start(self.f_blackd['frame'], 1, 0, 0)
- # info frame----------------------
- self.make_info_frame()
- # add info frame
- self.vbox_pg2.pack_start(self.f_info['frame'], 1, 0, 0)
- # end page2 stuff
- # page 3 stuff ffmpeg commands -----------------------------------------
- # page3 VBox -------------------------
- self.vbox_pg3 = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
- # audio codec -------------------
- self.make_audio_codec()
- #add frame audio codec
- self.vbox_pg3.pack_start(self.f_3acodec['frame'], 1, 0, 0)
- # video codec -------------------
- self.make_video_codec()
- #add frame video codec
- self.vbox_pg3.pack_start(self.f_3vcodec['frame'], 1, 0, 0)
- # other options ----------------
- self.make_other_opts()
- #add frame other options
- self.vbox_pg3.pack_start(self.f3_oth['frame'], 1, 0, 0)
- # page3 output ---------------------
- self.f3_out = self.make_frame_ag(3, " FFmpeg command " , 6, 8, 8, True)
- self.f3_out_label = Gtk.Label("")
- self.f3_out_label.set_width_chars(106)
- self.f3_out_label.set_max_width_chars(106)
- self.f3_out_label.set_line_wrap(True)
- self.f3_out_label.set_selectable(1)
- self.f3_out['grid'].attach(self.f3_out_label, 0, 0, 1, 1)
- # add frame page3 output
- self.vbox_pg3.pack_start(self.f3_out['frame'], 1, 0, 0)
- # run ffmpeg ---------------------------------
- self.make_run_ffmpeg()
- # add frame run ffmpeg
- self.vbox_pg3.pack_start(self.f3_run['frame'], 1, 0, 0)
- #---------------------------------------------------
- # main vbox
- self.main_vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
- # notebook
- self.notebook = Gtk.Notebook()
- self.notebook.set_tab_pos(Gtk.PositionType.TOP) #GTK_POS_LEFT = 0
- self.notebook.set_show_border (False)
- self.main_vbox.pack_start(self.notebook, 1, 0, 0)
- #page 1
- self.tab1label = Gtk.Label("Video filters")
- self.page1_ali = Gtk.Alignment()
- self.page1_ali.set_padding(0, 6, 6, 6)
- self.page1_ali.add(self.vbox1)
- self.notebook.append_page(self.page1_ali, self.tab1label)
- #page 2
- self.tab2label = Gtk.Label("Utility")
- self.page2_ali = Gtk.Alignment()
- self.page2_ali.set_padding(0, 6, 6, 6)
- self.page2_ali.add(self.vbox_pg2)
- self.notebook.append_page(self.page2_ali, self.tab2label)
- #page 3
- self.tab3label = Gtk.Label("Encode")
- self.page3_ali = Gtk.Alignment()
- self.page3_ali.set_padding(0, 6, 6, 6)
- self.page3_ali.add(self.vbox_pg3)
- self.notebook.append_page(self.page3_ali, self.tab3label)
- #---------------------------------------------------
- # low part BUTTONS AND TERM --------------------------
- self.make_low_part()
- # add low part-----------------
- self.main_vbox.pack_start(self.gridterm, 1, 1, 0)
- #---------------------------------------------------------
- self.window.add (self.main_vbox)
- #---------------------------------
- self.window.show_all()
- def make_deinterlace(self):
- self.f_deint = self.make_frame_ag(3, "" , 6, 8, 8, True)
- self.checkdeint = Gtk.CheckButton("deinterlace")
- self.checkdeint.connect("toggled", self.on_deint_clicked)
- self.f_deint['grid'].attach(self.checkdeint, 0, 0, 1, 1)
- self.box_deint = self.make_combobox(
- "yadif",
- "postprocessing linear blend",
- "detect (use only with Test)"
- )
- self.f_deint['grid'].attach(self.box_deint['cbox'], 1, 0, 1, 1)
- self.box_deint['cbox'].connect("changed", self.on_deint_clicked)
- #
- self.f_deint['grid'].attach(self.make_label(""), 2, 0, 1, 1)
- def make_map(self):
- #
- self.f_map = self.make_frame_ag(3, "" , 6, 8, 8, False)
- #
- self.check_map = Gtk.CheckButton("map")
- self.check_map.connect("toggled", self.on_map_clicked) # toggled or activate (enter)
- self.f_map['grid'].attach(self.check_map, 0, 0, 1, 1)
- #
- self.mapstream_label = self.make_label("streams: ")
- self.f_map['grid'].attach(self.mapstream_label, 1, 0, 1, 1)
- #
- self.entry_map = Gtk.Entry()
- self.entry_map.set_tooltip_text(Tips.map_tooltip_str)
- self.entry_map.connect("changed", self.on_map_clicked)
- self.f_map['grid'].attach(self.entry_map, 2, 0, 1, 1)
- #
- self.map_label = Gtk.Label("")
- self.map_label.set_width_chars(70)
- self.f_map['grid'].attach(self.map_label, 3, 0, 2, 1)
- # placeholder
- self.f_map['grid'].attach(self.make_label("Version: " + Vars.version + " "), 5, 0, 1, 1)
- def make_time_cut(self):
- #
- self.f_time = self.make_frame_ag(3, "" , 6, 8, 8, True)
- #
- self.check_time = Gtk.CheckButton("time")
- self.check_time.connect("toggled", self.on_time_clicked) # toggled or activate (enter)
- self.f_time['grid'].attach(self.check_time, 0, 0, 1, 1)
- #
- self.label_time_in = self.make_label("from: ")
- self.f_time['grid'].attach(self.label_time_in, 1, 0, 1, 1)
- self.entry_timein = Gtk.Entry()
- self.entry_timein.set_tooltip_text(Tips.time_tooltip_str)
- self.entry_timein.set_max_length(12)
- self.entry_timein.set_max_width_chars(12)
- self.entry_timein.set_width_chars(12)
- #self.entry_timein.set_halign(1)
- self.entry_timein.connect("changed", self.on_time_clicked)
- self.f_time['grid'].attach(self.entry_timein, 2, 0, 1, 1)
- self.label_time_out = self.make_label("to: ")
- self.f_time['grid'].attach(self.label_time_out, 3, 0, 1, 1)
- self.entry_timeout = Gtk.Entry()
- self.entry_timeout.set_tooltip_text(Tips.time_tooltip_str)
- self.entry_timeout.set_max_length(12)
- self.entry_timeout.set_max_width_chars(12)
- self.entry_timeout.set_width_chars(12)
- self.entry_timeout.connect("changed", self.on_time_clicked)
- self.f_time['grid'].attach(self.entry_timeout, 4, 0, 1, 1)
- self.time_label = Gtk.Label('')
- self.f_time['grid'].attach(self.time_label, 5, 0, 2, 1)
- def make_scale(self):
- self.frame_scale = self.make_frame_ag(3, ' scale ' , 6, 8, 8, False)
- # ------------------------------
- self.box_scale_side = self.make_combobox(
- "None",
- "W",
- "H"
- )
- self.box_scale_side['cbox'].set_size_request(180,-1)
- self.frame_scale['grid'].attach(self.box_scale_side['cbox'], 0, 0, 1, 1)
- self.box_scale_side['cbox'].connect("changed", self.on_scale_clicked)
- #------------------------------------
- self.box_scale_ar = self.make_combobox(
- "16/9",
- "4/3",
- "2.35/1"
- )
- self.frame_scale['grid'].attach(self.box_scale_ar['cbox'], 0, 1, 1, 1)
- self.box_scale_ar['cbox'].connect("changed", self.on_scale_clicked)
- #-----------------------------------------
- self.size_spinner = self.make_slider_and_spinner(720, 200, 2000, 8, 32, 0)
- self.frame_scale['grid'].attach(self.size_spinner['slider'], 1, 0, 1, 1)
- self.frame_scale['grid'].attach(self.size_spinner['spinner'], 2, 0, 1, 1)
- self.size_spinner['slider'].set_size_request(200,-1)
- self.size_spinner['adj'].set_value(720.001) #mettere decimali se no non si vede
- self.size_spinner['adj'].connect("value-changed", self.on_scale_clicked)
- #-------------------------------------------------------
- self.check_round = Gtk.CheckButton("round 8")
- self.check_round.connect("toggled", self.on_scale_clicked)
- self.frame_scale['grid'].attach(self.check_round, 1, 1, 1, 1)
- #
- self.check = Gtk.CheckButton("zscale")
- self.check.set_tooltip_text(" HQ resize with libzimg ")
- self.check.connect("toggled", self.on_scale_clicked)
- self.frame_scale['grid'].attach(self.check, 2, 1, 1, 1)
- #custom scale string
- self.label_scalecustom = self.make_label("Custom scale filter (override all scale settings):")
- self.label_scalecustom.set_alignment(0.5, 0.5)
- self.frame_scale['grid'].attach(self.label_scalecustom, 3, 0, 1, 1)
- self.entry_scalecustom = Gtk.Entry()
- self.entry_scalecustom.set_tooltip_text(Tips.customscale_str)
- self.entry_scalecustom.connect("changed", self.on_scale_clicked)
- self.entry_scalecustom.set_max_length(100)
- self.entry_scalecustom.set_max_width_chars(60)
- self.frame_scale['grid'].attach(self.entry_scalecustom, 3, 1, 1, 1)
- def make_crop(self):
- self.frame_crop = self.make_frame_ag(3, '' , 6, 2, 0, True)
- # -------
- self.checkcr = Gtk.CheckButton("crop")
- self.checkcr.connect("toggled", self.on_crop_clicked)
- self.frame_crop['grid'].attach(self.checkcr, 0, 0, 1, 1)
- #----------
- self.butcrode = Gtk.Button(label="Crop detect")
- self.butcrode.connect("clicked", self.on_butcrode_clicked)
- self.butcrode.set_sensitive(False)
- self.frame_crop['grid'].attach(self.butcrode, 0, 1, 1, 1)
- #-----------
- self.labelcropinw = self.make_label("input W: ")
- self.frame_crop['grid'].attach(self.labelcropinw, 1, 0, 1, 1)
- self.labelcropinh = self.make_label("input H: ")
- self.frame_crop['grid'].attach(self.labelcropinh, 1, 1, 1, 1)
- #
- self.spincw = self.make_spinbut(640 , 100 , 1920 , 10 , 1 , 0, True )
- self.spincw["adj"].connect("value-changed", self.on_crop_clicked)
- self.frame_crop['grid'].attach(self.spincw["spinner"], 2, 0, 1, 1)
- #
- self.spinch = self.make_spinbut(480 , 100 , 1280 , 10 , 1 , 0, True )
- self.spinch["adj"].connect("value-changed", self.on_crop_clicked)
- self.frame_crop['grid'].attach(self.spinch["spinner"], 2, 1, 1, 1)
- #
- self.labelcroptop = self.make_label("crop Top: ")
- self.frame_crop['grid'].attach(self.labelcroptop, 3, 0, 1, 1)
- self.labelcropbot = self.make_label("crop Bottom: ")
- self.frame_crop['grid'].attach(self.labelcropbot, 3, 1, 1, 1)
- #
- self.spinct = self.make_spinbut(0 , 0 , 600 , 1 , 10 , 0, True )
- self.spinct["adj"].connect("value-changed", self.on_crop_clicked)
- self.frame_crop['grid'].attach(self.spinct["spinner"], 4, 0, 1, 1)
- #
- self.spincb = self.make_spinbut(0 , 0 , 600 , 1 , 10 , 0, True )
- self.spincb["adj"].connect("value-changed", self.on_crop_clicked)
- self.frame_crop['grid'].attach(self.spincb["spinner"], 4, 1, 1, 1)
- #
- self.labelcroplef = self.make_label("crop Left: ")
- self.frame_crop['grid'].attach(self.labelcroplef, 5, 0, 1, 1)
- self.labelcroprig = self.make_label("crop Right: ")
- self.frame_crop['grid'].attach(self.labelcroprig, 5, 1, 1, 1)
- #
- self.spincl = self.make_spinbut(0 , 0 , 600 , 1 , 10 , 0, True )
- self.spincl["adj"].connect("value-changed", self.on_crop_clicked)
- self.frame_crop['grid'].attach(self.spincl["spinner"], 6, 0, 1, 1)
- #
- self.spincr = self.make_spinbut(0 , 0 , 600 , 1 , 10 , 0, True )
- self.spincr["adj"].connect("value-changed", self.on_crop_clicked)
- self.frame_crop['grid'].attach(self.spincr["spinner"], 6, 1, 1, 1)
- def make_denoise(self):
- self.frame_dn = self.make_frame_ag(3, ' denoise / unsharp luma chroma / frame rate ' , 6, 8, 8, True)
- # denoise ----------------------
- self.checkdn = Gtk.CheckButton("hqdn3d:")
- self.checkdn.set_alignment(1.0, 0.5)
- self.checkdn.set_halign(2)
- self.checkdn.connect("toggled", self.on_dn_clicked)
- self.frame_dn['grid'].attach(self.checkdn, 0, 0, 1, 1)
- #
- self.spindn = self.make_spinbut(4 , 2 , 8 , 1 , 10 , 0, True )
- self.spindn["adj"].connect("value-changed", self.on_dn_clicked)
- #self.spindn['spinner'].set_max_length(1)
- #self.spindn['spinner'].set_width_chars(1)
- self.frame_dn['grid'].attach(self.spindn["spinner"], 1, 0, 1, 1)
- # -----------------------
- # unsharp unsharp=5:5:luma:5:5:chroma, luma chroma -1.5 to 1.5
- self.checkuns = Gtk.CheckButton("unsharp l/c:")
- self.checkuns.set_alignment(1.0, 0.5)
- self.checkuns.set_halign(2)
- self.checkuns.connect("toggled", self.on_uns_clicked)
- self.frame_dn['grid'].attach(self.checkuns, 2, 0, 1, 1)
- self.spinunsl = self.make_spinbut(0.0 , -1.5 , 1.5 , .1 , .01 , 2, True )
- self.spinunsl["adj"].connect("value-changed", self.on_uns_clicked)
- self.frame_dn['grid'].attach(self.spinunsl["spinner"], 3, 0, 1, 1)
- self.spinunsc = self.make_spinbut(0.0 , -1.5 , 1.5 , .1 , .01 , 2, True )
- self.spinunsc["adj"].connect("value-changed", self.on_uns_clicked)
- self.frame_dn['grid'].attach(self.spinunsc["spinner"], 4, 0, 1, 1)
- # framerate --------------------------
- self.checkfr = Gtk.CheckButton("frame rate:")
- self.checkfr.set_alignment(1.0, 0.5)
- self.checkfr.set_halign(2)
- self.checkfr.connect("toggled", self.on_fr_clicked)
- self.frame_dn['grid'].attach(self.checkfr, 5, 0, 1, 1)
- self.spinfr = self.make_spinbut(0 , 0 , 100 , 1 , 10 , 2, True )
- self.spinfr["adj"].connect("value-changed", self.on_fr_clicked)
- self.frame_dn['grid'].attach(self.spinfr["spinner"], 6, 0, 1, 1)
- def make_low_part(self):
- # grid
- self.gridterm = Gtk.Grid()
- self.gridterm.set_row_spacing(2)
- self.gridterm.set_column_spacing(2)
- self.gridterm.set_column_homogeneous(True) # True
- # filechooserbutton
- self.but_file = Gtk.Button("Choose File")
- self.but_file.connect("clicked", self.on_but_file)
- self.but_file.set_tooltip_text(Tips.but_file_str)
- #ff command button
- self.butplay = Gtk.Button(label="FFplay")
- self.butplay.connect("clicked", self.on_butplay_clicked)
- self.butplay.set_sensitive(False)
- self.butplay.set_tooltip_text(Tips.ffplay_tooltip_str)
- #
- self.butprobe = Gtk.Button(label="FFprobe")
- self.butprobe.connect("clicked", self.on_butprobe_clicked)
- self.butprobe.set_sensitive(False)
- #
- self.buttest = Gtk.Button(label="Test")
- self.buttest.connect("clicked", self.on_buttest_clicked)
- self.buttest.set_sensitive(False)
- #
- self.buttestspl = Gtk.Button(label="Test split")
- self.buttestspl.connect("clicked", self.on_buttestspl_clicked)
- self.buttestspl.set_sensitive(False)
- # copy term button
- self.butt_vtecopy = Gtk.Button(label="Copy term")
- self.butt_vtecopy.connect("clicked", self.on_butt_vtecopy_clicked)
- # vte terminal
- self.terminal = Vte.Terminal()
- try: # vte 2.90
- self.terminal.fork_command_full(
- Vte.PtyFlags.DEFAULT, #default is fine
- os.getcwd(), #where to start the command? os.environ['HOME']
- ["/bin/sh"], #where is the emulator?
- [], #it's ok to leave this list empty
- GLib.SpawnFlags.DO_NOT_REAP_CHILD,
- None, #at least None is required
- None,
- )
- except: # vte 2.91
- self.terminal.spawn_sync(
- Vte.PtyFlags.DEFAULT, #default is fine
- os.getcwd(), #where to start the command? os.environ['HOME']
- ["/bin/sh"], #where is the emulator?
- [], #it's ok to leave this list empty
- GLib.SpawnFlags.DO_NOT_REAP_CHILD,
- None, #at least None is required
- None,
- )
- # scroller
- self.scroller = Gtk.ScrolledWindow()
- self.scroller.set_hexpand(True)
- self.scroller.set_vexpand(True)
- self.scroller.set_min_content_height(90)
- self.scroller.add(self.terminal)
- # attach to grid
- self.gridterm.attach(self.but_file, 0, 0, 2, 1)
- self.gridterm.attach(self.butprobe, 2, 0, 1, 1)
- self.gridterm.attach(self.butplay, 3, 0, 1, 1)
- self.gridterm.attach(self.buttest, 4, 0, 1, 1)
- self.gridterm.attach(self.buttestspl, 5, 0, 1, 1)
- self.gridterm.attach(self.butt_vtecopy, 6, 0, 1, 1)
- self.gridterm.attach(self.scroller, 0, 1, 7, 1)
- def make_volume_det(self):
- self.f_volume_det = self.make_frame_ag(3, "" , 6, 8, 8, True)
- #
- self.but_volume_det = Gtk.Button(label="Volume detect")
- self.but_volume_det.connect("clicked", self.on_but_volume_det_clicked)
- self.f_volume_det['grid'].attach(self.but_volume_det, 0, 0, 1, 1)
- self.but_volume_det.set_sensitive(False)
- #
- self.voldet_spin = Gtk.Spinner()
- self.voldet_spin.set_sensitive(False)
- self.f_volume_det['grid'].attach(self.voldet_spin, 1, 0, 1, 1)
- #
- self.label_maxvol = Gtk.Label("")
- self.f_volume_det['grid'].attach(self.label_maxvol, 2, 0, 1, 1)
- self.label_meanvol = Gtk.Label("")
- self.f_volume_det['grid'].attach(self.label_meanvol, 3, 0, 1, 1)
- #
- self.check_vol = Gtk.CheckButton("volume")
- self.check_vol.connect("toggled", self.on_volume_clicked)
- self.f_volume_det['grid'].attach(self.check_vol, 0, 1, 1, 1)
- #
- self.label_db = self.make_label("dB: ")
- self.f_volume_det['grid'].attach(self.label_db, 1, 1, 1, 1)
- self.spin_db = self.make_spinbut(0 , -6 , 20 , 0.1 , 1 , 2, True )
- self.spin_db["adj"].connect("value-changed", self.on_volume_clicked)
- self.f_volume_det['grid'].attach(self.spin_db["spinner"], 2, 1, 1, 1)
- self.label_ratio = self.make_label("ratio: ")
- self.f_volume_det['grid'].attach(self.label_ratio, 3, 1, 1, 1)
- self.label_ratio_val = Gtk.Label("1")
- self.f_volume_det['grid'].attach(self.label_ratio_val, 4, 1, 1, 1)
- def make_frames_det(self):
- self.f_frames_det = self.make_frame_ag(3, "" , 6, 8, 8, True)
- #
- self.but_frames_det = Gtk.Button(label="Total frames detect")
- self.but_frames_det.connect("clicked", self.on_but_frames_det_clicked)
- self.f_frames_det['grid'].attach(self.but_frames_det, 0, 0, 1, 1)
- self.but_frames_det.set_sensitive(False)
- #
- self.framesdet_spin = Gtk.Spinner()
- self.framesdet_spin.set_sensitive(False)
- self.f_frames_det['grid'].attach(self.framesdet_spin, 1, 0, 1, 1)
- #
- self.label_framesdet = Gtk.Label("N/A")
- self.f_frames_det['grid'].attach(self.label_framesdet, 2, 0, 1, 1)
- self.label_framesdet.set_selectable(True)
- #
- #placeholder
- #self.f_frames_det['grid'].attach(Gtk.Label(''), 3, 0, 2, 1)
- ###
- self.entry_time2frame = Gtk.Entry()
- self.entry_time2frame.set_tooltip_text(Tips.time2frame_str)
- self.entry_time2frame.set_max_length(12)
- self.entry_time2frame.set_max_width_chars(12)
- self.entry_time2frame.set_width_chars(12)
- self.entry_time2frame.connect("changed", self.on_time2frame_clicked)
- self.f_frames_det['grid'].attach(self.entry_time2frame, 3, 0, 1, 1)
- self.label_time2frame = Gtk.Label('')
- self.label_time2frame.set_selectable(True)
- self.label_time2frame.set_tooltip_text(" calculated frames ")
- self.f_frames_det['grid'].attach(self.label_time2frame, 4, 0, 2, 1)
- def make_volume_drc(self):
- self.f_volume_drc = self.make_frame_ag(3, "" , 6, 8, 8, True)
- self.check_drc = Gtk.CheckButton("ac3 input drc scale")
- self.check_drc.connect("toggled", self.on_drc_clicked)
- self.f_volume_drc['grid'].attach(self.check_drc, 0, 0, 1, 1)
- self.check_drc.set_sensitive(False)
- #
- self.spin_drc = self.make_spinbut(1 , 0 , 6 , 1 , 1 , 0, True )
- self.spin_drc["adj"].connect("value-changed", self.on_drc_clicked)
- self.spin_drc['spinner'].set_tooltip_text(Tips.drc_str)
- self.f_volume_drc['grid'].attach(self.spin_drc["spinner"], 1, 0, 1, 1)
- self.spin_drc["spinner"].set_sensitive(False)
- #
- #placeholder
- self.f_volume_drc['grid'].attach(Gtk.Label(''), 2, 0, 3, 1)
- def make_compand(self):
- #
- self.f_compand = self.make_frame_ag(3, "" , 6, 8, 8, False)
- #
- self.check_compand = Gtk.CheckButton("compand")
- self.check_compand.connect("toggled", self.on_compand_clicked)
- self.f_compand['grid'].attach(self.check_compand, 0, 0, 1, 1)
- #
- self.entry_compand = Gtk.Entry()
- self.entry_compand.set_text(Vars.compinit)
- self.entry_compand.set_width_chars(60)
- self.entry_compand.connect("changed", self.on_compand_clicked)
- self.entry_compand.set_tooltip_text(Tips.compad_str)
- self.f_compand['grid'].attach(self.entry_compand, 1, 0, 2, 1)
- #
- self.compand_reset = Gtk.Button(label="reset")
- self.compand_reset.set_size_request(110,-1)
- self.compand_reset.connect("clicked", self.on_compand_reset)
- self.f_compand['grid'].attach(self.compand_reset, 3, 0, 1, 1)
- self.compand_test = Gtk.Button(label="test ebur128")
- self.compand_test.set_size_request(110,-1)
- self.compand_test.set_sensitive(False)
- self.compand_test.connect("clicked", self.on_compand_test)
- self.f_compand['grid'].attach(self.compand_test, 4, 0, 1, 1)
- self.compand_volume = Gtk.Button(label="test volume")
- self.compand_volume.set_size_request(110,-1)
- self.compand_volume.set_sensitive(False)
- self.compand_volume.connect("clicked", self.on_compand_volume)
- self.f_compand['grid'].attach(self.compand_volume, 5, 0, 1, 1)
- def make_dynaudnorm(self):
- #
- self.f_dynaudnorm = self.make_frame_ag(3, "" , 6, 8, 8, False)
- #
- self.check_dynaudnorm = Gtk.CheckButton("dynaudnorm")
- self.check_dynaudnorm.connect("toggled", self.on_dynaudnorm_clicked)
- self.f_dynaudnorm['grid'].attach(self.check_dynaudnorm, 0, 0, 1, 1)
- #
- self.entry_dynaudnorm = Gtk.Entry()
- self.entry_dynaudnorm.set_text(Vars.dynaudnorm)
- self.entry_dynaudnorm.set_width_chars(57)
- self.entry_dynaudnorm.connect("changed", self.on_dynaudnorm_clicked)
- self.entry_dynaudnorm.set_tooltip_text(Tips.dynaudnorm_str)
- self.f_dynaudnorm['grid'].attach(self.entry_dynaudnorm, 1, 0, 2, 1)
- #
- self.compand_dynaudnorm = Gtk.Button(label="reset")
- self.compand_dynaudnorm.set_size_request(110,-1)
- self.compand_dynaudnorm.connect("clicked", self.on_dynaudnorm_reset)
- self.f_dynaudnorm['grid'].attach(self.compand_dynaudnorm, 3, 0, 1, 1)
- self.dynaudnorm_test = Gtk.Button(label="test ebur128")
- self.dynaudnorm_test.set_size_request(110,-1)
- self.dynaudnorm_test.set_sensitive(False)
- self.dynaudnorm_test.connect("clicked", self.on_dynaudnorm_test)
- self.f_dynaudnorm['grid'].attach(self.dynaudnorm_test, 4, 0, 1, 1)
- self.dynaudnorm_volume = Gtk.Button(label="test volume")
- self.dynaudnorm_volume.set_size_request(110,-1)
- self.dynaudnorm_volume.set_sensitive(False)
- self.dynaudnorm_volume.connect("clicked", self.on_dynaudnorm_volume)
- self.f_dynaudnorm['grid'].attach(self.dynaudnorm_volume, 5, 0, 1, 1)
- def make_black_detect(self):
- self.f_blackd = self.make_frame_ag(3, "" , 6, 8, 8, True)
- #
- self.but_black_det = Gtk.Button(label="Black detect")
- self.but_black_det.connect("clicked", self.on_but_black_det_clicked)
- self.but_black_det.set_sensitive(False)
- self.f_blackd['grid'].attach(self.but_black_det, 0, 0, 1, 1)
- #
- self.blackdet_spin = Gtk.Spinner()
- self.blackdet_spin.set_sensitive(False)
- self.f_blackd['grid'].attach(self.blackdet_spin, 1, 0, 1, 1)
- #
- scrolledwindow = Gtk.ScrolledWindow()
- #scrolledwindow.set_hexpand(True)
- scrolledwindow.set_vexpand(True)
- scrolledwindow.set_min_content_height(60)
- self.textview = Gtk.TextView()
- self.textbuffer = self.textview.get_buffer()
- self.textview.set_editable(False)
- self.textview.set_cursor_visible(False)
- self.textview.modify_font(Pango.font_description_from_string('Monospace 9'))
- scrolledwindow.add(self.textview)
- self.textbuffer.set_text(Tips.black_dt_init_str)
- self.f_blackd['grid'].attach(scrolledwindow, 2, 0, 3, 3)
- #
- self.progressbar_black_det = Gtk.ProgressBar()
- self.f_blackd['grid'].attach(self.progressbar_black_det, 0, 1, 1, 1)
- def make_info_frame(self):
- self.f_info = self.make_frame_ag(3, " info " , 6, 8, 8, True)
- scrolledwindow1 = Gtk.ScrolledWindow()
- scrolledwindow1.set_hexpand(True)
- scrolledwindow1.set_vexpand(True)
- scrolledwindow1.set_min_content_height(50)
- self.textview_info = Gtk.TextView()
- self.textbuffer_info = self.textview_info.get_buffer()
- self.textview_info.set_editable(False)
- self.textview_info.set_cursor_visible(False)
- self.textview_info.modify_font(Pango.font_description_from_string('Monospace 9'))
- scrolledwindow1.add(self.textview_info)
- self.f_info['grid'].attach(scrolledwindow1, 0, 0, 3, 3)
- def make_audio_codec(self):
- #
- self.f_3acodec = self.make_frame_ag(3, " audio codec " , 6, 8, 8, False)
- #
- self.box_ac = self.make_comboboxtext2(AudioEncoder.AEmp4)
- self.box_ac.set_active(AudioEncoder.AEmp4_default)
- self.f_3acodec['grid'].attach(self.box_ac, 0, 0, 1, 1)
- self.box_ac.connect("changed", self.on_codec_audio_changed)
- #
- self.spin_ac = self.make_spinbut(100 , 80 , 160 , 10 , 1 , 0, True )
- self.spin_ac["adj"].connect("value-changed", self.on_audio_clicked)
- self.f_3acodec['grid'].attach(self.spin_ac["spinner"], 1, 0, 1, 1)
- #
- label = self.make_label('sample: ')
- self.f_3acodec['grid'].attach(label, 3, 0, 1, 1)
- self.box_audio_rate = self.make_comboboxtext(AudioEncoder.AEaudio_sample)
- self.box_audio_rate.set_tooltip_text(Tips.audio_samp_str)
- self.box_audio_rate.connect("changed", self.on_codec_audio_changed)
- self.f_3acodec['grid'].attach(self.box_audio_rate, 4, 0, 1, 1)
- #
- self.check_soxr = Gtk.CheckButton("soxr")
- self.check_soxr.set_tooltip_text(' use SoX Resampler (libsoxr) ')
- self.check_soxr.set_active(False)
- self.check_soxr.set_sensitive(False)
- self.check_soxr.connect("toggled", self.on_codec_audio_changed)
- self.f_3acodec['grid'].attach(self.check_soxr, 5, 0, 1, 1)
- #
- #
- label = self.make_label('ch: ')
- self.f_3acodec['grid'].attach(label, 6, 0, 1, 1)
- self.box_audio_ch = self.make_comboboxtext(AudioEncoder.AEaudio_channels)
- self.box_audio_ch.set_tooltip_text(Tips.audio_channels_str)
- self.box_audio_ch.connect("changed", self.on_codec_audio_changed)
- self.f_3acodec['grid'].attach(self.box_audio_ch, 7, 0, 1, 1)
- self.check_prologic = Gtk.CheckButton("prologic2")
- self.check_prologic.set_sensitive(False)
- self.check_prologic.connect("toggled", self.on_codec_audio_changed)
- self.f_3acodec['grid'].attach(self.check_prologic, 8, 0, 1, 1)
- self.check_afterb = Gtk.CheckButton("fdk afterburner")
- self.check_afterb.set_active(True)
- self.check_afterb.set_sensitive(False)
- self.check_afterb.connect("toggled", self.on_codec_audio_changed)
- self.f_3acodec['grid'].attach(self.check_afterb, 9, 0, 1, 1)
- def make_video_codec(self):
- self.f_3vcodec = self.make_frame_ag(3, " video codec " , 6, 8, 8, False)
- self.box_vcodec = self.make_comboboxtext2(VideoEncoder.VEmp4)
- self.box_vcodec.set_active(VideoEncoder.VEmp4_default)
- self.box_vcodec.set_size_request(180,-1)
- self.f_3vcodec['grid'].attach(self.box_vcodec, 0, 0, 1, 1)
- self.box_vcodec.connect("changed", self.on_codec_video_changed)
- #
- self.box_vrc = self.make_comboboxtext2(VcodecOther.VRCall)
- self.box_vrc.set_size_request(180,-1)
- self.f_3vcodec['grid'].attach(self.box_vrc, 1, 0, 1, 1)
- self.box_vrc.connect("changed", self.on_codec_vrc_changed)
- #
- self.spin_vc = self.make_spinbut(21.3 , 15 , 40 , 0.1 , 1 , 1, True )
- self.spin_vc["adj"].connect("value-changed", self.on_codec_vrc_value_change)
- self.f_3vcodec['grid'].attach(self.spin_vc["spinner"], 2, 0, 1, 1)
- #
- # x265 pools 3 x264 threads
- self.check_3v_pool = Gtk.CheckButton("threads/pools 3")
- self.check_3v_pool.connect("toggled", self.on_codec_clicked)
- self.f_3vcodec['grid'].attach(self.check_3v_pool, 3, 0, 1, 1)
- # x26510bit
- self.check_3v_10bit = Gtk.CheckButton("x265 10bit")
- self.check_3v_10bit.connect("toggled", self.on_codec_clicked)
- self.f_3vcodec['grid'].attach(self.check_3v_10bit, 4, 0, 1, 1)
- # opencl
- self.check_3v_opencl = Gtk.CheckButton("opencl")
- self.check_3v_opencl.connect("toggled", self.on_codec_clicked)
- self.f_3vcodec['grid'].attach(self.check_3v_opencl, 5, 0, 1, 1)
- # x264 preset
- self.box_3v_preset = self.make_comboboxtext(VcodecOther.x264_preset)
- #self.box_3v_preset.set_active(3)
- self.box_3v_preset.set_tooltip_text(Tips.preset_tooltip_str)
- self.f_3vcodec['grid'].attach(self.box_3v_preset, 0, 1, 1, 1)
- self.box_3v_preset.connect("changed", self.on_preset_changed)
- # x264 tune
- self.box_3v_tune = self.make_comboboxtext(VcodecOther.x264_tune) # film,animation,grain,stillimage
- self.box_3v_tune.set_tooltip_text(Tips.tune_tooltip_str)
- self.f_3vcodec['grid'].attach(self.box_3v_tune, 1, 1, 1, 1)
- self.box_3v_tune.connect("changed", self.on_preset_changed)
- # x264 opts
- self.box_3v_x264opts = self.make_comboboxtext2(VcodecOptions.OPTx264)
- self.box_3v_x264opts.set_tooltip_text(Tips.opt_tooltip_str)
- self.box_3v_x264opts.set_size_request(180,-1)
- self.f_3vcodec['grid'].attach(self.box_3v_x264opts, 2, 1, 1, 1)
- self.box_3v_x264opts.connect("changed", self.on_codec_clicked)
- #opts custom
- self.entry_optscustom = Gtk.Entry()
- self.entry_optscustom.set_tooltip_text(Tips.x265_optscustom_str)
- self.entry_optscustom.set_text("psnr=1")
- self.entry_optscustom.connect("changed", self.on_codec_clicked)
- self.f_3vcodec['grid'].attach(self.entry_optscustom, 3, 1, 3, 1)
- def make_other_opts(self):
- #
- self.f3_oth = self.make_frame_ag(3, " other options " , 6, 8, 8, True)
- #
- self.check_2pass = Gtk.CheckButton("2 pass")
- self.check_2pass.connect("toggled", self.on_f3_other_clicked)
- self.f3_oth['grid'].attach(self.check_2pass, 0, 0, 1, 1)
- self.check_2pass.set_sensitive(False)
- #
- self.check_nometa = Gtk.CheckButton("no metatag")
- self.check_nometa.set_active(True)
- self.check_nometa.connect("toggled", self.on_f3_other_clicked)
- self.check_nometa.set_tooltip_text(Tips.nometa_tooltip_srt)
- self.f3_oth['grid'].attach(self.check_nometa, 1, 0, 1, 1)
- #
- #
- self.check_scopy = Gtk.CheckButton("sub copy")
- self.check_scopy.connect("toggled", self.on_f3_other_clicked)
- self.check_scopy.set_tooltip_text(Tips.subcopy_tooltip_srt)
- self.f3_oth['grid'].attach(self.check_scopy, 2, 0, 1, 1)
- #
- self.check_debug = Gtk.CheckButton("debug")
- self.check_debug.connect("toggled", self.on_f3_other_clicked)
- self.check_debug.set_tooltip_text(Tips.debug_tooltip_srt)
- self.f3_oth['grid'].attach(self.check_debug, 4, 0, 1, 1)
- #
- self.box_oth_container = self.make_comboboxtext2(VcodecOther.OutContainers)
- self.box_oth_container.set_active(VcodecOther.OutContainers_default)
- self.box_oth_container.set_tooltip_text(Tips.container_tooltip_srt)
- self.f3_oth['grid'].attach(self.box_oth_container, 5, 0, 1, 1)
- self.box_oth_container.connect("changed", self.on_container_changed)
- def make_run_ffmpeg(self):
- self.f3_run = self.make_frame_ag(3, " execute in terminal " , 6, 8, 8, True)
- #
- self.f3_run_indir_label = Gtk.Label("")
- self.f3_run_indir_label.set_margin_left(6)
- self.f3_run_indir_label.set_halign(1) # 1 left 2 right 3 center
- self.f3_run_indir_label.set_ellipsize(2) # need for set_max_width_chars: 1 start 2 middle 3 end
- self.f3_run_indir_label.set_max_width_chars(30)
- self.f3_run['grid'].attach(self.f3_run_indir_label, 0, 0, 1, 1)
- #
- self.f3_run_file = Gtk.Label("no input file")
- self.f3_run_file.set_margin_left(6)
- self.f3_run_file.set_halign(3) # 1 left 2 right 3 center
- self.f3_run_file.set_ellipsize(2) # need for set_max_width_chars: 1 start 2 middle 3 end
- self.f3_run_file.set_max_width_chars(42)
- self.f3_run_file.set_tooltip_text('')
- self.f3_run['grid'].attach(self.f3_run_file, 1, 0, 2, 1)
- self.f3_dur_file = Gtk.Label("")
- self.f3_run['grid'].attach(self.f3_dur_file, 3, 0, 1, 1)
- #
- self.but_f3_run = Gtk.Button(label="RUN")
- self.but_f3_run.connect("clicked", self.on_but_f3_run_clicked)
- self.but_f3_run.set_sensitive(False)
- self.f3_run['grid'].attach(self.but_f3_run, 3, 1, 1, 1)
- #
- self.f3_run_outdir_label = Gtk.Label("")
- self.f3_run_outdir_label.set_margin_left(6)
- self.f3_run_outdir_label.set_halign(1)
- self.f3_run_outdir_label.set_ellipsize(2) # need for set_max_width_chars: 1 start 2 middle 3 end
- self.f3_run_outdir_label.set_max_width_chars(54)
- self.f3_run_outdir_label.set_markup("<b>out dir: </b>" + os.getcwd())
- self.f3_run['grid'].attach(self.f3_run_outdir_label, 0, 1, 2, 1)
- #
- # filechooserbutton
- self.but_folder = Gtk.Button("Choose out dir")
- self.but_folder.set_tooltip_text(Tips.out_dir_tooltip_str)
- self.but_folder.connect("clicked", self.on_folder_clicked)
- self.f3_run['grid'].attach(self.but_folder, 2, 1, 1, 1)
- #
- self.reportdata = Gtk.Label('')
- self.f3_run['grid'].attach(self.reportdata, 0, 3, 4, 1)
- # event handlers -----------------------------------------------
- def on_window_destroy(self, *args):
- Gtk.main_quit(*args)
- def on_map_clicked(self, button):
- self.map_label.set_label("")
- Vars.maps_str = ""
- if self.check_map.get_active():
- map_in = self.entry_map.get_chars(0, -1)
- if map_in != "":
- map_l = map_in.split(",")
- for i in range(len(map_l)):
- if map_l[i] in Vars.maps_ch:
- if Vars.maps_str != "":
- Vars.maps_str += " "
- Vars.maps_str += "-map " + map_l[i]
- self.map_label.set_label(Vars.maps_str)
- self.outfilter()
- self.make_p3_out_command()
- def on_time_clicked(self, button):
- Vars.time_final_str = ""
- Vars.time_start = 0
- if self.check_time.get_active():
- timein = 0
- timeout = 0
- timedur = 0
- timein_ent = self.entry_timein.get_chars(0, -1)
- if timein_ent != "":
- if self.is_number(timein_ent):
- timein = float(timein_ent.split('.')[0])
- if len(timein_ent.split('.')) == 2:
- decimal = timein_ent.split('.')[1][:3]
- decimal = float('0.' + decimal)
- timein += decimal
- if Vars.duration_in_sec != 0:
- if timein > Vars.duration_in_sec:
- self.entry_timein.set_text(str(Vars.duration_in_sec -1))
- return
- else:
- timein = float(self.hms2sec(timein_ent.split('.')[0]))
- if len(timein_ent.split('.')) == 2:
- decimal = timein_ent.split('.')[1][:3]
- decimal = float('0.' + decimal)
- timein += decimal
- if Vars.duration_in_sec != 0:
- if timein > Vars.duration_in_sec:
- self.entry_timein.set_text(str(self.sec2hms(Vars.duration_in_sec -1)))
- return
- timeout_ent = self.entry_timeout.get_chars(0, -1)
- if timeout_ent != "":
- if self.is_number(timeout_ent):
- timeout = float(timeout_ent.split('.')[0])
- if len(timeout_ent.split('.')) == 2:
- decimal = timeout_ent.split('.')[1][:3]
- decimal = float('0.' + decimal)
- timeout += decimal
- if Vars.duration_in_sec != 0:
- if timeout > Vars.duration_in_sec:
- self.entry_timeout.set_text(str(Vars.duration_in_sec))
- return
- if timeout == Vars.duration_in_sec:
- timeout = 0
- timedur = timeout - timein
- else:
- timeout = float(self.hms2sec(timeout_ent.split('.')[0]))
- if len(timeout_ent.split('.')) == 2:
- decimal = timeout_ent.split('.')[1][:3]
- decimal = float('0.' + decimal)
- timeout += decimal
- if Vars.duration_in_sec != 0:
- if timeout > Vars.duration_in_sec:
- self.entry_timeout.set_text(Vars.duration)
- return
- if timeout == Vars.duration_in_sec:
- timeout = 0
- timedur = timeout - timein
- if timein != 0:
- Vars.time_final_str += " -ss " + str(timein)
- Vars.time_start = timein
- if timedur > 0:
- Vars.time_final_str += " -t " + str(timedur)
- self.time_label.set_text(Vars.time_final_str)
- self.outfilter()
- self.make_p3_out_command()
- def on_deint_clicked(self, button):
- Vars.deint_str = ""
- if self.checkdeint.get_active():
- deint_val = self.box_deint['cbox'].get_active()
- if deint_val == 0:
- Vars.deint_str = "yadif"
- elif deint_val == 1:
- Vars.deint_str = "pp=lb"
- elif deint_val == 2:
- Vars.deint_str = "idet"
- self.outfilter()
- def on_scale_clicked(self, button):
- customscale_in = ""
- customscale_in = self.entry_scalecustom.get_chars(0, -1)
- if customscale_in != "":
- Vars.scalestr = customscale_in
- self.outfilter()
- elif self.box_scale_side['cbox'].get_active() != 0:
- self.scale_calc()
- else:
- Vars.scalestr = ""
- self.outfilter()
- def on_dn_clicked(self, button):
- Vars.dn_str = ""
- if self.checkdn.get_active():
- dn_val = int(self.spindn['adj'].get_value())
- Vars.dn_str = "hqdn3d=" + str(dn_val)
- self.outfilter()
- def on_uns_clicked(self, button):
- Vars.uns_str = ""
- if self.checkuns.get_active():
- luma = self.spinunsl['adj'].get_value()
- chroma = self.spinunsc['adj'].get_value()
- Vars.uns_str = "unsharp=5:5:" + "{0:0.2f}".format(luma) + ":5:5:" + "{0:0.2f}".format(chroma)
- self.outfilter()
- def on_fr_clicked(self, button):
- Vars.fr_str = ""
- if self.checkfr.get_active():
- fr_val = self.spinfr['adj'].get_value()
- Vars.fr_str = "-r " + "{0:0.2f}".format(fr_val)
- self.outfilter()
- def on_crop_clicked(self, button):
- ok = 0
- Vars.crop_str = ""
- if self.checkcr.get_active():
- ok = 1
- if ok:
- inW = int(self.spincw['adj'].get_value())
- inH = int(self.spinch['adj'].get_value())
- crT = int(self.spinct['adj'].get_value())
- crB = int(self.spincb['adj'].get_value())
- crL = int(self.spincl['adj'].get_value())
- crR = int(self.spincr['adj'].get_value())
- finW = inW - crL - crR
- finH = inH - crT - crB
- if ( (finW < 100) or (finH < 100) ):
- Vars.crop_str = ""
- else:
- Vars.crop_str = "crop=" + str(finW) + ":" \
- + str(finH) + ":" \
- + str(crL) + ":" \
- + str(crT)
- if self.box_scale_ar['cbox'].get_active() != 2:
- self.outfilter()
- else:
- self.on_scale_clicked(button)
- def on_but_file(self,button):
- if Vars.ENCODING:
- return
- dialog = Gtk.FileChooserDialog("Please choose a file", self.window,
- Gtk.FileChooserAction.OPEN,
- ("_Cancel", Gtk.ResponseType.CANCEL,
- "_Open", Gtk.ResponseType.OK))
- #
- filter = Gtk.FileFilter()
- filter.set_name("Video")
- filter.add_mime_type("video/x-matroska")
- filter.add_mime_type("video/mp4")
- filter.add_mime_type("video/x-flv")
- filter.add_mime_type("video/avi")
- filter.add_mime_type("video/mpg")
- filter.add_mime_type("video/mpeg")
- filter.add_mime_type("video/x-ms-wmv")
- filter.add_mime_type("video/webm")
- filter.add_mime_type("video/ogg")
- filter.add_mime_type("video/quicktime")
- dialog.add_filter(filter)
- #
- dialog.set_current_folder(Vars.indir)
- response = dialog.run()
- if response == Gtk.ResponseType.OK:
- Vars.filename = dialog.get_filename()
- self.file_changed()
- dialog.destroy()
- def file_changed(self):
- #def reduce_string(the_string, left_part, right_part):
- #a = the_string[:left_part]
- #b = '...'
- #c = the_string[-right_part:]
- #rlabel = a + b + c
- #return rlabel
- self.butplay.set_sensitive(True) # low part ---------
- self.butprobe.set_sensitive(True)
- self.preview_logic() # test and testsplit
- self.check_time.set_active(False)
- self.butcrode.set_sensitive(True) # crop ----------
- self.spinct['adj'].set_value(0)
- self.spincb['adj'].set_value(0)
- self.spincl['adj'].set_value(0)
- self.spincr['adj'].set_value(0)
- self.but_volume_det.set_sensitive(True) # volume detect
- Vars.VOLDT_DONE = False
- #self.but_volume_det.set_label("Volume detect")
- self.label_meanvol.set_label("")
- self.label_maxvol.set_label("")
- self.check_vol.set_active(False) #volume
- self.spin_db["adj"].set_value(0)
- # framesdet
- Vars.FRAMDT_DONE = False
- self.but_frames_det.set_sensitive(True)
- self.label_framesdet.set_label("N/A")
- self.label_time2frame.set_label('')
- #
- self.check_drc.set_active(False) #drc
- self.check_drc.set_sensitive(False)
- self.spin_drc["adj"].set_value(1)
- self.spin_drc["spinner"].set_sensitive(False)
- Vars.ac3_drc = ""
- self.compand_test.set_sensitive(True) #compand test
- self.compand_volume.set_sensitive(True)
- if self.check_compand.get_active():
- self.check_compand.set_active(False)
- self.dynaudnorm_test.set_sensitive(True) #dynaudnorm test
- self.dynaudnorm_volume.set_sensitive(True)
- if self.check_dynaudnorm.get_active():
- self.check_dynaudnorm.set_active(False)
- self.but_black_det.set_sensitive(True) # black detect
- self.but_black_det.set_label("Black detect")
- self.textbuffer.set_text(Tips.black_dt_init_str)
- self.progressbar_black_det.set_fraction(0.0)
- self.check_prologic.set_sensitive(False) #check_prologic
- self.check_prologic.set_active(False)
- self.but_f3_run.set_sensitive(True) # ffmpeg run
- Vars.BLACKDT_DONE = False
- Vars.have_subs = False # subs
- self.check_map.set_active(False) # map
- #
- command = "clear" + "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- Vars.dirname = os.path.dirname(Vars.filename)
- Vars.basename = os.path.basename(Vars.filename)
- Vars.indir = os.path.dirname(Vars.filename)
- #out same as in
- Vars.outdir = Vars.indir
- command = "cd " + "\"" + Vars.outdir + "\"" + "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- # label outdir
- self.f3_run_outdir_label.set_markup("<b>out dir: </b>" + Vars.outdir)
- #
- self.check_out_file()
- # label indir
- self.f3_run_indir_label.set_label(Vars.dirname)
- self.f3_run_indir_label.set_tooltip_text(Vars.dirname)
- # label filename
- self.f3_run_file.set_label(Vars.basename)
- # label button openfile
- if len(Vars.basename) > 36:
- self.but_file.set_label(Vars.basename[0:33] + '...')
- else:
- self.but_file.set_label(Vars.basename)
- #
- self.but_f3_run.set_tooltip_text("")
- self.reportdata.set_text('')
- command = [Vars.ffprobe_ex, '-show_format', '-show_streams', '-pretty', '-loglevel', 'quiet', Vars.filename]
- p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = p.communicate()
- out = out.decode() # python3
- self.get_info(out)
- def get_info(self, out):
- def form_to_3(in_str):
- '''
- bitrate and size info formatting
- '''
- a = in_str.split(' ')[0]
- if len(in_str.split(' ')) == 2:
- b = in_str.split(' ')[1]
- a = float(a)
- result = "{0:.3f}".format(a ) + " " + b
- else:
- result = 'N/A'
- return result
- def set_w_h_video_scale():
- self.spincw['adj'].set_value(float(Vars.video_width)) #mettere decimali se no non si vede
- self.spincw['spinner'].set_sensitive(False)
- self.spinch['adj'].set_value(float(Vars.video_height)) #mettere decimali se no non si vede
- self.spinch['spinner'].set_sensitive(False)
- if Vars.add_1_1_dar:
- self.box_scale_ar['list'].append(["as input"])
- Vars.add_1_1_dar = False
- def set_dar_in(info):
- try:
- darw = info.split(':')[0]
- darh = info.split(':')[1]
- darw = int(darw)
- darh = int(darh)
- if darh > 0 and darw > 0:
- darin = float(darw)/darh
- Vars.darin = "{0:.3f}".format(darin)
- else:
- darin = float(Vars.video_width)/float(Vars.video_height)
- Vars.darin = "{0:.3f}".format(darin)
- except:
- darin = float(Vars.video_width)/float(Vars.video_height)
- Vars.darin = "{0:.3f}".format(darin)
- def maps_choises(num_streams):
- maps = []
- for i in range(0,num_streams):
- m = '0:' + str(i)
- maps.append(m)
- Vars.maps_ch = maps
- #x Vars.info_str
- Vars.info_str = ""
- is_stream = 0
- is_format = 0
- is_video = 0
- for line in out.split('\n'):
- line = line.strip()
- if line.startswith('[STREAM]'):
- Vars.info_str += "STREAM "
- is_stream = 1
- elif line.startswith('[/STREAM]'):
- Vars.info_str += "\n"
- is_stream = 0
- elif line.startswith('index=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- Vars.info_str += info + ": "
- elif line.startswith('codec_name=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- if info == 'ac3':
- self.check_drc.set_sensitive(True)
- self.spin_drc["spinner"].set_sensitive(True)
- Vars.info_str += info + " "
- elif line.startswith('profile=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- Vars.info_str = Vars.info_str + "profile=" +info + " "
- elif line.startswith('codec_type=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- if info == 'video':
- is_video = 1
- else:
- is_video = 0
- Vars.info_str += info + " "
- # auto -c:s copy if subtitles streams
- if info == 'subtitle':
- Vars.have_subs = True
- self.on_container_changed(0)
- elif line.startswith('width=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- if is_video:
- Vars.video_width = info
- Vars.info_str += info + "x"
- elif line.startswith('height=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- if is_video:
- Vars.video_height = info
- Vars.info_str += info + " "
- elif line.startswith('sample_aspect_ratio=') and is_stream == 1:
- s = line
- if is_video:
- info = s.split('=')[1]
- Vars.info_str += "SAR=" + info + " "
- elif line.startswith('display_aspect_ratio=') and is_stream == 1:
- s = line
- if is_video:
- info = s.split('=')[1]
- Vars.info_str += "DAR=" + info + " "
- set_dar_in(info)
- elif line.startswith('pix_fmt=') and is_stream == 1:
- s = line
- if is_video:
- info = s.split('=')[1]
- Vars.info_str += info + " "
- elif line.startswith('sample_rate=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- info = form_to_3(info)
- Vars.audio_srate_in = info
- Vars.info_str += "samplerate=" + info + " "
- if Vars.audio_srate_in == '44.100 KHz':
- self.box_audio_rate.set_active(1)
- else:
- self.box_audio_rate.set_active(0)
- self.on_audio_clicked(1)
- elif line.startswith('channels=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- Vars.audio_channels = int(info)
- Vars.info_str += "channels=" + info + " "
- if Vars.audio_channels == 6:
- self.check_prologic.set_sensitive(True)
- self.check_prologic.set_active(True)
- elif line.startswith('r_frame_rate=') and is_stream == 1:
- if is_video:
- s = line
- info = s.split('=')[1]
- a = info.split('/')[0]
- b = info.split('/')[1]
- a = float(a)
- b = float(b)
- if (a > 0) and (b > 0):
- c = float(a)/float(b)
- Vars.framerate = c
- info = "{0:0.2f}".format(c)
- self.spinfr["adj"].set_value(c)
- Vars.info_str += info + " fps "
- elif line.startswith('bit_rate=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- info = form_to_3(info)
- Vars.info_str += "bitrate=" + info + " "
- elif line.startswith('nb_frames=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- if is_video:
- if self.is_number(info):
- self.label_framesdet.set_label(info)
- elif line.startswith('TAG:NUMBER_OF_FRAMES=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- if is_video:
- if self.is_number(info):
- self.label_framesdet.set_label(info)
- elif line.startswith('TAG:language=') and is_stream == 1:
- s = line
- info = s.split('=')[1]
- Vars.info_str += "lang=" + info + " "
- elif line.startswith('[FORMAT]'):
- Vars.info_str = Vars.info_str + "FORMAT "
- is_format = 1
- elif line.startswith('[/FORMAT]'):
- is_format = 0
- elif line.startswith('nb_streams=') and is_format == 1:
- s = line
- info = s.split('=')[1]
- Vars.info_str += "streams=" + info + " "
- # possible map [tuple] Vars.maps_ch
- maps_choises(int(info))
- elif line.startswith('duration=') and is_format == 1:
- s = line
- infoor = s.split('=')[1]
- info = infoor.split('.')[0]
- Vars.duration_in_sec = self.hms2sec(info)
- Vars.duration = info
- if len (infoor.split('.')) == 2:
- decimal = infoor.split('.')[1][:3]
- info += '.' + decimal
- Vars.duration = info
- decimal = float('0.' + decimal)
- Vars.duration_in_sec += decimal
- self.entry_timein.set_text('0')
- self.entry_timeout.set_text(info)
- Vars.info_str += "duration=" + info + " "
- elif line.startswith('size=') and is_format == 1:
- s = line
- info = s.split('=')[1]
- info = form_to_3(info)
- Vars.info_str += "size=" + info + " "
- elif line.startswith('bit_rate=') and is_format == 1:
- s = line
- info = s.split('=')[1]
- info = form_to_3(info)
- Vars.info_str += "bitrate=" + info
- set_w_h_video_scale()
- self.f3_dur_file.set_label(Vars.duration)
- self.textbuffer_info.set_text(Vars.info_str)
- self.f3_run_file.set_tooltip_text(Vars.info_str)
- self.check_map.set_tooltip_text(Vars.info_str)
- self.check_time.set_tooltip_text(Vars.info_str)
- Vars.in_file_size = self.humansize(Vars.filename)
- def on_butplay_clicked(self, button):
- if Vars.ENCODING:
- return
- command = Vars.ffplay_ex + " -hide_banner" + " \"" + Vars.filename + "\"" +"\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- def on_butprobe_clicked(self, button):
- if Vars.ENCODING:
- return
- command = Vars.ffprobe_ex + " \"" + Vars.filename + "\"" + " 2>&1 | grep 'Input\|Duration\|Stream'" + "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- def on_butcrode_clicked(self, button):
- self.butcrode.set_sensitive(False)
- if Vars.time_start == 0:
- command = Vars.ffmpeg_ex + " -i " + "\"" + Vars.filename + "\"" + " -ss 60 -t 1 -vf cropdetect -f null - 2>&1 | awk \'/crop/ { print $NF }\' | tail -1"
- else:
- 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"
- p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
- out, err = p.communicate()
- out = out.decode()
- for line in out.split('\n'):
- line = line.strip()
- if "crop=" in line:
- aa = line.split('crop=', 1)
- aaa = aa[1]
- listdata = aaa.split(':')
- w = listdata[0]
- h = listdata[1]
- offx = listdata[2]
- offy = listdata[3]
- ctop = int(offy)
- cbot = int(Vars.video_height) - int(offy) -int(h)
- cleft = int(offx)
- cright = int(Vars.video_width) - int(offx) -int(w)
- self.spinct['adj'].set_value(float(ctop))
- self.spincb['adj'].set_value(float(cbot))
- self.spincl['adj'].set_value(float(cleft))
- self.spincr['adj'].set_value(float(cright))
- break
- self.butcrode.set_sensitive(True)
- def on_buttest_clicked(self, button):
- if Vars.ENCODING:
- return
- # -map preview: only with none -vf option
- if Vars.maps_str == "":
- command = Vars.ffplay_ex + " -hide_banner" + " \"" + Vars.filename + "\" " \
- + " " + Vars.time_final_str + " " \
- + "-vf " + Vars.filter_test_str + "\n"
- else:
- command = Vars.ffmpeg_ex + " -i \"" + Vars.filename + "\" " \
- + Vars.maps_str + " " + Vars.time_final_str + " "
- if Vars.filter_test_str != "":
- command = command + " -vf " + Vars.filter_test_str
- command = command + " -c copy -f matroska - | ffplay -" + "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- def on_buttestspl_clicked(self, button):
- if Vars.ENCODING:
- return
- command = Vars.ffplay_ex + " -hide_banner" + " \"" + Vars.filename + "\" " \
- + " " + Vars.time_final_str + " " \
- + " -vf \"split[a][b]; [a]pad=iw:(ih*2)+4:color=888888 [src]; [b]" \
- + Vars.filter_test_str + " [filt]; [src][filt]overlay=((main_w - w)/2):main_h/2\"" + "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- def on_butt_vtecopy_clicked(self, widget):
- self.terminal.select_all()
- self.terminal.copy_clipboard()
- try: # only vte2.9
- self.terminal.select_none()
- except:
- return
- def on_but_volume_det_clicked(self, button):
- def set_other_butt(boolean):
- if Vars.FRAMDT_DONE != True:
- self.but_frames_det.set_sensitive(boolean)
- if Vars.BLACKDT_DONE != True:
- self.but_black_det.set_sensitive(boolean)
- def finish_voldet(meanv, maxv, max_vol_det):
- self.voldet_spin.stop()
- self.voldet_spin.set_sensitive(False)
- self.but_volume_det.set_label("Volume detect")
- set_other_butt(True)
- self.label_meanvol.set_label(meanv)
- self.label_maxvol.set_label(maxv)
- max_vol_det = max_vol_det.split(' ')[1]
- volgain = float(max_vol_det) + 0.9
- if volgain < -0.75:
- volgain=abs(volgain)
- volgain=float(volgain)
- self.spin_db["adj"].set_value(volgain)
- def my_thread_voldet():
- command = [Vars.ffmpeg_ex, '-i', Vars.filename, '-vn', '-af', 'volumedetect', '-f', 'null', '/dev/null']
- p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
- GLib.idle_add(self.but_volume_det.set_label, "Wait")
- GLib.idle_add(set_other_butt, False)
- time.sleep(0.02)
- while True:
- line = p.stderr.read()
- if not line:
- break
- out = line.decode()
- for line in out.split('\n'):
- line = line.strip()
- if "mean_volume:" in line:
- aa = line.split('mean_volume:', 1)
- mea_vol_det = aa[1]
- meanv = "Mean vol: " + mea_vol_det
- if "max_volume:" in line:
- aa = line.split('max_volume:', 1)
- max_vol_det = aa[1]
- maxv = "Max vol: " + max_vol_det
- p.communicate()
- GLib.idle_add(finish_voldet, meanv, maxv, max_vol_det)
- time.sleep(0.1)
- if Vars.VOLDT_DONE:
- return
- Vars.VOLDT_DONE = True
- self.voldet_spin.set_sensitive(True)
- self.voldet_spin.start()
- thread=threading.Thread(target=my_thread_voldet)
- thread.daemon = True
- thread.start()
- def on_but_frames_det_clicked(self, button):
- def finish_framesdet(frames):
- self.label_framesdet.set_label(frames)
- self.framesdet_spin.stop()
- self.framesdet_spin.set_sensitive(False)
- self.but_frames_det.set_label("Total frames detect")
- set_other_butt(True)
- def set_other_butt(boolean):
- if Vars.VOLDT_DONE != True:
- self.but_volume_det.set_sensitive(boolean)
- if Vars.BLACKDT_DONE != True:
- self.but_black_det.set_sensitive(boolean)
- def my_thread_framedet():
- #ffprobe2 -show_packets ac3-sd.mkv 2>/dev/null | grep video | wc -l
- command = Vars.ffprobe_ex + " -show_packets \"" + Vars.filename + "\" 2>/dev/null | grep video | wc -l"
- p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
- GLib.idle_add(self.but_frames_det.set_label, "Wait")
- GLib.idle_add(set_other_butt, False)
- time.sleep(0.02)
- while True:
- line = p.stdout.read()
- if not line:
- break
- out = line.decode()
- for line in out.split('\n'):
- if line != "":
- line = line.strip()
- frames = line
- p.communicate()
- GLib.idle_add(finish_framesdet, frames)
- time.sleep(0.3)
- if Vars.FRAMDT_DONE:
- return
- Vars.FRAMDT_DONE = True
- self.framesdet_spin.set_sensitive(True)
- self.framesdet_spin.start()
- thread=threading.Thread(target=my_thread_framedet)
- thread.daemon = True
- thread.start()
- def on_time2frame_clicked(self, button):
- timein_ent = self.entry_time2frame.get_chars(0, -1)
- if timein_ent != "":
- if self.is_number(timein_ent):
- timein = float(timein_ent.split('.')[0])
- if len(timein_ent.split('.')) == 2:
- decimal = timein_ent.split('.')[1][:3]
- decimal = float('0.' + decimal)
- timein += decimal
- if Vars.duration_in_sec != 0:
- if timein > Vars.duration_in_sec:
- self.entry_timein.set_text(str(Vars.duration_in_sec -1))
- return
- else:
- timein = float(self.hms2sec(timein_ent.split('.')[0]))
- if len(timein_ent.split('.')) == 2:
- decimal = timein_ent.split('.')[1][:3]
- decimal = float('0.' + decimal)
- timein += decimal
- if Vars.duration_in_sec != 0:
- if timein > Vars.duration_in_sec:
- self.entry_timein.set_text(str(self.sec2hms(Vars.duration_in_sec -1)))
- return
- t2frames = int(round(float(timein)*Vars.framerate))
- self.label_time2frame.set_label(str(t2frames))
- def on_volume_clicked(self, button):
- ratio = 1
- self.label_ratio_val.set_label("1")
- Vars.final_af_str = ""
- db = self.spin_db["adj"].get_value()
- if db != 0.00:
- ratio = pow(10, (db/20.0))
- ratio = float("{0:.3f}".format(ratio))
- self.label_ratio_val.set_label(str(ratio))
- if self.check_vol.get_active():
- Vars.final_af_str = "volume=" + str(ratio)
- else:
- Vars.final_af_str = ""
- self.make_p3_out_command()
- def on_drc_clicked(self, buttom):
- Vars.ac3_drc = ""
- if self.check_drc.get_active():
- val = self.spin_drc["adj"].get_value()
- Vars.ac3_drc = "-drc_scale " + str(int(val))
- def on_compand_reset(self, button):
- self.entry_compand.set_text(Vars.compinit)
- self.on_compand_clicked(button)
- def on_compand_clicked(self, button):
- Vars.compand_data = ""
- if self.check_compand.get_active():
- if self.check_dynaudnorm.get_active():
- self.check_dynaudnorm.set_active(False)
- compand_data = self.entry_compand.get_chars(0, -1)
- if Vars.audio_channels == 6:
- Vars.compand_data = "aformat=channel_layouts=stereo,aresample=matrix_encoding=dplii,compand=" + compand_data
- else:
- Vars.compand_data = "aformat=channel_layouts=stereo,compand=" + compand_data
- self.make_p3_out_command()
- def on_compand_test(self, button):
- if Vars.compand_data != "":
- 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"
- else:
- 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"
- length = len(command)
- self.terminal.feed_child(command, length)
- def on_compand_volume(self, button):
- if Vars.compand_data != "":
- command = \
- Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'movie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[vid];"\
- + "amovie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[aud];"\
- + "[aud]asplit=[2][3];"\
- + "[2]aformat=channel_layouts=stereo,showvolume=h=20:t=0[volin];"\
- + "[3]" + Vars.compand_data + ",asplit[c2][out1];"\
- + "[c2]showvolume=h=40[volout];"\
- + "[vid][volin]overlay=6:6[int1];"\
- + "[int1][volout]overlay=6:56,setdar=" + Vars.darin + "[out]\'"\
- + " -window_title \"compand test, volume in,out\"" + "\n"
- else:
- command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'movie=" + Vars.filename + ":sp=" + str(Vars.time_start)\
- + "[vid];amovie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[aud];"\
- + "[aud]aformat=channel_layouts=stereo,"\
- + "asplit[out1][2] ; [2]showvolume=h=60[3]; [vid][3]overlay=6:6,setdar=" + Vars.darin + "[out]\'"\
- + " -window_title \"input volume\"" + "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- def on_dynaudnorm_reset(self, button):
- self.entry_dynaudnorm.set_text(Vars.dynaudnorm)
- self.on_dynaudnorm_clicked(button)
- def on_dynaudnorm_clicked(self, button):
- Vars.dynaudnorm_data = ""
- if self.check_dynaudnorm.get_active():
- if self.check_compand.get_active():
- self.check_compand.set_active(False)
- dynaudnorm_data = self.entry_dynaudnorm.get_chars(0, -1)
- if Vars.audio_channels == 6:
- Vars.dynaudnorm_data = "aformat=channel_layouts=stereo,aresample=matrix_encoding=dplii,dynaudnorm=" + dynaudnorm_data
- else:
- Vars.dynaudnorm_data = "aformat=channel_layouts=stereo,dynaudnorm=" + dynaudnorm_data
- self.make_p3_out_command()
- def on_dynaudnorm_test(self, button):
- if Vars.dynaudnorm_data != "":
- 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"
- else:
- 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"
- length = len(command)
- self.terminal.feed_child(command, length)
- def on_dynaudnorm_volume(self, button):
- if Vars.dynaudnorm_data != "":
- command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'movie=" + Vars.filename + ":sp=" + str(Vars.time_start)\
- + "[vid];amovie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[aud];"\
- + "[aud]" + Vars.dynaudnorm_data \
- + ", asplit[out1][2];"\
- + "[2]showvolume=h=15:w=240:f=120:r=15:t=0,"\
- + "drawgrid=width=15:height=30:thickness=2:color=white@0.2,crop=225:31:0:0[3];"\
- + "[vid][3]overlay=6:6:format=yuv420,setdar=" + Vars.darin +"[out]\'"\
- + " -window_title \"dynaudnorm test, volume out\"" + "\n"
- else:
- command = Vars.ffplay_ex + " -hide_banner" + " -f lavfi \'movie=" + Vars.filename + ":sp=" + str(Vars.time_start)\
- + "[vid];amovie=" + Vars.filename + ":sp=" + str(Vars.time_start) + "[aud];"\
- + "[aud]aformat=channel_layouts=stereo,"\
- + "asplit[out1][2] ; [2]showvolume=h=60[3]; [vid][3]overlay=6:6,setdar=" + Vars.darin +"[out]\'"\
- + " -window_title \"input volume\"" + "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- def on_audio_clicked(self, button):
- #audio
- Vars.audio_codec_str = self.audio_codec()
- self.make_p3_out_command()
- def on_codec_audio_changed(self, button):
- def no_afterburn():
- if self.check_afterb.get_sensitive():
- self.check_afterb.set_active(True)
- self.check_afterb.set_sensitive(False)
- def yes_afterburn():
- self.check_afterb.set_sensitive(True)
- #prologic2
- if Vars.audio_channels == 6 and self.box_audio_ch.get_active_text() == '2':
- self.check_prologic.set_sensitive(True)
- else:
- self.check_prologic.set_sensitive(False)
- #
- selected_audio_codec = self.box_ac.get_active_text()
- for i in range(0,len(AudioEncoder.AEall)):
- if AudioEncoder.AEall[i].label == selected_audio_codec:
- Vars.XaCheck = AudioEncoder.AEall[i]
- #Vars.XaCheck now is the selected AEobject
- break
- if Vars.acodec_is != Vars.XaCheck.codec:
- self.box_audio_ch.set_sensitive(True)
- self.box_audio_rate.set_sensitive(True)
- #
- if Vars.XaCheck.value:
- self.spin_ac['spinner'].set_sensitive(True)
- self.adj_change2(self.spin_ac['adj'], Vars.XaCheck.value)
- self.spin_ac['adj'].set_value(Vars.XaCheck.value[0])
- else:
- self.spin_ac['spinner'].set_sensitive(False)
- #
- if Vars.XaCheck.toolt:
- self.spin_ac['spinner'].set_tooltip_text(Vars.XaCheck.toolt)
- else:
- self.spin_ac['spinner'].set_tooltip_text('')
- #
- if Vars.XaCheck.afterbrn:
- yes_afterburn()
- else:
- no_afterburn()
- #
- if Vars.XaCheck.no_audio_enc:
- self.box_audio_ch.set_sensitive(False)
- self.box_audio_rate.set_sensitive(False)
- self.check_prologic.set_sensitive(False)
- self.check_soxr.set_sensitive(False)
- elif Vars.XaCheck.force_stereo: # aacplus
- self.box_audio_ch.set_sensitive(False)
- self.box_audio_ch.set_active(0)
- #
- Vars.acodec_is = Vars.XaCheck.codec
- self.on_audio_clicked(button)
- def audio_codec(self):
- # channels
- audio_codec_str = ""
- channel_str = "-ac 2"
- channel = self.box_audio_ch.get_active_text()
- if channel == "1":
- channel_str = "-ac 1"
- # sample rate e soxr
- sample_str = ""
- sample = self.box_audio_rate.get_active_text()
- if not(Vars.XaCheck.no_audio_enc):
- if sample == "44100":
- out_s = '44.100 KHz'
- if out_s != Vars.audio_srate_in:
- sample_str = "-ar 44.1k"
- self.check_soxr.set_sensitive(True)
- else:
- self.check_soxr.set_sensitive(False)
- elif sample == "48000":
- out_s = '48.000 KHz'
- if out_s != Vars.audio_srate_in:
- sample_str = "-ar 48k"
- self.check_soxr.set_sensitive(True)
- else:
- self.check_soxr.set_sensitive(False)
- # acodec
- def on_afterburner(ac_str):
- if (self.check_afterb.get_active() == False):
- ac_str = ac_str + " -afterburner 0 "
- return ac_str
- audio_codec_str = Vars.XaCheck.comm_str
- if not(Vars.XaCheck.no_audio_enc):
- if Vars.XaCheck.value != None:
- input_par = self.spin_ac['adj'].get_value()
- audio_codec_str += str(int(input_par))
- if Vars.XaCheck.kb:
- audio_codec_str += 'k '
- else:
- audio_codec_str = audio_codec_str + ' '
- audio_codec_str += sample_str + " " + channel_str
- if Vars.XaCheck.afterbrn:
- audio_codec_str = on_afterburner(audio_codec_str)
- return audio_codec_str
- def on_codec_video_changed(self, button):
- self.on_codec_clicked(button)
- def on_preset_changed(self, button):
- self.on_codec_clicked(button)
- def on_codec_clicked(self, button):
- Vars.final_codec_str = ""
- # video codec
- selected_video_codec = self.box_vcodec.get_active_text()
- for i in range(0,len(VideoEncoder.VEall)):
- if VideoEncoder.VEall[i].label == selected_video_codec:
- Vars.XvCheck = VideoEncoder.VEall[i]
- #Vars.XvCheck now is the selected VEobject
- break
- self.set_video_encoder()
- Vars.video_codec_str_more = self.make_video_codec_str()
- self.check_out_file()
- self.on_codec_vrc_value_change(button)
- def on_codec_vrc_changed(self, button):
- video_rc = self.box_vrc.get_active_text()
- if not(Vars.XvCheck.no_video_enc):
- if video_rc == VcodecOther.VRCcrf.label: # crf
- self.adj_change2(self.spin_vc['adj'], Vars.XvCheck.crf_val)
- self.spin_vc['adj'].set_value(Vars.XvCheck.crf_val[0])
- self.check_2pass.set_active(False)
- self.check_2pass.set_sensitive(False)
- elif video_rc == VcodecOther.VRCbr.label: # bitrate
- self.adj_change2(self.spin_vc['adj'], Vars.XvCheck.br_val)
- self.spin_vc['adj'].set_value(Vars.XvCheck.br_val[0])
- if Vars.XvCheck.br2pass:
- self.check_2pass.set_sensitive(True)
- else:
- self.check_2pass.set_sensitive(False)
- elif video_rc == VcodecOther.VRCq.label: # q-scale
- self.adj_change2(self.spin_vc['adj'], Vars.XvCheck.q_val)
- self.spin_vc['adj'].set_value(Vars.XvCheck.q_val[0])
- self.check_2pass.set_active(False)
- self.check_2pass.set_sensitive(False)
- def on_codec_vrc_value_change(self, button):
- Vars.video_codec_str = ""
- video_rc = self.box_vrc.get_active_text() #0 crf, 1 kb/s
- if not(Vars.XvCheck.no_video_enc):
- in_data = str(self.spin_vc['adj'].get_value())
- if video_rc == VcodecOther.VRCcrf.label: #crf
- if Vars.XvCheck.crf_comm:
- crf_comm = Vars.XvCheck.crf_comm #-x265-params
- else:
- crf_comm = '-crf:v ' # default ffmpeg
- video_codec_str = Vars.XvCheck.comm_str + crf_comm + in_data
- if not(Vars.XvCheck.vrc_custom_comm): # x265 vrc in opts
- video_codec_str += ' '
- elif video_rc == VcodecOther.VRCbr.label: #bitrate
- in_data = str(int(self.spin_vc['adj'].get_value()))
- if Vars.XvCheck.br_comm:
- br_comm = Vars.XvCheck.br_comm #-x265-params
- else:
- br_comm = '-b:v ' # default ffmpeg
- video_codec_str = Vars.XvCheck.comm_str + br_comm + in_data
- if Vars.XvCheck.kb:
- video_codec_str += 'k '
- elif video_rc == VcodecOther.VRCq.label: #q scale
- q_comm = '-q:v '
- video_codec_str = Vars.XvCheck.comm_str + q_comm + in_data
- video_codec_str += Vars.video_codec_str_more
- else:
- video_codec_str = Vars.video_codec_str_more
- Vars.video_codec_str = video_codec_str
- self.make_p3_out_command()
- def set_video_encoder(self):
- if Vars.vcodec_is != Vars.XvCheck.codec:
- Vars.vcodec_is = Vars.XvCheck.codec
- # no video encoding
- if Vars.XvCheck.no_video_enc:
- self.video_ui_widg_false_all()
- return
- # set ui widgets
- if Vars.XvCheck.is10bit:
- self.check_3v_10bit.set_sensitive(True)
- else:
- self.check_3v_10bit.set_sensitive(False)
- if Vars.XvCheck.pool or Vars.XvCheck.threads:
- self.check_3v_pool.set_sensitive(True)
- else:
- self.check_3v_pool.set_active(False)
- self.check_3v_pool.set_sensitive(False)
- if Vars.XvCheck.opencl:
- self.check_3v_opencl.set_sensitive(True)
- else:
- self.check_3v_opencl.set_active(False)
- self.check_3v_opencl.set_sensitive(False)
- # vrc
- if Vars.XvCheck.vrc:
- self.box_vrc.set_sensitive(True)
- self.spin_vc['spinner'].set_sensitive(True)
- self.cboxtxt_change2(
- self.box_vrc,
- self.on_codec_vrc_changed,
- eval('VcodecOther.VRC' + Vars.XvCheck.codec),
- 0,
- 'Vars.vrc_list',
- Vars.XvCheck.codec)
- else:
- self.spin_vc['spinner'].set_sensitive(False)
- self.box_vrc.set_sensitive(False)
- # preset
- if Vars.XvCheck.preset:
- self.box_3v_preset.set_sensitive(True)
- self.cboxtxt_change(
- self.box_3v_preset,
- self.on_preset_changed,
- eval('VcodecOther.' + Vars.XvCheck.codec + '_preset'),
- eval('VcodecOther.' + Vars.XvCheck.codec + '_preset_default'),
- 'Vars.preset_list',
- Vars.XvCheck.codec)
- else:
- self.box_3v_preset.set_sensitive(False)
- # tune
- if Vars.XvCheck.tune:
- self.box_3v_tune.set_sensitive(True)
- self.cboxtxt_change(
- self.box_3v_tune,
- self.on_preset_changed,
- eval('VcodecOther.' + Vars.XvCheck.codec + '_tune'),
- eval('VcodecOther.' + Vars.XvCheck.codec + '_tune_default'),
- 'Vars.tune_list',
- Vars.XvCheck.codec)
- else:
- self.box_3v_tune.set_sensitive(False)
- # opts
- if Vars.XvCheck.opts:
- self.box_3v_x264opts.set_sensitive(True)
- self.cboxtxt_change2(
- self.box_3v_x264opts,
- self.on_codec_clicked,
- eval('VcodecOptions.OPT' + Vars.XvCheck.codec),
- eval('VcodecOptions.OPT' + Vars.XvCheck.codec + '_default'),
- 'Vars.opt_list',
- Vars.XvCheck.codec)
- else:
- self.box_3v_x264opts.set_sensitive(False)
- def make_video_codec_str(self):
- video_codec_str = ""
- ## no video encoding
- if Vars.XvCheck.no_video_enc:
- video_codec_str = Vars.XvCheck.comm_str
- return video_codec_str
- # opts
- if Vars.XvCheck.opts:
- selected_opt = self.box_3v_x264opts.get_active_text()
- options_obj = eval('VcodecOptions.OPT' + Vars.XvCheck.codec)
- for i in range(0,len(options_obj)):
- if options_obj[i].label == selected_opt:
- XoptCheck = options_obj[i]
- break
- else:
- XoptCheck = options_obj[0]
- # protection on OPT change
- # next ui main loop will find selected_opt label
- if Vars.XvCheck.vrc_custom_comm: # x265 vrc commands and pool in -params
- if XoptCheck.text_entry:
- self.entry_optscustom.set_sensitive(True)
- video_codec_str += ":" + self.entry_optscustom.get_chars(0, -1)
- else:
- self.entry_optscustom.set_sensitive(False)
- video_codec_str += XoptCheck.comm_str
- # pools 3
- if Vars.XvCheck.pool:
- if self.check_3v_pool.get_active():
- video_codec_str += ":pools=3"
- else: # standard ffmpeg vrc commands
- video_codec_str += XoptCheck.comm_str
- # opencl
- if Vars.XvCheck.opencl:
- if self.check_3v_opencl.get_active():
- video_codec_str += ":opencl"
- # preset
- if Vars.XvCheck.preset:
- preset = self.box_3v_preset.get_active_text()
- video_codec_str += " -preset " + preset + " "
- # tune
- if Vars.XvCheck.tune:
- tune = self.box_3v_tune.get_active_text()
- if tune != "none":
- video_codec_str += "-tune " + tune
- # threads
- if Vars.XvCheck.threads:
- if self.check_3v_pool.get_active():
- video_codec_str += " -threads 3"
- # 10bit -pix_fmt yuv420p10le
- if Vars.XvCheck.is10bit:
- if self.check_3v_10bit.get_active():
- video_codec_str += " -pix_fmt yuv420p10le "
- ##
- return video_codec_str
- def video_ui_widg_false_all(self):
- # deactivate widget
- self.box_vrc.set_sensitive(False)
- self.spin_vc['spinner'].set_sensitive(False)
- self.box_3v_preset.set_sensitive(False)
- self.box_3v_tune.set_sensitive(False)
- self.box_3v_x264opts.set_sensitive(False)
- self.entry_optscustom.set_sensitive(False)
- self.check_3v_opencl.set_active(False)
- self.check_3v_opencl.set_sensitive(False)
- self.check_2pass.set_active(False)
- self.check_2pass.set_sensitive(False)
- self.check_3v_10bit.set_sensitive(False)
- self.check_3v_pool.set_sensitive(False)
- def on_f3_other_clicked(self, button):
- Vars.final_other_str = ""
- Vars.debug = 0
- Vars.first_pass = 0
- Vars.n_pass = 1
- if self.check_nometa.get_active():
- Vars.final_other_str = "-map_metadata -1"
- if self.check_2pass.get_active():
- Vars.first_pass = 1
- Vars.n_pass = 2
- if self.check_scopy.get_active():
- if (Vars.final_other_str == ""):
- Vars.final_other_str = "-c:s copy"
- else:
- Vars.final_other_str += " " + "-c:s copy"
- if self.check_debug.get_active():
- Vars.debug = 1
- self.make_p3_out_command()
- def on_container_changed(self,button):
- selected_container = self.box_oth_container.get_active_text()
- for i in range(0,len(VcodecOther.OutContainers)):
- if VcodecOther.OutContainers[i].label == selected_container:
- XocCheck = VcodecOther.OutContainers[i]
- #XocCheck now is the selected container obj
- break
- #set generals
- Vars.container_str = XocCheck.comm_str
- Vars.ext = XocCheck.ext
- if XocCheck.sub_stream and Vars.have_subs:
- self.check_scopy.set_sensitive(True)
- self.check_scopy.set_active(True)
- else:
- self.check_scopy.set_active(False)
- self.check_scopy.set_sensitive(False)
- #set audio choises
- if Vars.acodec_list != XocCheck.alist: # alist is changed
- self.cboxtxt_change2(
- self.box_ac,
- self.on_codec_audio_changed,
- eval('AudioEncoder.AE' + XocCheck.alist),
- eval('AudioEncoder.AE' + XocCheck.alist + '_default'),
- 'Vars.acodec_list',
- XocCheck.alist
- )
- ########### OLD WAY ####################
- #self.cboxtxt_change2(
- #self.box_ac,
- #self.on_codec_audio_changed,
- #AudioEncoder.AEmp4,
- #AudioEncoder.AEmp4_default,
- #'Vars.acodec_list',
- #"mp4")
- ########################################
- #set video choises
- if Vars.vcodec_list != XocCheck.vlist: # vlist is changed
- self.cboxtxt_change2(
- self.box_vcodec,
- self.on_codec_video_changed,
- eval('VideoEncoder.VE' + XocCheck.vlist),
- eval('VideoEncoder.VE' + XocCheck.vlist + '_default'),
- 'Vars.vcodec_list',
- XocCheck.vlist
- )
- if XocCheck.audio_only:
- self.box_vcodec.set_sensitive(False)
- else:
- self.box_vcodec.set_sensitive(True)
- self.check_out_file()
- self.make_p3_out_command()
- def on_but_f3_run_clicked(self, button):
- def clear_ff_file():
- if os.path.exists(Vars.outdir + '/' + 'ffmpeg2pass-0.log'):
- os.remove(Vars.outdir + '/' + 'ffmpeg2pass-0.log')
- if os.path.exists(Vars.outdir + '/' + 'ffmpeg2pass-0.log.mbtree'):
- os.remove(Vars.outdir + '/' + 'ffmpeg2pass-0.log.mbtree')
- if os.path.exists(Vars.outdir + '/' + 'x264_lookahead.clbin'):
- os.remove(Vars.outdir + '/' + 'x264_lookahead.clbin')
- if os.path.exists(Vars.outdir + '/' + 'x265_2pass.log'):
- os.remove(Vars.outdir + '/' + 'x265_2pass.log')
- def end_run():
- if Vars.eff_pass == 0 and Vars.final_command1 == "":
- Vars.out_file_size = self.humansize(Vars.newname)
- stri = " Done in: " + self.sec2hms(Vars.time_done) + " " + "\n"\
- + " in: " + Vars.in_file_size + "\n"\
- + " out: " + Vars.out_file_size
- self.but_f3_run.set_tooltip_text(stri)
- stri2 = " Done in: " + self.sec2hms(Vars.time_done) + " "\
- + " input size: " + Vars.in_file_size + " "\
- + " output size: " + Vars.out_file_size
- self.reportdata.set_text(stri2)
- self.but_f3_run.set_label('RUN')
- self.window.set_deletable(True)
- clear_ff_file()
- Vars.ENCODING = False
- elif Vars.eff_pass == 0 and Vars.final_command1 != "":
- Vars.eff_pass = 1
- Vars.ENCODING = False
- self.on_but_f3_run_clicked(1)
- elif Vars.eff_pass == 1:
- Vars.out_file_size = self.humansize(Vars.newname)
- stri = " Done in: " + self.sec2hms(Vars.time_done + Vars.time_done_1) + " " + "\n"\
- + " pass 1: " + self.sec2hms(Vars.time_done) + " " + "\n"\
- + " pass 2: " + self.sec2hms(Vars.time_done_1) + " " + "\n"\
- + " in: " + Vars.in_file_size + "\n"\
- + " out: " + Vars.out_file_size
- self.but_f3_run.set_tooltip_text(stri)
- stri2 = " Done in: " + self.sec2hms(Vars.time_done + Vars.time_done_1) + " "\
- + " pass 1: " + self.sec2hms(Vars.time_done) + " "\
- + " pass 2: " + self.sec2hms(Vars.time_done_1) + " "\
- + " input size: " + Vars.in_file_size + " "\
- + " output size: " + Vars.out_file_size
- self.reportdata.set_text(stri2)
- Vars.eff_pass = 0
- self.but_f3_run.set_label('RUN')
- self.window.set_deletable(True)
- clear_ff_file()
- Vars.ENCODING = False
- def check_run(name):
- def win_controls(label, boolean):
- self.but_f3_run.set_label(label)
- self.window.set_deletable(boolean)
- self.but_f3_run.set_tooltip_text(' Abort current encoding ')
- def encod_time(startime):
- if Vars.time_done == 0:
- et = self.sec2hms(time.time() - startime)
- else:
- et = self.sec2hms((time.time() - startime) + Vars.time_done)
- self.but_f3_run.set_label(et + ' - STOP' )
- GLib.idle_add(win_controls, 'ENCODING ...' , False)
- time.sleep(0.02)
- t0 = time.time()
- processname = name
- for line in subprocess.Popen(["ps", "xa"], shell=False, stdout=subprocess.PIPE).stdout:
- line = line.decode()
- fields = line.split()
- pid = fields[0]
- process = fields[4]
- if process.find(processname) >= 0:
- if line.find(Vars.filename) >= 0:
- mypid = pid
- break
- finn = True
- while finn == True:
- GLib.idle_add(encod_time, t0)
- time.sleep(1)
- try:
- finn = os.path.exists("/proc/" + mypid)
- except:
- Vars.eff_pass = 0
- GLib.idle_add(win_controls, 'RUN' , True)
- time.sleep(0.02)
- Vars.ENCODING = False
- return
- if Vars.eff_pass == 0:
- tfin = time.time() - t0
- Vars.time_done = int(tfin)
- else:
- tfin = time.time() - t0
- Vars.time_done_1 = int(tfin)
- GLib.idle_add(end_run)
- time.sleep(0.5)
- if Vars.ENCODING: # STOP pressed
- Vars.final_command1 = "" # prevent 2 pass start
- command = "q"+ "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- return
- if Vars.eff_pass == 0:
- self.check_out_file()
- Vars.time_done = 0
- Vars.time_done_1 = 0
- if Vars.n_pass == 1:
- Vars.final_command1 = ""
- Vars.final_command2 = Vars.ffmpeg_ex + " -hide_banner"
- if Vars.ac3_drc != "":
- Vars.final_command2 += " " + Vars.ac3_drc
- Vars.final_command2 += " -i \"" \
- + Vars.filename + "\" " \
- + Vars.p3_command \
- + " \"" + Vars.newname + "\"" \
- + "\n"
- command = Vars.final_command2
- if Vars.n_pass == 2:
- Vars.final_command1 = Vars.ffmpeg_ex + " -hide_banner" + " -i \"" \
- + Vars.filename + "\" " \
- + Vars.p3_comm_first_p \
- + "\n"
- Vars.final_command2 = Vars.ffmpeg_ex + " -hide_banner"
- if Vars.ac3_drc != "":
- Vars.final_command2 += " " + Vars.ac3_drc
- Vars.final_command2 += " -i \"" \
- + Vars.filename + "\" " \
- + Vars.p3_command \
- + " \"" + Vars.newname + "\"" \
- + "\n"
- command = Vars.final_command1
- else:
- command = Vars.final_command2
- if Vars.debug == 1:
- if Vars.n_pass == 1:
- command = "echo $\'\n\n\n" + Vars.final_command2 + "\' \n"
- if Vars.n_pass == 2:
- command = "echo $\'\n\n\n" + Vars.final_command1 + "\n" + Vars.final_command2 + "\' \n"
- length = len(command)
- #
- if Vars.debug == 0:
- if Vars.eff_pass != 1:
- self.but_f3_run.set_tooltip_text('')
- self.reportdata.set_text('')
- Vars.ENCODING = True
- self.terminal.feed_child(command, length)
- if Vars.debug == 0:
- t = threading.Thread(name='child procs', target=check_run, args=(Vars.ffmpeg_ex,))
- t.daemon = True
- t.start()
- def on_folder_clicked(self, button):
- if Vars.ENCODING:
- return
- dialog = Gtk.FileChooserDialog("Please choose a folder", self.window,
- Gtk.FileChooserAction.SELECT_FOLDER,
- ("_Cancel", Gtk.ResponseType.CANCEL,
- "_Select", Gtk.ResponseType.OK))
- dialog.set_default_size(800, 400)
- dialog.set_current_folder(Vars.outdir)
- response = dialog.run()
- if response == Gtk.ResponseType.OK:
- Vars.outdir = dialog.get_filename()
- command = "cd " + "\"" + Vars.outdir + "\"" + "\n"
- length = len(command)
- self.terminal.feed_child(command, length)
- self.f3_run_outdir_label.set_markup("<b>out dir: </b>" + Vars.outdir)
- self.check_out_file()
- dialog.destroy()
- def on_but_black_det_clicked(self, button):
- def update_progress(pprog):
- self.progressbar_black_det.set_fraction(pprog)
- return False
- def update_textv(stri):
- self.textbuffer.insert_at_cursor(stri, -1)
- i = self.textbuffer.get_end_iter()
- self.textview.scroll_to_iter(i, 0.0, True, 0.0, 1.0)
- return False
- def stopped():
- stri = "Stopped by user.\n"
- self.textbuffer.insert_at_cursor(stri, -1)
- i = self.textbuffer.get_end_iter()
- self.textview.scroll_to_iter(i, 0.0, True, 0.0, 1.0)
- self.but_black_det.set_label("Black detect")
- self.blackdet_spin.stop()
- self.blackdet_spin.set_sensitive(False)
- self.progressbar_black_det.set_fraction(0.0)
- Vars.blackdet_is_run = False
- set_other_butt(True)
- def bd_finish(detected):
- if detected == 0:
- stri = "none black gap found"
- self.textbuffer.insert_at_cursor(stri, -1)
- self.blackdet_spin.stop()
- self.blackdet_spin.set_sensitive(False)
- self.but_black_det.set_label("black detectet")
- self.progressbar_black_det.set_fraction(1.0)
- Vars.blackdet_is_run = False
- Vars.BLACKDT_DONE = True
- set_other_butt(True)
- def set_other_butt(boolean):
- if Vars.VOLDT_DONE != True:
- self.but_volume_det.set_sensitive(boolean)
- if Vars.FRAMDT_DONE != True:
- self.but_frames_det.set_sensitive(boolean)
- def my_thread_blackdet():
- Vars.blackdet_is_run = True
- command = [Vars.ffmpeg_ex, '-i', Vars.filename, '-y', '-an', '-vf', 'blackdetect=d=.5', '-f', 'null', '/dev/null']
- p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, universal_newlines=True)
- self.bd_th = False
- detected = 0
- time_step = 0
- pprog = 0.0
- stri = ""
- GLib.idle_add(set_other_butt, False)
- time.sleep(0.01)
- while True:
- line = p.stderr.readline()
- if 'time=' in line:
- if time_step == 12:
- tml = line.split('time=')[1]
- tml2 = tml.split(' ')[0]
- time_n = tml2.split('.')[0]
- time_n = self.hms2sec(time_n)
- time_step = 0
- pprog = float(time_n)/Vars.duration_in_sec
- GLib.idle_add(update_progress, pprog)
- time.sleep(0.002)
- else:
- time_step += 1
- if 'blackdetect ' in line:
- a = line
- b = a.split('black_start:')[1]
- start = b.split(' ')[0]
- st_in_s = float(start)
- st_in_s = int(st_in_s)
- start_in_s = ("%4.1i"% (st_in_s))
- start = self.sec2hms(start)
- stri = "black start at: " + start_in_s + " s, " + start + " "
- c = b.split('black_duration:')[1]
- durat = c.split(' ')[0]
- dur_s = float(durat)
- dur_s = "{0:0=3.1f}".format(dur_s)
- stri += "duration: " + dur_s + "s\n"
- detected = 1
- GLib.idle_add(update_textv, stri)
- time.sleep(0.002)
- if line == '' and p.poll() != None:
- break
- if self.bd_th:
- p.communicate("q")
- break
- try:
- p.communicate()
- except:
- GLib.idle_add(stopped)
- time.sleep(0.1)
- return
- GLib.idle_add(bd_finish, detected)
- time.sleep(0.1)
- if Vars.BLACKDT_DONE:
- return
- if Vars.blackdet_is_run == False:
- self.but_black_det.set_label("Stop")
- self.textbuffer.set_text('') # clear for insert from start
- stri = "Detected:\n\n"
- start = self.textbuffer.get_start_iter()
- self.textbuffer.insert(start, stri, -1)
- self.blackdet_spin.set_sensitive(True)
- self.blackdet_spin.start()
- thread = threading.Thread(target=my_thread_blackdet)
- thread.daemon = True
- thread.start()
- elif Vars.blackdet_is_run == True:
- self.bd_th = True
- # -------------------------------------
- def preview_logic(self):
- if not('-map ' in Vars.p3_command or '-vf ' in Vars.p3_command):
- self.buttest.set_sensitive(False)
- self.buttestspl.set_sensitive(False)
- elif '-map ' in Vars.p3_command and '-vf ' in Vars.p3_command:
- self.buttest.set_sensitive(False)
- self.buttestspl.set_sensitive(False)
- elif '-map ' in Vars.p3_command:
- self.buttest.set_sensitive(True)
- self.buttestspl.set_sensitive(False)
- elif '-vf ' in Vars.p3_command:
- self.buttest.set_sensitive(True)
- self.buttestspl.set_sensitive(True)
- def scale_calc(self):
- dim_round = 2
- if self.check_round.get_active():
- dim_round = 8
- Vars.scalestr = ""
- # dar
- dar = self.box_scale_ar['cbox'].get_active()
- if dar == 0: # 16/9
- scale_factor = 1.777777778
- setdar = ",setdar=16/9,setsar=1/1"
- elif dar == 1: # 4/3
- scale_factor = 1.333333333
- setdar = ",setdar=4/3,setsar=1/1"
- elif dar == 2: # 235/100
- scale_factor = 2.35
- setdar = ",setdar=235/100,setsar=1/1"
- elif dar == 3: #1/1 same as input
- w = int(Vars.video_width)
- h = int(Vars.video_height)
- # cropped?
- if self.checkcr.get_active():
- crT = int(self.spinct['adj'].get_value())
- crB = int(self.spincb['adj'].get_value())
- crL = int(self.spincl['adj'].get_value())
- crR = int(self.spincr['adj'].get_value())
- h = h - crT - crB
- w = w - crL - crR
- scale_factor = (float(w) / h)
- setdar = ""
- #input number
- num_in = self.size_spinner['adj'].get_value()
- #side in
- side = self.box_scale_side['cbox'].get_active() # 0 none, 1 W, 2 H
- if side == 1:
- wout = num_in
- hout = wout / float(scale_factor)
- elif side == 2:
- hout = num_in
- wout = hout * float(scale_factor)
- wout = int(round(float(wout)/dim_round)*dim_round)
- hout = int(round(float(hout)/dim_round)*dim_round)
- # scale string
- scalestr = str(wout) + ":" + str(hout)
- #
- zscale = self.check.get_active()
- if zscale:
- Vars.scalestr = "zscale=" + scalestr + ":f=lanczos" + setdar
- else:
- Vars.scalestr = "scale=" + scalestr + ":flags=lanczos" + setdar
- self.outfilter()
- def outfilter(self):
- final_str = ""
- if Vars.deint_str != "":
- final_str += Vars.deint_str
- if Vars.crop_str != "":
- if final_str == "":
- final_str += Vars.crop_str
- else:
- final_str += "," + Vars.crop_str
- if Vars.scalestr != "":
- if final_str == "":
- final_str += Vars.scalestr
- else:
- final_str += "," + Vars.scalestr
- if Vars.dn_str != "":
- if final_str == "":
- final_str += Vars.dn_str
- else:
- final_str += "," + Vars.dn_str
- if Vars.uns_str != "":
- if final_str == "":
- final_str += Vars.uns_str
- else:
- final_str += "," + Vars.uns_str
- Vars.filter_test_str = final_str
- if final_str != "":
- Vars.final_vf_str = "-vf " + final_str
- else:
- Vars.final_vf_str = ""
- label_str = ""
- if Vars.maps_str != "":
- label_str += Vars.maps_str + " "
- if Vars.time_final_str != "":
- label_str += Vars.time_final_str + " "
- if Vars.fr_str != "":
- label_str += Vars.fr_str + " "
- if Vars.final_vf_str != "":
- label_str += Vars.final_vf_str
- self.labelout.set_text(label_str)
- self.make_p3_out_command()
- if Vars.info_str != "":
- self.preview_logic()
- def make_p3_out_command(self):
- def x265_pass_com(string_eval, npass): # string , int (1-2)
- datainfo = string_eval.split(' ')
- pointer = datainfo.index('-x265-params')
- x265opts0 = datainfo[pointer+1]
- x265opts1 = x265opts0 + ":pass=" + str(npass) + " "
- string_eval = string_eval.replace(x265opts0, x265opts1)
- return string_eval
- def libsoxr_apply(string_eval):
- if 'aresample=matrix_encoding=dplii' in string_eval:
- string_eval = string_eval.replace('aresample=matrix_encoding=dplii', 'aresample=matrix_encoding=dplii:resampler=soxr')
- elif 'aformat=channel_layouts=stereo' in string_eval:
- string_eval = string_eval.replace('aformat=channel_layouts=stereo', 'aformat=channel_layouts=stereo,aresample=resampler=soxr')
- else:
- string_eval = 'aresample=resampler=soxr,' + string_eval
- return string_eval
- # encoding video? audio?
- v_encod = Vars.vcodec_is != "vcopy" and Vars.vcodec_is != "none" # vcopy vn
- a_encod = Vars.acodec_is != "acopy" and Vars.acodec_is != "anone" # acopy an
- Vars.p3_command = ""
- Vars.p3_comm_first_p = ""
- self.f3_out_label.set_label("")
- if Vars.maps_str != "":
- Vars.p3_command = Vars.maps_str + " "
- if Vars.time_final_str != "":
- Vars.p3_command += Vars.time_final_str + " "
- if Vars.fr_str != "" and v_encod:
- Vars.p3_command += Vars.fr_str + " "
- if Vars.final_vf_str != "" and v_encod: # check -vcopy
- Vars.p3_command += Vars.final_vf_str + " "
- # first pass
- if Vars.first_pass:
- Vars.p3_comm_first_p = Vars.p3_command + Vars.video_codec_str + " "
- if Vars.vcodec_is == "x265":
- Vars.p3_comm_first_p = x265_pass_com(Vars.p3_comm_first_p, 1)
- else:
- Vars.p3_comm_first_p += "-pass 1 "
- if Vars.vcodec_is == "x264":
- Vars.p3_comm_first_p += "-fastfirstpass 1 "
- Vars.p3_comm_first_p += "-an -f null /dev/null"
- else:
- Vars.p3_comm_first_p = ""
- # -af
- audiof = ""
- if Vars.final_af_str != "" and a_encod: # check -acopy -an
- audiof_1 = Vars.final_af_str
- else:
- audiof_1 = ""
- if (Vars.compand_data != "" or Vars.dynaudnorm_data != "") and a_encod: # check -acopy -an
- if Vars.compand_data != "":
- audiof_2 = Vars.compand_data
- elif Vars.dynaudnorm_data != "":
- audiof_2 = Vars.dynaudnorm_data
- else:
- audiof_2 = ""
- if a_encod:
- if audiof_1 != "" and audiof_2 != "":
- audiof = audiof_1 + "," + audiof_2
- elif audiof_1 != "" and audiof_2 == "":
- if Vars.audio_channels == 6 and self.box_audio_ch.get_active_text() == '2' and self.check_prologic.get_active():
- audiof = 'aformat=channel_layouts=stereo,aresample=matrix_encoding=dplii,' + audiof_1
- else:
- audiof = audiof_1
- elif audiof_1 == "" and audiof_2 != "":
- audiof = audiof_2
- elif audiof_1 == "" and audiof_2 == "":
- if Vars.audio_channels == 6 and self.box_audio_ch.get_active_text() == '2' and self.check_prologic.get_active():
- audiof = 'aformat=channel_layouts=stereo,aresample=matrix_encoding=dplii'
- # libsoxr
- if self.check_soxr.get_sensitive() and self.check_soxr.get_active():
- if audiof == "":
- audiof = 'aresample=resampler=soxr'
- else:
- audiof = libsoxr_apply(audiof)
- #
- if audiof != "":
- Vars.p3_command += "-af \'" + audiof + "\' "
- Vars.final_codec_str = Vars.audio_codec_str + " " + Vars.video_codec_str
- if Vars.final_codec_str != "":
- Vars.p3_command += Vars.final_codec_str + " "
- #second pass
- if Vars.n_pass == 2:
- if Vars.vcodec_is != "x265":
- Vars.p3_command += "-pass 2" + " "
- elif Vars.vcodec_is == "x265":
- Vars.p3_command = x265_pass_com(Vars.p3_command, 2)
- if Vars.container_str != "":
- Vars.p3_command += Vars.container_str + " "
- if Vars.final_other_str != "":
- Vars.p3_command += Vars.final_other_str + " "
- self.f3_out_label.set_label(Vars.p3_command)
- def main(self):
- Gtk.main()
- if __name__ == "__main__":
- GObject.threads_init()
- ProgrammaGTK()
- Gtk.main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement