Ejemplo n.º 1
0
    def __init__(self, parent, main):
        super(AV1, self).__init__(parent)
        self.main = main
        grid = QtWidgets.QGridLayout()

        self.widgets = Box(fps=None,
                           remove_hdr=None,
                           mode=None,
                           segment_size=None)

        self.mode = 'QP'

        grid.addLayout(self.init_remove_hdr(), 1, 0, 1, 2)
        grid.addLayout(self.init_speed(), 0, 0, 1, 2)

        grid.addLayout(self.init_modes(), 0, 2, 4, 4)
        grid.addLayout(self.init_segment_size(), 3, 0, 1, 2)

        grid.addWidget(QtWidgets.QWidget(), 5, 0)
        grid.setRowStretch(5, 1)
        guide_label = QtWidgets.QLabel(
            f"<a href='https://github.com/OpenVisualCloud/SVT-AV1'>SVT-AV1 Github</a>"
        )
        guide_label.setAlignment(QtCore.Qt.AlignBottom)
        guide_label.setOpenExternalLinks(True)
        grid.addWidget(guide_label, 9, 0, -1, 1)
        self.setLayout(grid)
        self.hide()
Ejemplo n.º 2
0
    def __init__(self, parent, main):
        super(AV1, self).__init__(parent)
        self.main = main

        grid = QtWidgets.QGridLayout()

        # grid.addWidget(QtWidgets.QLabel("FFMPEG libaom-av1"), 0, 0)

        self.widgets = Box(fps=None, remove_hdr=None, mode=None)

        self.mode = 'CRF'

        grid.addLayout(self.init_remove_hdr(), 0, 0, 1, 2)
        grid.addLayout(self.init_modes(), 0, 2, 3, 3)

        grid.addWidget(QtWidgets.QWidget(), 5, 0)
        grid.setRowStretch(5, 1)
        guide_label = QtWidgets.QLabel(
            f"<a href='https://trac.ffmpeg.org/wiki/Encode/AV1'>FFMPEG AV1 Encoding Guide</a>"
        )
        guide_label.setAlignment(QtCore.Qt.AlignBottom)
        guide_label.setOpenExternalLinks(True)
        grid.addWidget(guide_label, 9, 0, -1, 1)

        self.setLayout(grid)
        self.hide()
Ejemplo n.º 3
0
    def __init__(self, parent, main):
        super(VP9, self).__init__(parent)
        self.main = main

        grid = QtWidgets.QGridLayout()

        # grid.addWidget(QtWidgets.QLabel("VP9"), 0, 0)

        self.widgets = Box(
            fps=None,
            remove_hdr=None,
            mode=None)

        self.mode = 'CRF'

        grid.addLayout(self.init_remove_hdr(), 2, 0, 1, 2)
        grid.addLayout(self.init_modes(), 0, 2, 4, 4)
        grid.addLayout(self.init_quality(), 1, 0, 1, 2)
        grid.addLayout(self.init_speed(), 0, 0, 1, 2)

        grid.addLayout(self.init_row_mt(), 4, 0, 1, 2)
        grid.addLayout(self.init_force_420(), 5, 0, 1, 2)
        grid.addLayout(self.init_single_pass(), 6, 0, 1, 2)

        grid.addWidget(QtWidgets.QWidget(), 8, 0)
        grid.setRowStretch(8, 1)
        guide_label = QtWidgets.QLabel(f"<a href='https://trac.ffmpeg.org/wiki/Encode/VP9'>FFMPEG VP9 Encoding Guide</a>")
        guide_label.setAlignment(QtCore.Qt.AlignBottom)
        guide_label.setOpenExternalLinks(True)
        grid.addWidget(guide_label, 9, 0, -1, 1)
        self.setLayout(grid)
        self.hide()
