diff -Nru clipgrab-3.9.7/ClipGrab.plist clipgrab-3.9.10/ClipGrab.plist --- clipgrab-3.9.7/ClipGrab.plist 2021-10-08 13:58:07.000000000 +0000 +++ clipgrab-3.9.10/ClipGrab.plist 2024-01-28 19:06:32.000000000 +0000 @@ -17,11 +17,11 @@ NSHighResolutionCapable True CFBundleVersion - 3.9.7 + 3.9.10 CFBundleShortVersionString - 3.9.7 + 3.9.10 CFBundleGetInfoString - 3.9.7 + 3.9.10 NSRequiresAquaSystemAppearance diff -Nru clipgrab-3.9.7/clipgrab.pro clipgrab-3.9.10/clipgrab.pro --- clipgrab-3.9.7/clipgrab.pro 2021-10-08 13:58:07.000000000 +0000 +++ clipgrab-3.9.10/clipgrab.pro 2024-01-28 19:06:32.000000000 +0000 @@ -88,5 +88,5 @@ QMAKE_INFO_PLIST = ClipGrab.plist LIBS += -framework AppKit -framework Foundation } -VERSION = 3.9.7 +VERSION = 3.9.10 DEFINES += CLIPGRAB_VERSION=$$VERSION diff -Nru clipgrab-3.9.7/debian/changelog clipgrab-3.9.10/debian/changelog --- clipgrab-3.9.7/debian/changelog 2023-08-31 19:15:37.000000000 +0000 +++ clipgrab-3.9.10/debian/changelog 2024-03-08 20:20:33.000000000 +0000 @@ -1,3 +1,9 @@ +clipgrab (3.9.10-1~ppa~mantic) mantic; urgency=medium + + * New upstream release. + + -- tomx3 Fri, 8 Mar 2024 21:20:42 +0100 + clipgrab (3.9.7-1~ppa~mantic) mantic; urgency=medium * Initial release. diff -Nru clipgrab-3.9.7/video.cpp clipgrab-3.9.10/video.cpp --- clipgrab-3.9.7/video.cpp 2021-10-08 13:58:07.000000000 +0000 +++ clipgrab-3.9.10/video.cpp 2024-01-28 19:06:32.000000000 +0000 @@ -33,6 +33,7 @@ cachedDownloadSize = 0; cachedDownloadProgress = 0; audioOnly = false; + duration = 0; } void video::startYoutubeDl(QStringList arguments) { @@ -171,6 +172,8 @@ url = "https://www.youtube.com/watch?v=" + url; } + duration = json.value("duration").toInt(0); + state = state::unfetched; return; } @@ -195,8 +198,10 @@ QList videoFormats; QList audioFormats; QStringList acceptedExts = {"mp4", "m4a"}; + QStringList vcodecPreferences = {"avc1", "av01"}; if (QSettings().value("UseWebM", false).toBool()) { acceptedExts << "webm" << "opus"; + vcodecPreferences.empty(); } for (int i = 0; i < formats.size(); i++) { QJsonObject format = formats.at(i).toObject(); @@ -218,7 +223,7 @@ }); // Sort video formats by format and resolution - std::sort(videoFormats.begin(), videoFormats.end(), [](QJsonObject a, QJsonObject b) { + std::sort(videoFormats.begin(), videoFormats.end(), [vcodecPreferences](QJsonObject a, QJsonObject b) { int heightA = a.value("height").toInt(); int heightB = b.value("height").toInt(); if (heightA != heightB) return heightA > heightB; @@ -231,10 +236,22 @@ QString extB = b.value("ext").toString(); if (extA != extB) return extA > extB; - // This makes sure AVC1 comes before AV01 and AV01 is removed as a duplicate QString vcodecA = a.value("vcodec").toString(); QString vcodecB = b.value("vcodec").toString(); - if (vcodecA != vcodecB) return vcodecA > vcodecB; + + bool vcodecAPreferencePos = vcodecPreferences.length(); + bool vcodecBPreferencePos = vcodecPreferences.length(); + + for (int i = 0; i < vcodecPreferences.length(); i++) { + if (vcodecA.startsWith(vcodecPreferences.at(i))) vcodecAPreferencePos = i; + if (vcodecB.startsWith(vcodecPreferences.at(i))) vcodecBPreferencePos = i; + } + + // If there is a preferred codec, put it first + if (vcodecAPreferencePos != vcodecBPreferencePos) return vcodecAPreferencePos < vcodecBPreferencePos; + + // Else use alphabetic ordering + if (vcodecA != vcodecB) return vcodecA < vcodecB; QString acodecA = a.value("acodec").toString(); QString acodecB = b.value("acodec").toString(); @@ -293,7 +310,7 @@ QStringList compatibleAudioExts = {"aac", "m4a"}; if (videoFormat.value("ext") == "webm") { compatibleAudioExts.clear(); - compatibleAudioExts << "webm" << "ogg"; + compatibleAudioExts << "webm" << "ogg" << "opus"; } compatibleAudioFormats.erase(std::remove_if(compatibleAudioFormats.begin(), compatibleAudioFormats.end(), [videoFormat, compatibleAudioExts](QJsonObject audioFormat) { QString ext = audioFormat.value("ext").toString(); @@ -342,7 +359,7 @@ return; } - re.setPattern("^\\[download\\]\\s+(\\d+\\.\\d)%\\s+of\\s+~?(\\d+\\.\\d+)(T|G|M|K)iB"); + re.setPattern("^\\[download\\]\\s+(\\d+\\.\\d)%\\s+of\\s+~?\\s*(\\d+\\.\\d+)(T|G|M|K)iB"); match = re.match(line); if (match.hasMatch() && !downloadFilenames.isEmpty()) { qint64 downloadProgress = 0; @@ -351,13 +368,16 @@ downloadProgress += QFileInfo(downloadFilenames.at(i) + ".part").size(); } - if (downloadSize > 0 && downloadProgress > 0) { - cachedDownloadSize = downloadSize; + QStringList prefixes {"K", "M", "G", "T"}; + qint64 downloadSizeEstimate = match.captured(2).toFloat() * pow(1024, 1 + prefixes.indexOf(match.captured(3))); + + qint64 previousDownloadSizeEstimate = downloadSizeEstimates.last(); + bool downloadSizeChangedSignificantly = downloadSize == 0 || (downloadSizeEstimate > previousDownloadSizeEstimate * 1.1) || (previousDownloadSizeEstimate < downloadSize * 0.9); + + if (downloadProgress > 0 && !downloadSizeChangedSignificantly) { cachedDownloadProgress = downloadProgress; - emit downloadProgressChanged(downloadSize, downloadProgress); + emit downloadProgressChanged(cachedDownloadSize, downloadProgress); } else if (downloadProgress > 0) { - QStringList prefixes {"K", "M", "G", "T"}; - qint64 downloadSizeEstimate = match.captured(2).toFloat() * pow(1024, 1 + prefixes.indexOf(match.captured(3))); downloadSizeEstimates.replace(downloadSizeEstimates.size() - 1, downloadSizeEstimate); qint64 totalDownloadSizeEstimate = 0; @@ -473,6 +493,7 @@ } void video::handleProcessFinished(int /*exitCode*/, QProcess::ExitStatus exitStatus) { + qDebug() << youtubeDl->readAllStandardError(); switch (state) { case state::fetching: if (exitStatus == QProcess::ExitStatus::NormalExit) { diff -Nru clipgrab-3.9.7/video.h clipgrab-3.9.10/video.h --- clipgrab-3.9.7/video.h 2021-10-08 13:58:07.000000000 +0000 +++ clipgrab-3.9.10/video.h 2024-01-28 19:06:32.000000000 +0000 @@ -109,7 +109,7 @@ QString artist; QString metaTitle; QString metaArtist; - int duration; + qint64 duration; int selectedQuality; QList qualities; diff -Nru clipgrab-3.9.7/youtube_dl.cpp clipgrab-3.9.10/youtube_dl.cpp --- clipgrab-3.9.7/youtube_dl.cpp 2021-10-08 13:58:07.000000000 +0000 +++ clipgrab-3.9.10/youtube_dl.cpp 2024-01-28 19:06:32.000000000 +0000 @@ -6,6 +6,7 @@ } QString YoutubeDl::path = QString(); +QString YoutubeDl::pythonCaFile = QString(); QString YoutubeDl::find(bool force) { if (!force && !path.isEmpty()) return path; @@ -46,15 +47,43 @@ QString execPath = QCoreApplication::applicationDirPath(); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - env.insert("PATH", execPath + ":" + env.value("PATH")); - process->setEnvironment(env.toStringList()); #if defined Q_OS_WIN + env.insert("PATH", QDir::toNativeSeparators(execPath) + ";" + env.value("PATH")); process->setProgram(execPath + "/python/python.exe"); + #elif defined Q_OS_MAC + QDir pythonDir(execPath + "/../Frameworks/Python.framework/Versions/Current/bin"); + QString pythonPath = pythonDir.canonicalPath() + "/python3"; + if (QFile::exists(pythonPath)) { + if (pythonCaFile.isEmpty()) { + QProcess* caFileProcess = new QProcess(); + caFileProcess->setProgram(pythonPath); + caFileProcess->setProcessEnvironment(env); + caFileProcess->setArguments(QStringList() << "-m" << "pip._vendor.certifi"); + caFileProcess->start(); + caFileProcess->waitForFinished(10000); + pythonCaFile = caFileProcess->readLine().trimmed(); + QString error = caFileProcess->readAllStandardError(); + if (!error.isEmpty()) { + qDebug() << "Error finding Python certificates" << error; + } + qDebug() << "Using SSL_CERT_FILE" << pythonCaFile; + } + } else { + pythonPath = QStandardPaths::findExecutable("python3"); + } + + if (!pythonCaFile.isEmpty()) { + env.insert("SSL_CERT_FILE", pythonCaFile); + } + + env.insert("PATH", execPath + ":" + env.value("PATH")); + process->setProgram(pythonPath); #else + env.insert("PATH", execPath + ":" + env.value("PATH")); process->setProgram(QStandardPaths::findExecutable("python3")); #endif - + QSettings settings; QStringList proxyArguments; if (settings.value("UseProxy", false).toBool()) { @@ -82,6 +111,9 @@ } process->setArguments(QStringList() << path << arguments << proxyArguments << networkArguments); + process->setWorkingDirectory(QDir::tempPath()); + process->setProcessEnvironment(env); + return process; } diff -Nru clipgrab-3.9.7/youtube_dl.h clipgrab-3.9.10/youtube_dl.h --- clipgrab-3.9.7/youtube_dl.h 2021-10-08 13:58:07.000000000 +0000 +++ clipgrab-3.9.10/youtube_dl.h 2024-01-28 19:06:32.000000000 +0000 @@ -17,6 +17,7 @@ static QString findPython(); static QString path; + static QString pythonCaFile; }; #endif // YOUTUBEDL_H