From 1cd7f60d5d2b4ee3fb1904e7f5a097278b174a9d Mon Sep 17 00:00:00 2001 From: andreasGBL <29144928+andreasGBL@users.noreply.github.com> Date: Sat, 16 Jul 2022 17:56:26 +0200 Subject: [PATCH] Trim only feature, multiple improvements Added the trim only feature, Supports windows dpi scaling, only scales the video or changes the framerate when needed --- include/ffmpegwrapper.h | 8 +++---- include/structs.h | 16 ++++++++----- include/videolowwindow.h | 1 + src/ffmpegwrapper.cpp | 41 +++++++++++++++++-------------- src/filedropwidget.cpp | 52 +++++++++++++++++++++++++++++++++++----- src/main.cpp | 1 + src/videolowwindow.cpp | 33 +++++++++++++++++++++---- src/videolowwindow.ui | 21 ++++++++++++---- 8 files changed, 131 insertions(+), 42 deletions(-) diff --git a/include/ffmpegwrapper.h b/include/ffmpegwrapper.h index ab331cc..d7f270e 100644 --- a/include/ffmpegwrapper.h +++ b/include/ffmpegwrapper.h @@ -8,7 +8,7 @@ class FFMPEGWrapper { public: FFMPEGWrapper(); - bool exportFile(Video const & video, TrimSettings const & settings, double MBitRate, Resolution const & res, Codec const & codec, int HardwareAccelleration, int Framerate); + bool exportFile(Video const & video, TrimSettings const & settings, double MBitRate, Resolution const & res, Codec const & codec, int HardwareAccelleration, int Framerate, bool trimOnly); private: QString getFileName(QString const & filePath); QString getExportFileName(QString const & fileName); @@ -17,10 +17,10 @@ class FFMPEGWrapper QString getTrimString(QTime const & start, QTime const & end, Video const & video); QString getMBitRateString(double MBitRate); - QString getFramerateFilter(int Framerate); - QString getScaleFilterString(Resolution const & res, int HardwareAcceleration); + QString getFramerateFilter(double Framerate, double vidFramerate); + QString getScaleFilterString(Resolution const & res, Resolution const & vidRes, int HardwareAcceleration); - QString getVideoCodecString(Codec const & codec, int HardwareAcceleration); + QString getVideoCodecString(Codec const & codec, int HardwareAcceleration, bool trimOnly); QString getAudioCodecString(bool canCopy); QString getHardwareAccelerationString(int HardwareAcceleration, bool usesScaleFilter); QString getInputFileString(QString const & filePath); diff --git a/include/structs.h b/include/structs.h index 5a17bd2..c80a0aa 100644 --- a/include/structs.h +++ b/include/structs.h @@ -19,6 +19,8 @@ struct Codec { struct Video { QString filePath; QTime length; + Resolution resolution; + double framerate; }; struct TrimSettings { @@ -28,11 +30,13 @@ struct TrimSettings { }; enum RESOLUTION_IDX { - RESOLUTION_AS_INPUT = 0, - K4 = 1, - p1080 = 2, - p720 = 3, - p480 = 4 + RESOLUTION_AS_INPUT, + K4, + p1440, + p1080, + p720, + p480, + p240 }; enum HARDWARE_ACCELERATION { @@ -72,7 +76,7 @@ Resolution const RESOLUTIONS[7] = { } }; -int const FRAMERATES[5] = { +float const FRAMERATES[5] = { 0, 30, 60, diff --git a/include/videolowwindow.h b/include/videolowwindow.h index 441bb5b..3c82bc8 100644 --- a/include/videolowwindow.h +++ b/include/videolowwindow.h @@ -28,6 +28,7 @@ private slots: void quickHEVC_16(); void exportVideo(); void reviewVideo(); + void quickTrimOnly(); void gotCutInformation(QTime start, QTime end, bool cancelled); void startTimeEdited(); void endTimeEdited(); diff --git a/src/ffmpegwrapper.cpp b/src/ffmpegwrapper.cpp index 2a82bab..5ddf3e3 100644 --- a/src/ffmpegwrapper.cpp +++ b/src/ffmpegwrapper.cpp @@ -20,7 +20,7 @@ FFMPEGWrapper::FFMPEGWrapper() } } -bool FFMPEGWrapper::exportFile(const Video & video, const TrimSettings & settings, double MBitRate, const Resolution & res, const Codec & codec, int HardwareAccelleration, int Framerate) +bool FFMPEGWrapper::exportFile(const Video & video, const TrimSettings & settings, double MBitRate, const Resolution & res, const Codec & codec, int HardwareAccelleration, int Framerate, bool trimOnly) { const QString & filePath = video.filePath; QString expFilePath = getExportFilePath(filePath); @@ -33,12 +33,12 @@ bool FFMPEGWrapper::exportFile(const Video & video, const TrimSettings & setting //filters std::vector filters; - QString framerateFilter = getFramerateFilter(Framerate); - QString scaleFilter = getScaleFilterString(res, HardwareAccelleration); + QString framerateFilter = getFramerateFilter(Framerate, video.framerate); + QString scaleFilter = getScaleFilterString(res, video.resolution, HardwareAccelleration); //options part2 - QString audioCodec = getAudioCodecString(settings.start == QTime(0, 0) || !settings.trim); - QString videoCodec = getVideoCodecString(codec, HardwareAccelleration); + QString audioCodec = getAudioCodecString(settings.start == QTime(0, 0) || !settings.trim || trimOnly); + QString videoCodec = getVideoCodecString(codec, HardwareAccelleration, trimOnly); QString bitrate = getMBitRateString(MBitRate); QString outputFile = getOutputFileString(expFilePath); @@ -118,17 +118,17 @@ QString FFMPEGWrapper::getMBitRateString(double MBitRate) return "-b:v " + QString::number(MBitRate) + "M"; } -QString FFMPEGWrapper::getFramerateFilter(int Framerate) +QString FFMPEGWrapper::getFramerateFilter(double Framerate, double vidFramerate) { - if (Framerate <= 0) + if (Framerate <= 0. || Framerate == vidFramerate) return QString(""); else return QString("fps=fps=") + QString::number(Framerate); } -QString FFMPEGWrapper::getScaleFilterString(Resolution const & res, int HardwareAcceleration) +QString FFMPEGWrapper::getScaleFilterString(Resolution const & res, Resolution const& vidRes, int HardwareAcceleration) { - if (res.height <= 0 && res.width <= 0) { + if (res.height <= 0 && res.width <= 0 || (res.height == vidRes.height && res.width == vidRes.width)) { return QString(""); } QString resolutionString = QString::number(res.width) + ":" + QString::number(res.height); @@ -141,17 +141,22 @@ QString FFMPEGWrapper::getScaleFilterString(Resolution const & res, int Hardware } } -QString FFMPEGWrapper::getVideoCodecString(Codec const & codec, int HardwareAcceleration) +QString FFMPEGWrapper::getVideoCodecString(Codec const & codec, int HardwareAcceleration, bool trimOnly) { QString prefix = "-c:v "; - switch (HardwareAcceleration) - { - case(HARDWARE_ACCELERATION::NVIDIA): - return prefix + codec.NVIDIA.c_str(); - case(HARDWARE_ACCELERATION::AMD): - return prefix + codec.AMD.c_str(); - default: - return prefix + codec.defaultName.c_str(); + if (trimOnly) { + return prefix + "copy"; + } + else { + switch (HardwareAcceleration) + { + case(HARDWARE_ACCELERATION::NVIDIA): + return prefix + codec.NVIDIA.c_str(); + case(HARDWARE_ACCELERATION::AMD): + return prefix + codec.AMD.c_str(); + default: + return prefix + codec.defaultName.c_str(); + } } } diff --git a/src/filedropwidget.cpp b/src/filedropwidget.cpp index b9ff1ad..df0d146 100644 --- a/src/filedropwidget.cpp +++ b/src/filedropwidget.cpp @@ -72,9 +72,11 @@ void FileDropWidget::dropEvent(QDropEvent * event) std::string cmd = "ffprobe.exe \"" + path.toStdString() + "\" 2>&1"; //redirect stderr to stdout QString probe(""); int hours = 0, minutes = 0, seconds = 0, milliseconds = 0; + Resolution resolution = {0, 0}; + double framerate = 0; { { - FILE * f; + FILE* f; f = _popen(cmd.c_str(), "r"); char buff[128]; if (f) { @@ -83,7 +85,7 @@ void FileDropWidget::dropEvent(QDropEvent * event) } } } - // std::cout<<"Probe:"<(timesplit[2].toDouble()); milliseconds = static_cast((timesplit[2].toDouble() - static_cast(seconds)) * 100.0) * 10; } - } - QTime vidLength(hours, minutes, seconds, milliseconds); //TODO: do probing and thumbnail at 3 seconds in parallel (async) and redo thumbnail in rare case of a video that is shorter than 3 seconds + + QString pattern2("(\\d{1,3}.\\d{2}|\\d{1,3}) fps"); + regex = QRegularExpression(pattern2); + bool ok = true; + + match = regex.match(probe); + if (match.hasMatch()) { + QString res = match.captured(0); + QString splitter(" fps"); + QString fps = res.split(splitter)[0]; + double frate = fps.trimmed().toDouble(&ok); + if (ok) + framerate = frate; + std::cout << "fps: "< 3000 ? 3000 : msecsMid); //prefer a thumbnail at 3 seconds or at videoLength / 2, if video is shorter QString tempFolder("VideoLow.tmp"); @@ -108,7 +148,7 @@ void FileDropWidget::dropEvent(QDropEvent * event) QString thumbnail = QDir::tempPath()+QString("/"+tempFolder+"/thumb.jpg"); QString format("hh:mm:ss.zzz"); - cmd = "ffmpeg -y -i \"" + path.toStdString() + "\" -ss " + thumbnailTime.toString(format).toStdString() + " -vf \"scale=600:600:force_original_aspect_ratio=decrease\" -vframes 1 \"" + thumbnail.toStdString() + "\" 2>&1"; //redirect stderr to stdout + cmd = "ffmpeg -y -i \"" + path.toStdString() + "\" -ss " + thumbnailTime.toString(format).toStdString() + " -vf \"scale=1000:1000:force_original_aspect_ratio=decrease\" -vframes 1 \"" + thumbnail.toStdString() + "\" 2>&1"; //redirect stderr to stdout QString thumb; { FILE * f; @@ -124,7 +164,7 @@ void FileDropWidget::dropEvent(QDropEvent * event) QPixmap m(thumbnail); auto scaled = m.scaled(previewLabel->width(), previewLabel->height(), Qt::KeepAspectRatio); previewLabel->setPixmap(scaled); - Video vid = { path, vidLength}; + Video vid = { path, vidLength, resolution, framerate}; emit newVideoFileDropped(vid); hasDrop = true; } diff --git a/src/main.cpp b/src/main.cpp index 4d098e2..93480f4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ int main(int argc, char *argv[]) { + QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication a(argc, argv); VideoLowWindow w; w.show(); diff --git a/src/videolowwindow.cpp b/src/videolowwindow.cpp index e059e3f..d55e8b7 100644 --- a/src/videolowwindow.cpp +++ b/src/videolowwindow.cpp @@ -2,7 +2,6 @@ #include #include - #include "include/structs.h" #include @@ -13,7 +12,9 @@ VideoLowWindow::VideoLowWindow(QWidget * parent) , ffmpeg() , ui(new Ui::VideoLowWindow) { + ui->setupUi(this); + ui->centralwidget->resize(width() - 10, height() - 10); ui->HardwareAccelerationComboBox->setCurrentIndex(HARDWARE_ACCELERATION_DEFAULT); ui->HardwareAccelerationQuickComboBox->setCurrentIndex(HARDWARE_ACCELERATION_DEFAULT); ui->HardwareAccelerationComboBox->update(); @@ -36,6 +37,7 @@ VideoLowWindow::~VideoLowWindow() void VideoLowWindow::connectSlots() { + QObject::connect(ui->trimVideoButton, &QPushButton::clicked, this, &VideoLowWindow::quickTrimOnly); QObject::connect(ui->H264_2, &QPushButton::clicked, this, &VideoLowWindow::quickH264_2); QObject::connect(ui->H264_4, &QPushButton::clicked, this, &VideoLowWindow::quickH264_4); QObject::connect(ui->H264_8, &QPushButton::clicked, this, &VideoLowWindow::quickH264_8); @@ -66,7 +68,8 @@ void VideoLowWindow::quickH264(double MBitRate) RESOLUTIONS[RESOLUTION_IDX::RESOLUTION_AS_INPUT], CODECS[CODEC_IDX::H264], ui->HardwareAccelerationQuickComboBox->currentIndex(), - FRAMERATES[ui->FramerateQuickComboBox->currentIndex()] + FRAMERATES[ui->FramerateQuickComboBox->currentIndex()], + false ), ui->HardwareAccelerationQuickComboBox->currentIndex() != 0 ); @@ -83,7 +86,8 @@ void VideoLowWindow::quickHEVC(double MBitRate) RESOLUTIONS[RESOLUTION_IDX::RESOLUTION_AS_INPUT], CODECS[CODEC_IDX::HEVC], ui->HardwareAccelerationQuickComboBox->currentIndex(), - FRAMERATES[ui->FramerateQuickComboBox->currentIndex()] + FRAMERATES[ui->FramerateQuickComboBox->currentIndex()], + false ), ui->HardwareAccelerationQuickComboBox->currentIndex() != 0 ); @@ -168,7 +172,8 @@ void VideoLowWindow::exportVideo() RESOLUTIONS[ui->ResolutionComboBox->currentIndex()], CODECS[ui->CodecComboBox->currentIndex()], ui->HardwareAccelerationComboBox->currentIndex(), - FRAMERATES[ui->FramerateComboBox->currentIndex()] + FRAMERATES[ui->FramerateComboBox->currentIndex()], + false ), ui->HardwareAccelerationComboBox->currentIndex() != 0 ); @@ -183,6 +188,26 @@ void VideoLowWindow::reviewVideo() cutWindow->show(); } +void VideoLowWindow::quickTrimOnly() +{ + if (currentVideo) { + handleExportExitCode( + ffmpeg.exportFile( + *currentVideo, + getTrimSettings(), + ui->BitrateDoubleSpinBox->value(), + RESOLUTIONS[RESOLUTION_IDX::RESOLUTION_AS_INPUT], + CODECS[CODEC_IDX::H264], + ui->HardwareAccelerationQuickComboBox->currentIndex(), + FRAMERATES[0], + true + ), + ui->HardwareAccelerationQuickComboBox->currentIndex() != 0 + ); + + } +} + void VideoLowWindow::gotCutInformation(QTime start, QTime end, bool cancelled) { if (!cancelled) { diff --git a/src/videolowwindow.ui b/src/videolowwindow.ui index c72a30e..4008d31 100644 --- a/src/videolowwindow.ui +++ b/src/videolowwindow.ui @@ -6,8 +6,8 @@ 0 0 - 777 - 642 + 776 + 655 @@ -20,6 +20,12 @@ VideoLow + + + 0 + 0 + + @@ -505,6 +511,13 @@ + + + + Only Trim Video + + + @@ -731,8 +744,8 @@ 0 0 - 777 - 22 + 776 + 17