Ejemplo n.º 4
0
    def init_modes(self):
        layout = QtWidgets.QGridLayout()
        crf_group_box = QtWidgets.QGroupBox()
        crf_group_box.setStyleSheet("QGroupBox{padding-top:5px; margin-top:-18px}")
        crf_box_layout = QtWidgets.QHBoxLayout()
        bitrate_group_box = QtWidgets.QGroupBox()
        bitrate_group_box.setStyleSheet("QGroupBox{padding-top:5px; margin-top:-18px}")
        bitrate_box_layout = QtWidgets.QHBoxLayout()
        # rotation_dir = Path(base_path, 'data', 'rotations')
        # group_box.setStyleSheet("QGroupBox{padding-top:15px; margin-top:-15px; padding-bottom:-5px}")
        self.widgets.mode = QtWidgets.QButtonGroup()
        self.widgets.mode.buttonClicked.connect(self.set_mode)

        bitrate_radio = QtWidgets.QRadioButton("Bitrate")
        bitrate_radio.setFixedWidth(80)
        self.widgets.mode.addButton(bitrate_radio)
        self.widgets.bitrate = QtWidgets.QComboBox()
        self.widgets.bitrate.setFixedWidth(250)
        self.widgets.bitrate.addItems(recommended_bitrates)
        self.widgets.bitrate.currentIndexChanged.connect(lambda: self.main.build_commands())
        self.widgets.bitrate.setCurrentIndex(6)
        self.widgets.custom_bitrate = QtWidgets.QLineEdit("3000")
        self.widgets.custom_bitrate.setFixedWidth(100)
        bitrate_box_layout.addWidget(bitrate_radio)
        bitrate_box_layout.addWidget(self.widgets.bitrate)
        bitrate_box_layout.addStretch()
        bitrate_box_layout.addWidget(QtWidgets.QLabel("Custom:"))
        bitrate_box_layout.addWidget(self.widgets.custom_bitrate)

        crf_radio = QtWidgets.QRadioButton("CRF")
        crf_radio.setChecked(True)
        crf_radio.setFixedWidth(80)
        self.widgets.mode.addButton(crf_radio)

        self.widgets.crf = QtWidgets.QComboBox()
        self.widgets.crf.setFixedWidth(250)
        self.widgets.crf.addItems(recommended_crfs)
        self.widgets.crf.setCurrentIndex(4)
        self.widgets.crf.currentIndexChanged.connect(lambda: self.main.build_commands())
        self.widgets.custom_crf = QtWidgets.QLineEdit("30")
        self.widgets.custom_crf.setFixedWidth(100)
        crf_box_layout.addWidget(crf_radio)
        crf_box_layout.addWidget(self.widgets.crf)
        crf_box_layout.addStretch()
        crf_box_layout.addWidget(QtWidgets.QLabel("Custom:"))
        crf_box_layout.addWidget(self.widgets.custom_crf)

        bitrate_group_box.setLayout(bitrate_box_layout)
        crf_group_box.setLayout(crf_box_layout)

        layout.addWidget(crf_group_box, 0, 0)
        layout.addWidget(bitrate_group_box, 1, 0)
        return layout
Ejemplo n.º 5
0
    def __init__(self, parent=None):
        super(About, self).__init__(parent)
        layout = QtWidgets.QGridLayout()

        self.setMinimumSize(400, 400)

        build_file = Path(base_path, 'build_version')

        label = QtWidgets.QLabel(f"<b>FastFlix</b> v{__version__}<br>"
                                 f"{f'Build: {build_file.read_text().strip()}<br>' if build_file.exists() else ''}"
                                 f"<br>Author: <a href='https://github.com/cdgriffith'>Chris Griffith</a>"
                                 f"<br>License: MIT")
        label.setFont(QtGui.QFont("Arial", 14))
        label.setAlignment(QtCore.Qt.AlignCenter)
        label.setOpenExternalLinks(True)
        label.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)

        supporting_libraries_label = QtWidgets.QLabel(
            "Supporting libraries<br>"
            f"<a href='https://www.python.org/'>Python</a> {reusables.version_string} (PSF LICENSE), "
            f"<a href='https://wiki.qt.io/Qt_for_Python'>PySide2</a> {pyside_version} (LGPLv3)<br>"
            f"<a href='https://github.com/cdgriffith/Box'>python-box</a> {box_version} (MIT), "
            f"<a href='https://github.com/cdgriffith/Reusables'>Reusables</a> {reusables.__version__} (MIT)<br>")
        supporting_libraries_label.setAlignment(QtCore.Qt.AlignCenter)
        supporting_libraries_label.setOpenExternalLinks(True)

        layout.addWidget(label)
        layout.addWidget(supporting_libraries_label)

        if Path(base_path, 'bundled').exists():
            bundle_label = QtWidgets.QLabel(
                "Bundled with: <a href='https://github.com/OpenVisualCloud/SVT-AV1'>SVT AV1</a> (Modified BSD) and "
                "<a href='https://www.ffmpeg.org/download.html'>ffmpeg</a> (LGPL)")
            bundle_label.setAlignment(QtCore.Qt.AlignCenter)
            bundle_label.setOpenExternalLinks(True)
            layout.addWidget(bundle_label)

        if pyinstaller:
            pyinstaller_label = QtWidgets.QLabel("Packaged with: <a href='https://www.pyinstaller.org/index.html'>"
                                                 "PyInstaller</a>")
            pyinstaller_label.setAlignment(QtCore.Qt.AlignCenter)
            pyinstaller_label.setOpenExternalLinks(True)
            layout.addWidget(pyinstaller_label)

        replacer = '\\'
        license_label = QtWidgets.QLabel(
            f"<a href='file:///{base_path.replace(replacer, '/')}/docs/build-licenses.txt' download>LICENSES</a>")
        license_label.setAlignment(QtCore.Qt.AlignCenter)
        license_label.setOpenExternalLinks(True)
        layout.addWidget(license_label)

        self.setLayout(layout)
        self.show()
