"Fossies" - the Fresh Open Source Software Archive

Member "ffmulticonverter-1.8.0/ffmulticonverter/audiovideotab.py" (25 Jun 2016, 23162 Bytes) of package /linux/privat/ffmulticonverter-1.8.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "audiovideotab.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.7.2_vs_1.8.0.

    1 # Copyright (C) 2011-2016 Ilias Stamatis <stamatis.iliass@gmail.com>
    2 #
    3 # This program is free software: you can redistribute it and/or modify
    4 # it under the terms of the GNU General Public License as published by
    5 # the Free Software Foundation, either version 3 of the License, or
    6 # (at your option) any later version.
    7 #
    8 # This program is distributed in the hope that it will be useful,
    9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
   10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11 # GNU General Public License for more details.
   12 #
   13 # You should have received a copy of the GNU General Public License
   14 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
   15 
   16 import re
   17 
   18 from PyQt5.QtGui import QRegExpValidator
   19 from PyQt5.QtCore import QRegExp, QSize, QTimer
   20 from PyQt5.QtWidgets import (
   21         QApplication, QWidget, QComboBox, QLineEdit, QLabel, QPushButton,
   22         QCheckBox, QRadioButton, QHBoxLayout, QSpacerItem, QSizePolicy, QFrame,
   23         QButtonGroup, QMessageBox, QToolButton, QFileDialog
   24         )
   25 
   26 from ffmulticonverter import utils
   27 from ffmulticonverter import presets_dlgs
   28 from ffmulticonverter import config
   29 
   30 
   31 class AudioVideoTab(QWidget):
   32     def __init__(self, parent):
   33         super(AudioVideoTab, self).__init__(parent)
   34         self.parent = parent
   35         self.name = 'AudioVideo'
   36 
   37         self.defaultStr = self.tr('Default')
   38         self.DisableStream = self.tr('Disable')
   39 
   40         self.formats = config.video_formats
   41         frequency_values = [self.defaultStr] + config.video_frequency_values
   42         bitrate_values = [self.defaultStr] + config.video_bitrate_values
   43 
   44         rotation_options = [
   45                 self.tr('None'),
   46                 '90 ' + self.tr('clockwise'),
   47                 '90 ' + self.tr('clockwise') + ' + ' + self.tr('vertical flip'),
   48                 '90 ' + self.tr('counter clockwise'),
   49                 '90 ' + self.tr('counter clockwise') +
   50                 ' + ' + self.tr('vertical flip'),
   51                 '180',
   52                 self.tr('horizontal flip'),
   53                 self.tr('vertical flip')
   54                 ]
   55 
   56         digits_validator = QRegExpValidator(QRegExp(r'[1-9]\d*'), self)
   57         digits_validator_wzero = QRegExpValidator(QRegExp(r'\d*'), self)
   58         digits_validator_minus = QRegExpValidator(QRegExp(r'(-1|[1-9]\d*)'), self)
   59         time_validator = QRegExpValidator(
   60                 QRegExp(r'\d{1,2}:\d{1,2}:\d{1,2}\.\d+'), self)
   61 
   62         converttoQL = QLabel(self.tr('Convert to:'))
   63         self.extQCB = QComboBox()
   64         self.extQCB.setMinimumWidth(100)
   65         vidcodecQL = QLabel('Video codec:')
   66         self.vidcodecQCB = QComboBox()
   67         self.vidcodecQCB.setMinimumWidth(110)
   68         audcodecQL = QLabel('Audio codec:')
   69         self.audcodecQCB = QComboBox()
   70         self.audcodecQCB.setMinimumWidth(110)
   71 
   72         hlayout1 = utils.add_to_layout(
   73                 'h', converttoQL, self.extQCB, QSpacerItem(180, 20),
   74                 vidcodecQL, self.vidcodecQCB, audcodecQL, self.audcodecQCB)
   75 
   76         commandQL = QLabel(self.tr('Command:'))
   77         self.commandQLE = QLineEdit()
   78         self.presetQPB = QPushButton(self.tr('Preset'))
   79         self.defaultQPB = QPushButton(self.defaultStr)
   80         hlayout2 = utils.add_to_layout(
   81                 'h', commandQL, self.commandQLE, self.presetQPB,
   82                 self.defaultQPB)
   83 
   84         sizeQL = QLabel(self.tr('Video Size:'))
   85         aspectQL = QLabel(self.tr('Aspect:'))
   86         frameQL = QLabel(self.tr('Frame Rate (fps):'))
   87         bitrateQL = QLabel(self.tr('Video Bitrate (kbps):'))
   88 
   89         self.widthQLE = utils.create_LineEdit(
   90                 (70, 16777215), digits_validator_minus, 4)
   91         self.heightQLE = utils.create_LineEdit(
   92                 (70, 16777215), digits_validator_minus, 4)
   93         label = QLabel('<html><p align="center">x</p></html>')
   94         layout1 = utils.add_to_layout('h', self.widthQLE, label,self.heightQLE)
   95         self.aspect1QLE = utils.create_LineEdit(
   96                 (50, 16777215), digits_validator, 2)
   97         self.aspect2QLE = utils.create_LineEdit(
   98                 (50, 16777215), digits_validator, 2)
   99         label = QLabel('<html><p align="center">:</p></html>')
  100         layout2 = utils.add_to_layout(
  101                 'h', self.aspect1QLE, label, self.aspect2QLE)
  102         self.frameQLE = utils.create_LineEdit(
  103                 (120, 16777215), digits_validator, 4)
  104         self.bitrateQLE = utils.create_LineEdit(
  105                 (130, 16777215), digits_validator, 6)
  106 
  107         labels = [sizeQL, aspectQL, frameQL, bitrateQL]
  108         widgets = [layout1, layout2, self.frameQLE, self.bitrateQLE]
  109 
  110         self.preserveaspectQChB = QCheckBox(self.tr("Preserve aspect ratio"))
  111         self.preservesizeQChB = QCheckBox(self.tr("Preserve video size"))
  112 
  113         preserve_layout = utils.add_to_layout(
  114                 'v', self.preserveaspectQChB, self.preservesizeQChB)
  115 
  116         videosettings_layout = QHBoxLayout()
  117         for a, b in zip(labels, widgets):
  118             a.setText('<html><p align="center">{0}</p></html>'.format(a.text()))
  119             layout = utils.add_to_layout('v', a, b)
  120             videosettings_layout.addLayout(layout)
  121             if a == aspectQL:
  122                 # add vidaspectCB in layout after aspectQL
  123                 videosettings_layout.addLayout(preserve_layout)
  124 
  125         freqQL = QLabel(self.tr('Frequency (Hz):'))
  126         chanQL = QLabel(self.tr('Audio Channels:'))
  127         bitrateQL = QLabel(self.tr('Audio Bitrate (kbps):'))
  128         threadsQL = QLabel(self.tr('Threads:'))
  129 
  130         self.freqQCB = QComboBox()
  131         self.freqQCB.addItems(frequency_values)
  132         self.chan1QRB = QRadioButton('1')
  133         self.chan1QRB.setMaximumSize(QSize(51, 16777215))
  134         self.chan2QRB = QRadioButton('2')
  135         self.chan2QRB.setMaximumSize(QSize(51, 16777215))
  136         self.group = QButtonGroup()
  137         self.group.addButton(self.chan1QRB)
  138         self.group.addButton(self.chan2QRB)
  139         spcr1 = QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Minimum)
  140         spcr2 = QSpacerItem(40, 20, QSizePolicy.Preferred, QSizePolicy.Minimum)
  141         chanlayout = utils.add_to_layout(
  142                 'h', spcr1, self.chan1QRB, self.chan2QRB, spcr2)
  143         self.audbitrateQCB = QComboBox()
  144         self.audbitrateQCB.addItems(bitrate_values)
  145         self.threadsQLE = utils.create_LineEdit(
  146                 (50, 16777215), digits_validator_wzero, 1)
  147 
  148         labels = [freqQL, bitrateQL, chanQL, threadsQL]
  149         widgets = [self.freqQCB, self.audbitrateQCB, chanlayout,self.threadsQLE]
  150 
  151         audiosettings_layout = QHBoxLayout()
  152         for a, b in zip(labels, widgets):
  153             a.setText('<html><p align="center">{0}</p></html>'.format(a.text()))
  154             layout = utils.add_to_layout('v', a, b)
  155             audiosettings_layout.addLayout(layout)
  156 
  157         time_format = " (hh:mm:ss):"
  158         beginQL = QLabel(self.tr("Split file. Begin time") + time_format)
  159         self.beginQLE = utils.create_LineEdit(None, time_validator, None)
  160         durationQL = QLabel(self.tr("Duration") + time_format)
  161         self.durationQLE = utils.create_LineEdit(None, time_validator, None)
  162 
  163         hlayout4 = utils.add_to_layout(
  164                 'h',  beginQL, self.beginQLE, durationQL, self.durationQLE)
  165 
  166         embedQL = QLabel(self.tr("Embed subtitle:"))
  167         self.embedQLE = QLineEdit()
  168         self.embedQTB = QToolButton()
  169         self.embedQTB.setText("...")
  170 
  171         rotateQL = QLabel(self.tr("Rotate:"))
  172         self.rotateQCB = QComboBox()
  173         self.rotateQCB.addItems(rotation_options)
  174 
  175         hlayout5 = utils.add_to_layout(
  176                 'h', rotateQL, self.rotateQCB, embedQL, self.embedQLE,
  177                 self.embedQTB)
  178 
  179         hidden_layout = utils.add_to_layout(
  180                 'v', videosettings_layout, audiosettings_layout,
  181                 hlayout4, hlayout5)
  182 
  183         line = QFrame()
  184         line.setFrameShape(QFrame.HLine)
  185         line.setFrameShadow(QFrame.Sunken)
  186         self.moreQPB = QPushButton(QApplication.translate('Tab', 'More'))
  187         self.moreQPB.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
  188         self.moreQPB.setCheckable(True)
  189         hlayout3 = utils.add_to_layout('h', line, self.moreQPB)
  190 
  191         self.frame = QFrame()
  192         self.frame.setLayout(hidden_layout)
  193         self.frame.hide()
  194 
  195         final_layout = utils.add_to_layout(
  196                 'v', hlayout1, hlayout2, hlayout3, self.frame)
  197         self.setLayout(final_layout)
  198 
  199         self.presetQPB.clicked.connect(self.choose_preset)
  200         self.defaultQPB.clicked.connect(self.set_default_command)
  201         self.embedQTB.clicked.connect(self.open_subtitle_file)
  202         self.moreQPB.toggled.connect(self.frame.setVisible)
  203         self.moreQPB.toggled.connect(
  204                 lambda: QTimer.singleShot(100, self.resize_parent))
  205         self.widthQLE.textChanged.connect(self.command_update_size)
  206         self.heightQLE.textChanged.connect(self.command_update_size)
  207         self.aspect1QLE.textChanged.connect(self.command_update_aspect)
  208         self.aspect2QLE.textChanged.connect(self.command_update_aspect)
  209         self.frameQLE.textChanged.connect(self.command_update_frames)
  210         self.bitrateQLE.textChanged.connect(self.command_update_vidbitrate)
  211         self.threadsQLE.textChanged.connect(self.command_update_threads)
  212         self.beginQLE.textChanged.connect(self.command_update_begin_time)
  213         self.durationQLE.textChanged.connect(self.command_update_duration)
  214         self.embedQLE.textChanged.connect(self.command_update_subtitles)
  215         self.vidcodecQCB.currentIndexChanged.connect(self.command_update_vcodec)
  216         self.audcodecQCB.currentIndexChanged.connect(self.command_update_acodec)
  217         self.freqQCB.currentIndexChanged.connect(self.command_update_frequency)
  218         self.rotateQCB.currentIndexChanged.connect(self.command_update_rotation)
  219         self.audbitrateQCB.currentIndexChanged.connect(
  220                 self.command_update_audbitrate)
  221         self.chan1QRB.clicked.connect(
  222                 lambda: self.command_update_channels('1'))
  223         self.chan2QRB.clicked.connect(
  224                 lambda: self.command_update_channels('2'))
  225         self.preserveaspectQChB.toggled.connect(
  226                 self.command_update_preserve_aspect)
  227         self.preservesizeQChB.toggled.connect(
  228                 self.command_update_preserve_size)
  229 
  230     def resize_parent(self):
  231         """Give MainWindow its default size."""
  232         self.parent.setMinimumSize(self.parent.sizeHint())
  233         self.parent.resize(self.parent.sizeHint())
  234 
  235     def clear(self):
  236         """Clear all values of graphical widgets."""
  237         lines = [
  238                 self.commandQLE, self.widthQLE, self.heightQLE,
  239                 self.aspect1QLE, self.aspect2QLE, self.frameQLE,
  240                 self.bitrateQLE, self.threadsQLE, self.beginQLE,
  241                 self.embedQLE, self.durationQLE
  242                 ]
  243         for i in lines:
  244             i.clear()
  245 
  246         self.vidcodecQCB.setCurrentIndex(0)
  247         self.audcodecQCB.setCurrentIndex(0)
  248         self.freqQCB.setCurrentIndex(0)
  249         self.audbitrateQCB.setCurrentIndex(0)
  250         self.rotateQCB.setCurrentIndex(0)
  251         self.preserveaspectQChB.setChecked(False)
  252         self.preservesizeQChB.setChecked(False)
  253         self.group.setExclusive(False)
  254         self.chan1QRB.setChecked(False)
  255         self.chan2QRB.setChecked(False)
  256         self.group.setExclusive(True)
  257         # setExclusive(False) in order to be able to uncheck checkboxes and
  258         # then setExclusive(True) so only one radio button can be set
  259 
  260     def fill_video_comboboxes(self, vcodecs, acodecs, extraformats):
  261         self.vidcodecQCB.currentIndexChanged.disconnect()
  262         self.audcodecQCB.currentIndexChanged.disconnect()
  263 
  264         self.vidcodecQCB.clear()
  265         self.audcodecQCB.clear()
  266         self.extQCB.clear()
  267         self.vidcodecQCB.addItems([self.defaultStr, self.DisableStream] + vcodecs)
  268         self.audcodecQCB.addItems([self.defaultStr, self.DisableStream] + acodecs)
  269         self.extQCB.addItems(sorted(self.formats + extraformats))
  270 
  271         self.vidcodecQCB.currentIndexChanged.connect(self.command_update_vcodec)
  272         self.audcodecQCB.currentIndexChanged.connect(self.command_update_acodec)
  273 
  274     def ok_to_continue(self):
  275         """
  276         Check if everything is ok with audiovideotab to continue conversion.
  277         Returns boolean.
  278         """
  279         if not self.parent.ffmpeg_path:
  280             QMessageBox.warning(self, 'FF Multi Converter - ' + self.tr(
  281                 'Error!'), self.tr('FFmpeg is not installed!'))
  282             return False
  283         return True
  284 
  285     def open_subtitle_file(self):
  286         fname = QFileDialog.getOpenFileName(
  287                 self, 'FF Multi Converter - ' + self.tr('Choose File'),
  288                 config.home, 'Subtitles (*.srt *.sub *.ssa *.ass)'
  289                 )[0]
  290         if fname:
  291             self.embedQLE.setText(fname)
  292 
  293     def set_default_command(self):
  294         """Set the default value to self.commandQLE."""
  295         self.clear()
  296         self.commandQLE.setText(self.parent.default_command)
  297 
  298     def choose_preset(self):
  299         """
  300         Open the presets dialog and update self.commandQLE,
  301         and self.extQCB and with the appropriate values.
  302         """
  303         dialog = presets_dlgs.ShowPresets(choose=True)
  304         if dialog.exec_() and dialog.the_command is not None:
  305             self.clear()
  306             self.commandQLE.setText(dialog.the_command)
  307             self.commandQLE.home(False)
  308             find = self.extQCB.findText(dialog.the_extension)
  309             if find >= 0:
  310                 self.extQCB.setCurrentIndex(find)
  311 
  312     def command_update_size(self):
  313         command = self.commandQLE.text()
  314         text1 = self.widthQLE.text()
  315         text2 = self.heightQLE.text()
  316 
  317         if not (text1 == '-1' or text2 == '-1'):
  318             self.preserveaspectQChB.setChecked(False)
  319 
  320         if (text1 or text2) and not (text1 and text2) or (text1 == '-' or
  321                 text2 == '-'):
  322             return
  323 
  324         regex = r'(\s+|^)-s(:v){0,1}\s+\d+x\d+(\s+|$)'
  325         if re.search(regex, command):
  326             command = re.sub(regex, '', command)
  327 
  328         regex = r'(,*\s*){0,1}(scale=-?\d+:-?\d+)(\s*,*\s*){0,1}'
  329         _filter = "scale={0}:{1}".format(text1, text2) if text1 and text2 else ''
  330 
  331         self.commandQLE.setText(utils.update_cmdline_text(
  332                 command, _filter, regex, bool(text1 and text2), 0, 2))
  333 
  334     def command_update_preserve_size(self):
  335         checked = self.preservesizeQChB.isChecked()
  336 
  337         self.widthQLE.setEnabled(not checked)
  338         self.heightQLE.setEnabled(not checked)
  339 
  340         if checked:
  341             self.widthQLE.clear()
  342             self.heightQLE.clear()
  343             # command_update_size() is triggered here
  344 
  345         command = self.commandQLE.text()
  346         regex = r'(\s+|^)-s\s+\d+x\d+(\s+|$)'
  347         command = re.sub(' +', ' ', re.sub(regex, ' ', command)).strip()
  348         self.commandQLE.setText(command)
  349 
  350     def command_update_aspect(self):
  351         command = self.commandQLE.text()
  352         text1 = self.aspect1QLE.text()
  353         text2 = self.aspect2QLE.text()
  354 
  355         if (text1 or text2) and not (text1 and text2):
  356             return
  357 
  358         regex = r'(\s+|^)-aspect\s+\d+:\d+(\s+|$)'
  359         s = ' -aspect {0}:{1} '.format(text1, text2) if text1 and text2 else ' '
  360 
  361         if re.search(regex, command):
  362             command = re.sub(regex, s, command)
  363         else:
  364             command += s
  365 
  366         command = re.sub(' +', ' ', command).strip()
  367         self.commandQLE.setText(command)
  368 
  369     def command_update_preserve_aspect(self):
  370         command = self.commandQLE.text()
  371         checked = self.preserveaspectQChB.isChecked()
  372 
  373         self.aspect1QLE.setEnabled(not checked)
  374         self.aspect2QLE.setEnabled(not checked)
  375 
  376         if checked:
  377             self.aspect1QLE.clear()
  378             self.aspect2QLE.clear()
  379             # self.command_update_aspect() is triggered here
  380 
  381             regex = r'(,*\s*){0,1}(scale=(-?\d+):(-?\d+))(\s*,*\s*){0,1}'
  382             search = re.search(regex, command)
  383             if search:
  384                 width = search.groups()[2]
  385                 height = search.groups()[3]
  386                 if not (width == '-1' or height == '-1'):
  387                     s = "scale=-1:{0}".format(height)
  388                     command = re.sub(regex, r'\1{0}\5'.format(s), command)
  389                     self.widthQLE.setText('-1')
  390                     self.heightQLE.setText(height)
  391 
  392         regex = r'(\s+|^)-aspect\s+\d+:\d+(\s+|$)'
  393         command = re.sub(' +', ' ', re.sub(regex, ' ', command)).strip()
  394         self.commandQLE.setText(command)
  395 
  396     def command_update_frames(self):
  397         command = self.commandQLE.text()
  398         text = self.frameQLE.text()
  399 
  400         regex = r'(\s+|^)-r\s+\d+(\s+|$)'
  401         s = ' -r {0} '.format(text) if text else ' '
  402 
  403         if re.search(regex, command):
  404             command = re.sub(regex, s, command)
  405         else:
  406             command += s
  407 
  408         command = re.sub(' +', ' ', command).strip()
  409         self.commandQLE.setText(command)
  410 
  411     def command_update_vidbitrate(self):
  412         command = self.commandQLE.text()
  413         text = self.bitrateQLE.text()
  414 
  415         regex = r'(\s+|^)-b(:v){0,1}\s+\d+[kKmM](\s+|$)'
  416         s = ' -b:v {0}k '.format(text) if text else ' '
  417 
  418         if re.search(regex, command):
  419             command = re.sub(regex, s, command)
  420         else:
  421             command += s
  422 
  423         command = re.sub('-sameq', '', command)
  424         command = re.sub(' +', ' ', command).strip()
  425 
  426         self.commandQLE.setText(command)
  427 
  428     def command_update_frequency(self):
  429         command = self.commandQLE.text()
  430         text = self.freqQCB.currentText()
  431 
  432         regex = r'(\s+|^)-ar\s+\d+(\s+|$)'
  433         s = ' -ar {0} '.format(text) if self.freqQCB.currentIndex() != 0 else ' '
  434 
  435         if re.search(regex, command):
  436             command = re.sub(regex, s, command)
  437         else:
  438             command += s
  439 
  440         command = re.sub(' +', ' ', command).strip()
  441         self.commandQLE.setText(command)
  442 
  443     def command_update_audbitrate(self):
  444         command = self.commandQLE.text()
  445         text = self.audbitrateQCB.currentText()
  446 
  447         regex = r'(\s+|^)-(ab|b:a)\s+\d+[kKmM](\s+|$)'
  448         if self.audbitrateQCB.currentIndex() != 0:
  449             s = ' -b:a {0}k '.format(text)
  450         else:
  451             s = ' '
  452 
  453         if re.search(regex, command):
  454             command = re.sub(regex, s, command)
  455         else:
  456             command += s
  457 
  458         command = re.sub(' +', ' ', command).strip()
  459         self.commandQLE.setText(command)
  460 
  461     def command_update_channels(self, channel):
  462         command = self.commandQLE.text()
  463 
  464         regex = r'(\s+|^)-ac\s+\d+(\s+|$)'
  465         s = ' -ac {0} '.format(channel)
  466 
  467         if re.search(regex, command):
  468             command = re.sub(regex, s, command)
  469         else:
  470             command += s
  471 
  472         command = re.sub(' +', ' ', command).strip()
  473         self.commandQLE.setText(command)
  474 
  475     def command_update_threads(self):
  476         command = self.commandQLE.text()
  477         text = self.threadsQLE.text()
  478 
  479         regex = r'(\s+|^)-threads\s+\d+(\s+|$)'
  480         s = ' -threads {0} '.format(text) if text else ' '
  481 
  482         if re.search(regex, command):
  483             command = re.sub(regex, s, command)
  484         else:
  485             command += s
  486 
  487         command = re.sub(' +', ' ', command).strip()
  488         self.commandQLE.setText(command)
  489 
  490     def command_update_begin_time(self):
  491         command = self.commandQLE.text()
  492         text = self.beginQLE.text()
  493 
  494         regex = r'(\s+|^)-ss\s+\S+(\s+|$)'
  495         s = ' -ss {0} '.format(text) if text else ' '
  496 
  497         if re.search(regex, command):
  498             command = re.sub(regex, s, command)
  499         else:
  500             command += s
  501 
  502         command = re.sub(' +', ' ', command).strip()
  503         self.commandQLE.setText(command)
  504 
  505     def command_update_duration(self):
  506         command = self.commandQLE.text()
  507         text = self.durationQLE.text()
  508 
  509         regex = r'(\s+|^)-t\s+\S+(\s+|$)'
  510         s = ' -t {0} '.format(text) if text else ' '
  511 
  512         if re.search(regex, command):
  513             command = re.sub(regex, s, command)
  514         else:
  515             command += s
  516 
  517         command = re.sub(' +', ' ', command).strip()
  518         self.commandQLE.setText(command)
  519 
  520     def command_update_vcodec(self):
  521         command = self.commandQLE.text()
  522         text = self.vidcodecQCB.currentText()
  523 
  524         regex = r'(\s+|^)-(vcodec|c:v)\s+\S+(\s+|$)'
  525         regex_vn = r'(\s+|^)-vn(\s+|$)'
  526         if self.vidcodecQCB.currentIndex() == 1:
  527             s = ' -vn '.format(text)
  528         elif self.vidcodecQCB.currentIndex() == 0:
  529             s = ' '
  530         else:
  531             s = ' -vcodec {0} '.format(text)
  532 
  533         if re.search(regex, command):
  534             command = re.sub(regex, s, command)
  535         elif re.search(regex_vn, command):
  536             command = re.sub(regex_vn, s, command)
  537         else:
  538             command += s
  539 
  540         command = re.sub(' +', ' ', command).strip()
  541         self.commandQLE.setText(command)
  542 
  543     def command_update_acodec(self):
  544         command = self.commandQLE.text()
  545         text = self.audcodecQCB.currentText()
  546 
  547         regex = r'(\s+|^)-(acodec|c:a)\s+\S+(\s+|$)'
  548         regex_an = r'(\s+|^)-an(\s+|$)'
  549         if self.audcodecQCB.currentIndex() == 1:
  550             s = ' -an '.format(text)
  551         elif self.audcodecQCB.currentIndex() == 0:
  552             s = ' '
  553         else:
  554             s = ' -acodec {0} '.format(text)
  555 
  556         if re.search(regex, command):
  557             command = re.sub(regex, s, command)
  558         elif re.search(regex_an, command):
  559             command = re.sub(regex_an, s, command)
  560         else:
  561             command += s
  562 
  563         command = re.sub(' +', ' ', command).strip()
  564         self.commandQLE.setText(command)
  565 
  566     def command_update_subtitles(self):
  567         command = self.commandQLE.text()
  568         regex = r'(,*\s*){0,1}(subtitles=\'.*\')(\s*,*\s*){0,1}'
  569 
  570         text = self.embedQLE.text()
  571         _filter = "subtitles='{0}'".format(text) if text else ''
  572 
  573         self.commandQLE.setText(utils.update_cmdline_text(
  574                 command, _filter, regex, bool(text), 0, 2))
  575 
  576     def command_update_rotation(self):
  577         command = self.commandQLE.text()
  578         regex = r'(,*\s*){0,1}(transpose=\d(,\s*transpose=\d)*|vflip|hflip)(\s*,*\s*){0,1}'
  579 
  580         rotate = self.rotateQCB.currentIndex()
  581         if rotate == 0:   # none
  582             _filter = ''
  583         elif rotate == 1: # 90 clockwise
  584             _filter = 'transpose=1'
  585         elif rotate == 2: # 90 clockwise + vertical flip
  586             _filter = 'transpose=3'
  587         elif rotate == 3: # 90 counter clockwise
  588             _filter = 'transpose=2'
  589         elif rotate == 4: # 90 counter clockwise + vertical flip
  590             _filter = 'transpose=0'
  591         elif rotate == 5: # 180
  592             _filter = 'transpose=2,transpose=2'
  593         elif rotate == 6: # horizontal flip
  594             _filter = 'hflip'
  595         elif rotate == 7: # vertical flip
  596             _filter = 'vflip'
  597 
  598         self.commandQLE.setText(utils.update_cmdline_text(
  599                 command, _filter, regex, bool(rotate != 0), 0, 3))