Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package clipgrab for openSUSE:Factory checked in at 2025-12-15 11:56:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/clipgrab (Old) and /work/SRC/openSUSE:Factory/.clipgrab.new.1939 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "clipgrab" Mon Dec 15 11:56:46 2025 rev:12 rq:1322658 version:3.9.14 Changes: -------- --- /work/SRC/openSUSE:Factory/clipgrab/clipgrab.changes 2024-02-12 18:55:20.297277065 +0100 +++ /work/SRC/openSUSE:Factory/.clipgrab.new.1939/clipgrab.changes 2025-12-15 12:03:23.339923392 +0100 @@ -1,0 +2,5 @@ +Fri Dec 12 16:13:23 UTC 2025 - Carsten Ziepke <[email protected]> + +- Update to version 3.9.14 (no changelog supplied) + +------------------------------------------------------------------- Old: ---- clipgrab-3.9.10.tar.gz New: ---- clipgrab-3.9.14.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ clipgrab.spec ++++++ --- /var/tmp/diff_new_pack.4TUd7J/_old 2025-12-15 12:03:24.163958095 +0100 +++ /var/tmp/diff_new_pack.4TUd7J/_new 2025-12-15 12:03:24.167958263 +0100 @@ -1,7 +1,7 @@ # # spec file for package clipgrab # -# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2025 SUSE LLC # Copyright (c) 2008-2013 [email protected] # # All modifications and additions to the file contributed by third parties @@ -18,7 +18,7 @@ Name: clipgrab -Version: 3.9.10 +Version: 3.9.14 Release: 0 Summary: Video downloader License: GPL-3.0-or-later ++++++ clipgrab-3.9.10.tar.gz -> clipgrab-3.9.14.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clipgrab-3.9.10/ClipGrab.plist new/clipgrab-3.9.14/ClipGrab.plist --- old/clipgrab-3.9.10/ClipGrab.plist 2024-01-28 20:06:32.000000000 +0100 +++ new/clipgrab-3.9.14/ClipGrab.plist 2025-11-11 13:22:37.000000000 +0100 @@ -17,11 +17,11 @@ <key>NSHighResolutionCapable</key> <string>True</string> <key>CFBundleVersion</key> - <string>3.9.10</string> + <string>3.9.14</string> <key>CFBundleShortVersionString</key> - <string>3.9.10</string> + <string>3.9.14</string> <key>CFBundleGetInfoString</key> - <string>3.9.10</string> + <string>3.9.14</string> <key>NSRequiresAquaSystemAppearance</key> <true /> </dict> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clipgrab-3.9.10/clipgrab.pro new/clipgrab-3.9.14/clipgrab.pro --- old/clipgrab-3.9.10/clipgrab.pro 2024-01-28 20:06:32.000000000 +0100 +++ new/clipgrab-3.9.14/clipgrab.pro 2025-11-11 13:22:37.000000000 +0100 @@ -88,5 +88,5 @@ QMAKE_INFO_PLIST = ClipGrab.plist LIBS += -framework AppKit -framework Foundation } -VERSION = 3.9.10 +VERSION = 3.9.14 DEFINES += CLIPGRAB_VERSION=$$VERSION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clipgrab-3.9.10/video.cpp new/clipgrab-3.9.14/video.cpp --- old/clipgrab-3.9.10/video.cpp 2024-01-28 20:06:32.000000000 +0100 +++ new/clipgrab-3.9.14/video.cpp 2025-11-11 13:22:37.000000000 +0100 @@ -148,7 +148,17 @@ } void video::handleInfoJson(QByteArray data) { - QJsonObject json = QJsonDocument::fromJson(data).object(); + QJsonDocument document = QJsonDocument::fromJson(data); + if (document.isNull()) { + state = state::error; + return; + } + + QJsonObject json = document.object(); + if (json.empty()) { + state = state::error; + return; + } title = json.value("title").toString(); id = json.value("id").toString(); @@ -214,16 +224,56 @@ } } - // Sort audio formats by bitrate - std::sort(audioFormats.begin(), audioFormats.end(), [](QJsonObject a, QJsonObject b) { + // This tries to remove YouTube AI translations + QStringList languagePreferences = {}; + if (portal == "youtube") { + for(int i = 0; i < audioFormats.length(); i++) { + QString formatNote = audioFormats.at(i).value("format_note").toString(); + if (formatNote.toLower().contains("original")) { + QString language = audioFormats.at(i).value("language").toString(); + if (!languagePreferences.contains(language)) { + languagePreferences << language; + qDebug() << "Adding preferred language" << language << "from" << formatNote; + } + + } + } + + if (!languagePreferences.empty()) { + audioFormats.erase( + std::remove_if(audioFormats.begin(), audioFormats.end(), [languagePreferences](QJsonObject format) { + QString language = format.value("language").toString(); + return !languagePreferences.contains(language); + }), + audioFormats.end() + ); + + videoFormats.erase( + std::remove_if(videoFormats.begin(), videoFormats.end(), [languagePreferences](QJsonObject format) { + QString language = format.value("language").toString(); + return !language.isEmpty() && !languagePreferences.contains(language); + }), + videoFormats.end() + ); + } + } + + // Sort audio formats by bitrate and whether they're labelled as "original" + std::sort(audioFormats.begin(), audioFormats.end(), [languagePreferences](QJsonObject a, QJsonObject b) { double tbrA = a.value("tbr").toDouble(); double tbrB = b.value("tbr").toDouble(); + if (tbrA != tbrB) return tbrA > tbrB; - return tbrA > tbrB; + // Finally use alphabetic ordering of the format string. + QString formatA = a.value("format").toString(); + QString formatB = b.value("format").toString(); + if (formatA != formatB) return formatA < formatB; + + return false; }); - // Sort video formats by format and resolution - std::sort(videoFormats.begin(), videoFormats.end(), [vcodecPreferences](QJsonObject a, QJsonObject b) { + // Sort audio formats by bitrate and whether they're labelled as "original" + std::sort(videoFormats.begin(), videoFormats.end(), [vcodecPreferences, languagePreferences](QJsonObject a, QJsonObject b) { int heightA = a.value("height").toInt(); int heightB = b.value("height").toInt(); if (heightA != heightB) return heightA > heightB; @@ -259,6 +309,12 @@ if (acodecA == "none") return true; if (acodecB == "none") return false; } + + // Finally use alphabetic ordering of the format string. + QString formatA = a.value("format").toString(); + QString formatB = b.value("format").toString(); + if (formatA != formatB) return formatA < formatB; + return false; }); @@ -307,7 +363,7 @@ quality.containerName = videoFormat.value("ext").toString(); QList<QJsonObject> compatibleAudioFormats(audioFormats); - QStringList compatibleAudioExts = {"aac", "m4a"}; + QStringList compatibleAudioExts = {"aac", "m4a", "mp4"}; if (videoFormat.value("ext") == "webm") { compatibleAudioExts.clear(); compatibleAudioExts << "webm" << "ogg" << "opus"; @@ -318,7 +374,7 @@ return !compatibleAudioExts.contains(ext); }), compatibleAudioFormats.end()); - if (videoFormat.value("acodec") == "none" && audioFormats.size() > 0) { + if (videoFormat.value("acodec") == "none" && compatibleAudioFormats.size() > 0) { int audioIndex = (compatibleAudioFormats.size() -1) * i / videoFormats.size(); quality.audioFormat = compatibleAudioFormats.at(audioIndex).value("format_id").toString(); quality.audioFileSize = compatibleAudioFormats.at(audioIndex).value("filesize").toInt();