Ejemplo n.º 6
0
    def __init__(self, parent, audio, number, enabled=True):
        super(Subtitle, self).__init__(parent)
        self.audio = audio
        self.widget = QtWidgets.QLineEdit()
        self.widget.setText(audio)
        self.widget.setDisabled(not enabled)
        self.setFixedHeight(60)

        grid = QtWidgets.QGridLayout()
        grid.addWidget(QtWidgets.QLabel(f"Track {number}"), 0, 0, 1, 2)
        grid.addWidget(self.widget, 1, 0, 1, 2)
        self.setLayout(grid)
Ejemplo n.º 7
0
    def __init__(self, parent):
        super(CommandList, self).__init__(parent)

        layout = QtWidgets.QGridLayout()
        layout.addWidget(QtWidgets.QLabel('Commands to execute'))

        self.inner_widget = QtWidgets.QWidget()

        self.scroll_area = QtWidgets.QScrollArea(self)
        self.scroll_area.setMinimumHeight(200)

        layout.addWidget(self.scroll_area)

        self.setLayout(layout)
Ejemplo n.º 8
0
    def __init__(self, parent):
        super(SubtitleList, self).__init__(parent)

        layout = QtWidgets.QGridLayout()
        layout.addWidget(QtWidgets.QLabel('Subtitle Tracks'))

        self.inner_widget = QtWidgets.QWidget()

        self.scroll_area = QtWidgets.QScrollArea(self)
        self.scroll_area.setMinimumHeight(200)

        layout.addWidget(self.scroll_area)

        self.setLayout(layout)
Ejemplo n.º 9
0
    def __init__(self, parent, command, number, name="", enabled=True):
        super(Command, self).__init__(parent)
        self.command = command
        self.widget = QtWidgets.QLineEdit()
        self.widget.setReadOnly(True)
        self.widget.setText(command)
        self.widget.setDisabled(not enabled)
        self.setFixedHeight(60)

        grid = QtWidgets.QGridLayout()
        grid.addWidget(
            QtWidgets.QLabel(f"Command {number}" if not name else name), 0, 0,
            1, 2)
        grid.addWidget(self.widget, 1, 0, 1, 2)
        self.setLayout(grid)
Ejemplo n.º 10
0
    def __init__(self, parent, main):
        super(GIF, self).__init__(parent)
        self.main = main

        grid = QtWidgets.QGridLayout()

        # grid.addWidget(QtWidgets.QLabel("GIF"), 0, 0)

        self.widgets = Box(fps=None, remove_hdr=None, dither=None)

        grid.addLayout(self.init_fps(), 1, 0)
        grid.addLayout(self.init_remove_hdr(), 2, 0)
        grid.addLayout(self.init_dither(), 0, 0)

        grid.addWidget(QtWidgets.QWidget(), 5, 0, 5, 2)
        self.setLayout(grid)
