Heute habe ich eine Version von RaidenVideoRipper für Apple-Geräte mit macOS und M1/M2/M3/M4-Prozessoren (Apple Silicon) veröffentlicht. RaidenVideoRipper ist eine schnelle Videobearbeitungsanwendung, mit der Sie einen Teil einer Videodatei in eine neue Datei schneiden können. Sie können auch GIFs erstellen und die Audiospur als MP3 exportieren.
Als nächstes werde ich kurz beschreiben, welche Befehle ich verwendet habe, um dies zu erreichen. Die Theorie, was hier passiert, die Dokumentation der Versorgungsunternehmen, kann unter den folgenden Links nachgelesen werden:
https://www.unix.com/man-page/osx/1/otool/
https://www.unix.com/man-page/osx/1/install_name_tool/
https://llvm.org/docs/CommandGuide/llvm-nm.html
https://linux.die.net/man/1/file
https://www.unix.com/man-page/osx/8/SPCTL/
https://linux.die.net/man/1/chmod
https://linux.die.net/man/1/ls
https://man7.org/linux/man-pages/man7/xattr.7.html
https://doc.qt.io/qt-6/macos-deployment.html
Installieren Sie zunächst Qt auf Ihrem macOS und installieren Sie auch die Umgebung für Qt Desktop Development. Anschließend stellen Sie Ihr Projekt beispielsweise in Qt Creator zusammen. Anschließend beschreibe ich, was erforderlich ist, um sicherzustellen, dass Abhängigkeiten mit externen dynamischen Bibliotheken bei der Verteilung der Anwendung an Endbenutzer korrekt verarbeitet werden.
Erstellen Sie ein Frameworks-Verzeichnis im Ordner YOUR_APP.app/Contents Ihrer Anwendung und platzieren Sie darin externe Abhängigkeiten. So sehen beispielsweise die Frameworks für die RaidenVideoRipper-Anwendung aus:
Frameworks
├── DullahanFFmpeg.framework
│ ├── dullahan_ffmpeg.a
│ ├── libavcodec.60.dylib
│ ├── libavdevice.60.dylib
│ ├── libavfilter.9.dylib
│ ├── libavformat.60.dylib
│ ├── libavutil.58.dylib
│ ├── libpostproc.57.dylib
│ ├── libswresample.4.dylib
│ └── libswscale.7.dylib
├── QtCore.framework
│ ├── Headers -> Versions/Current/Headers
│ ├── QtCore -> Versions/Current/QtCore
│ ├── Resources -> Versions/Current/Resources
│ └── Versions
├── QtGui.framework
│ ├── Headers -> Versions/Current/Headers
│ ├── QtGui -> Versions/Current/QtGui
│ ├── Resources -> Versions/Current/Resources
│ └── Versions
├── QtMultimedia.framework
│ ├── Headers -> Versions/Current/Headers
│ ├── QtMultimedia -> Versions/Current/QtMultimedia
│ ├── Resources -> Versions/Current/Resources
│ └── Versions
├── QtMultimediaWidgets.framework
│ ├── Headers -> Versions/Current/Headers
│ ├── QtMultimediaWidgets -> Versions/Current/QtMultimediaWidgets
│ ├── Resources -> Versions/Current/Resources
│ └── Versions
├── QtNetwork.framework
│ ├── Headers -> Versions/Current/Headers
│ ├── QtNetwork -> Versions/Current/QtNetwork
│ ├── Resources -> Versions/Current/Resources
│ └── Versions
└── QtWidgets.framework
├── Headers -> Versions/Current/Headers
├── QtWidgets -> Versions/Current/QtWidgets
├── Resources -> Versions/Current/Resources
└── Versions
Der Einfachheit halber habe ich nur die zweite Verschachtelungsebene gedruckt.
Als nächstes drucken wir die aktuellen dynamischen Abhängigkeiten Ihrer Anwendung aus:
otool -L RaidenVideoRipper
Ausgabe für die RaidenVideoRipper-Binärdatei, die sich in RaidenVideoRipper.app/Contents/MacOS befindet:
RaidenVideoRipper:
@rpath/DullahanFFmpeg.framework/dullahan_ffmpeg.a (compatibility version 0.0.0, current version 0.0.0)
@rpath/QtMultimediaWidgets.framework/Versions/A/QtMultimediaWidgets (compatibility version 6.0.0, current version 6.8.1)
@rpath/QtWidgets.framework/Versions/A/QtWidgets (compatibility version 6.0.0, current version 6.8.1)
@rpath/QtMultimedia.framework/Versions/A/QtMultimedia (compatibility version 6.0.0, current version 6.8.1)
@rpath/QtGui.framework/Versions/A/QtGui (compatibility version 6.0.0, current version 6.8.1)
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (compatibility version 45.0.0, current version 2575.20.19)
/System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Metal.framework/Versions/A/Metal (compatibility version 1.0.0, current version 367.4.0)
@rpath/QtNetwork.framework/Versions/A/QtNetwork (compatibility version 6.0.0, current version 6.8.1)
@rpath/QtCore.framework/Versions/A/QtCore (compatibility version 6.0.0, current version 6.8.1)
/System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (compatibility version 1.0.0, current version 275.0.0)
/System/Library/Frameworks/DiskArbitration.framework/Versions/A/DiskArbitration (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/UniformTypeIdentifiers.framework/Versions/A/UniformTypeIdentifiers (compatibility version 1.0.0, current version 709.0.0)
/System/Library/Frameworks/AGL.framework/Versions/A/AGL (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1800.101.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1351.0.0)
Wie im RaidenVideoRipper in den Qt- und dullahan_ffmpeg-Abhängigkeiten zu sehen ist. Dullahan FFmpeg ist ein Zweig von FFmpeg, der seine Funktionalität in einer dynamischen Bibliothek kapselt und die Möglichkeit bietet, den aktuellen Ausführungsfortschritt und den Abbruch mithilfe von C-Routinen abzurufen.
Ersetzen Sie als Nächstes die Pfade der Anwendung und aller erforderlichen Bibliotheken durch install_name_tool.
Der Befehl hierfür lautet:
install_name_tool -change old_path new_path target
Anwendungsbeispiel:
install_name_tool -change /usr/local/lib/libavfilter.9.dylib @rpath/DullahanFFmpeg.framework/libavfilter.9.dylib dullahan_ffmpeg.a
Nachdem Sie alle Pfade korrekt eingegeben haben, sollte die Anwendung korrekt starten. Überprüfen Sie, ob alle Pfade zu Bibliotheken relativ sind, übertragen Sie die Binärdatei und öffnen Sie sie erneut.
Wenn Sie einen Fehler sehen, überprüfen Sie die Pfade über otool und ändern Sie sie erneut über install_name_tool.
Es gibt auch einen Fehler bei der Verwechslung von Abhängigkeiten. Wenn die von Ihnen ersetzte Bibliothek kein Symbol in der Tabelle hat, können Sie das Vorhandensein oder Fehlen eines Symbols wie folgt überprüfen:
nm -gU path
Nach der Ausführung sehen Sie die gesamte Symboltabelle der Bibliothek oder Anwendung.
Es ist auch möglich, dass Sie die Abhängigkeiten der falschen Architektur kopiert haben. Sie können dies mit der Datei überprüfen:
file path
Das Dateidienstprogramm zeigt Ihnen, zu welcher Architektur die Bibliothek oder Anwendung gehört.
Qt benötigt außerdem einen Plugins-Ordner im Contents-Ordner Ihres YOUR_APP.app-Verzeichnisses. Kopieren Sie die Plugins von Qt nach Contents. Überprüfen Sie als Nächstes die Funktionalität der Anwendung. Anschließend können Sie mit der Optimierung des Plugins-Ordners beginnen, Elemente aus diesem Ordner löschen und die Anwendung testen.
macOS-Sicherheit
Nachdem Sie alle Abhängigkeiten kopiert und die Pfade für die dynamische Verknüpfung korrigiert haben, müssen Sie die Anwendung mit der Signatur des Entwicklers signieren und zusätzlich die Anwendungsversion zur Beglaubigung an Apple senden.
Wenn Sie keine 100 US-Dollar für eine Entwicklerlizenz haben oder nichts unterschreiben möchten, schreiben Sie Ihren Benutzern Anweisungen zum Starten der Anwendung.
Diese Anleitung funktioniert auch für RaidenVideoRipper:
- Gatekeeper deaktivieren: spctl –master-disable
- Start von beliebigen Quellen in „Datenschutz und Sicherheit“ zulassen: Wechseln von Anwendungen zu „Überall“ zulassen
- Entfernen Sie die Quarantäne-Flagge nach dem Herunterladen aus einer ZIP- oder DMG-Anwendung: xattr -d com.apple.quarantine app.dmg
- Überprüfen Sie, ob das Quarantäne-Flag (com.apple.quarantine) fehlt: ls -l@ app.dmg
- Fügen Sie bei Bedarf eine Bestätigung zum Starten der Anwendung in Datenschutz und Sicherheit hinzu
Ein Fehler mit der Quarantäne-Flagge wird normalerweise dadurch reproduziert, dass auf dem Bildschirm des Benutzers die Fehlermeldung „Anwendung ist beschädigt“ erscheint. In diesem Fall müssen Sie das Quarantäne-Flag aus den Metadaten entfernen.
Link zum Erstellen von RaidenVideoRipper für Apple Silicon:
https://github.com/demensdeum/RaidenVideoRipper/releases/download/1.0.1.0/RaidenVideoRipper-1.0.1.0.dmg