Ejemplo n.º 11
0
    def __init__(self, parent, available_audio_encoders):
        super(AudioList, self).__init__(parent)
        self.main = parent.main
        self.inner_layout = None
        self.available_audio_encoders = available_audio_encoders

        layout = QtWidgets.QGridLayout()
        layout.addWidget(QtWidgets.QLabel('Audio Tracks'))

        self.inner_widget = QtWidgets.QWidget()

        self.scroll_area = QtWidgets.QScrollArea(self)
        self.scroll_area.setMinimumHeight(200)

        layout.addWidget(self.scroll_area)

        self.tracks = []

        self.setLayout(layout)
Ejemplo n.º 12
0
    def __init__(self, parent, data_path, ffmpeg, ffprobe, svt_av1, **kwargs):
        super().__init__(parent)
        self.container = parent
        self.initialized = False
        self.loading_video = True
        self.scale_updating = False
        self.path = Box(
            data=
            data_path,  # Path(user_data_dir("FastFlix", appauthor=False, version=__version__, roaming=True))
        )

        self.plugins = load_plugins(Path(data_path, 'plugins'))

        self.ffmpeg = ffmpeg
        self.ffprobe = ffprobe
        self.svt_av1 = svt_av1

        self.input_defaults = Box(scale=None, crop=None)

        self.path.ffmpeg = Path(self.path.data, "ffmpeg")
        self.path.svt_av1 = Path(self.path.data, "svt_av1")

        for path in self.path.values():
            path.mkdir(parents=True, exist_ok=True)

        self.setAcceptDrops(True)

        self.input_video = None
        self.streams, self.format_info = None, None

        # self.x265 = X265(parent=self, source=source)
        # self.av1 = AV1(parent=self, source=source)
        # self.gif = GIF(parent=self, source=source)

        self.widgets = Box(input_file=None,
                           preview=None,
                           start_time=None,
                           duration=None,
                           video_track=None,
                           convert_to=None,
                           rotate=None,
                           convert_button=None,
                           v_flip=None,
                           h_flip=None,
                           crop=Box(top=None,
                                    bottom=None,
                                    left=None,
                                    right=None),
                           scale=Box(width=None,
                                     height=None,
                                     keep_aspect_ratio=None))

        self.thumb_file = Path(self.path.data, 'thumbnail_preview.png')
        self.flix = Flix(ffmpeg=self.ffmpeg,
                         ffprobe=self.ffprobe,
                         svt_av1=self.svt_av1)
        self.video_options = VideoOptions(
            self, available_audio_encoders=self.flix.get_audio_encoders())

        self.completed.connect(self.conversion_complete)
        self.cancelled.connect(self.conversion_cancelled)
        self.thumbnail_complete.connect(self.thumbnail_generated)
        self.encoding_worker = None
        self.command_runner = None
        self.converting = False

        self.video_width = 0
        self.video_height = 0

        self.default_options = Box()
        self.output_video = None

        self.grid = QtWidgets.QGridLayout()

        self.init_video_area()
        self.init_scale_and_crop()
        self.init_preview_image()

        self.grid.addWidget(self.video_options, 5, 0, 10, 15)
        self.grid.setSpacing(5)

        self.setLayout(self.grid)
        self.show()
        self.initialized = True
Ejemplo n.º 13
0
    def init_rotate(self):
        group_box = QtWidgets.QGroupBox()
        rotation_dir = Path(base_path, 'data', 'rotations')
        group_box.setStyleSheet(
            "QGroupBox{padding-top:15px; margin-top:-15px; padding-bottom:-5px}"
        )
        group = QtWidgets.QButtonGroup()

        v_size = QtCore.QSize(40, 60)
        h_size = QtCore.QSize(60, 40)

        rot_none = QtWidgets.QRadioButton("No Rotation")
        rot_none.setIcon(QtGui.QIcon(str(Path(rotation_dir, 'FastFlix.png'))))
        rot_none.setIconSize(h_size)
        rot_none.name = None

        rot_1 = QtWidgets.QRadioButton("90°")
        rot_1.setIcon(QtGui.QIcon(str(Path(rotation_dir, 'FastFlix C90.png'))))
        rot_1.setIconSize(v_size)
        rot_1.name = 1

        rot_2 = QtWidgets.QRadioButton("270°")
        rot_2.setIcon(QtGui.QIcon(str(Path(rotation_dir,
                                           'FastFlix CC90.png'))))
        rot_2.setIconSize(v_size)
        rot_2.name = 2

        rot_4 = QtWidgets.QRadioButton("180°")
        rot_4.setIcon(QtGui.QIcon(str(Path(rotation_dir, 'FastFlix 180.png'))))
        rot_4.setIconSize(h_size)
        rot_4.name = 4

        self.widgets.v_flip = QtWidgets.QCheckBox("Vertical Flip")
        self.widgets.v_flip.setIcon(
            QtGui.QIcon(str(Path(rotation_dir, 'FastFlix VF.png'))))
        self.widgets.v_flip.setIconSize(h_size)
        self.widgets.v_flip.toggled.connect(lambda: self.page_update())

        self.widgets.h_flip = QtWidgets.QCheckBox("Horizontal Flip")
        self.widgets.h_flip.setIcon(
            QtGui.QIcon(str(Path(rotation_dir, 'FastFlix HF.png'))))
        self.widgets.h_flip.setIconSize(h_size)
        self.widgets.h_flip.toggled.connect(lambda: self.page_update())

        group.addButton(rot_1)
        group.addButton(rot_2)
        group.addButton(rot_4)
        group.addButton(rot_none)
        layout = QtWidgets.QGridLayout()
        layout.addWidget(rot_none, 1, 0)
        layout.addWidget(rot_1, 0, 0)
        layout.addWidget(rot_2, 0, 2)
        layout.addWidget(rot_4, 0, 1)
        layout.addWidget(self.widgets.v_flip, 1, 2)
        layout.addWidget(self.widgets.h_flip, 1, 1)
        label = QtWidgets.QLabel("Rotation",
                                 alignment=(Qt.AlignBottom | Qt.AlignRight))
        label.setStyleSheet("QLabel{color:#777}")
        layout.addWidget(label, 1, 3)
        group_box.setLayout(layout)
        rot_none.setChecked(True)
        self.widgets.rotate = group
        self.widgets.rotate.buttonClicked.connect(lambda: self.page_update())
        return group_box
Ejemplo n.º 14
0
    def __init__(self,
                 parent,
                 audio,
                 index,
                 codec,
                 available_audio_encoders,
                 outdex=None,
                 enabled=True,
                 original=False,
                 first=False,
                 last=False,
                 codecs=(),
                 channels=2):
        super(Audio, self).__init__(parent)
        self.parent = parent
        self.audio = audio
        self.setFixedHeight(60)
        self.original = original
        self.outdex = index if self.original else outdex
        self.first = first
        self.last = last
        self.index = index
        self.codec = codec
        self.codecs = codecs
        self.channels = channels
        self.loading = True
        self.available_audio_encoders = available_audio_encoders

        self.widgets = Box(
            track_number=QtWidgets.QLabel(
                f'{index}:{self.outdex}' if enabled else '❌'),
            audio_info=QtWidgets.QLineEdit(audio),
            up_button=QtWidgets.QPushButton("^"),
            down_button=QtWidgets.QPushButton("v"),
            enable_check=QtWidgets.QCheckBox("Enabled"),
            dup_button=QtWidgets.QPushButton("➕"),
            delete_button=QtWidgets.QPushButton("⛔"),
            convert_to=None,
            convert_bitrate=None,
        )

        self.widgets.enable_check.setChecked(enabled)
        #self.widgets.enable_check.toggled.connect(lambda: self.parent.reorder())

        self.widgets.dup_button.clicked.connect(lambda: self.dup_me())
        self.widgets.dup_button.setFixedWidth(20)
        self.widgets.delete_button.clicked.connect(lambda: self.del_me())
        self.widgets.delete_button.setFixedWidth(20)

        self.widgets.track_number.setFixedWidth(20)

        grid = QtWidgets.QGridLayout()
        grid.addLayout(self.init_move_buttons(), 0, 0)
        grid.addWidget(self.widgets.track_number, 0, 1)
        grid.addWidget(self.widgets.audio_info, 0, 2)
        grid.addLayout(self.init_conversion(), 0, 3)

        if not original:
            grid.addWidget(self.widgets.delete_button, 0, 4)
        else:
            grid.addWidget(self.widgets.dup_button, 0, 5)
            grid.addWidget(self.widgets.enable_check, 0, 4)
        self.setLayout(grid)
        self.loading = False