media-kit-macos-codesign-crash

Par divinevideo · divine-mobile

Corriger le crash au lancement d'une app Flutter macOS dû à un échec de chargement de la bibliothèque media_kit. À utiliser quand : (1) L'app macOS compile avec succès mais crashe immédiatement au lancement, (2) Le log de crash indique "Library not loaded: @rpath/Ass.framework" ou un framework media_kit similaire, (3) L'erreur indique "code signature not valid for use in process: Trying to load an unsigned library", (4) Le problème apparaît après flutter clean ou un clone fresh, (5) Un script de codesign existe dans le Podfile mais les frameworks restent non signés après le build — vérifier l'ORDRE des phases de build. Corrige les frameworks natifs media_kit non signés (Ass.framework, Avcodec.framework, etc.) en ajoutant une signature post-build ET en garantissant un ordre correct des phases de build.

npx skills add https://github.com/divinevideo/divine-mobile --skill media-kit-macos-codesign-crash

Kit Média macOS Correctif du Crash de Codesign

Problème

Les applications Flutter macOS utilisant media_kit (bibliothèque de lecteur vidéo) plantent immédiatement au lancement après une génération complète. L'app se génère avec succès mais échoue au démarrage en raison de frameworks natifs non signés.

Contexte / Conditions de déclenchement

  • Application Flutter macOS utilisant le package media_kit ou media_kit_video
  • L'app se génère sans erreurs : « Built build/macos/Build/Products/Debug/divine.app »
  • L'app plante immédiatement au lancement sans interface visible
  • Le rapport de crash ou la console affiche :
    Library not loaded: @rpath/Ass.framework/Versions/A/Ass
    Reason: code signature in '...' not valid for use in process: Trying to load an unsigned library
  • Se produit souvent après flutter clean, pod deintegrate + pod install, ou après un clone git frais
  • CRITIQUE : Peut aussi se produire quand le script de codesign existe MAIS s'exécute dans le mauvais ordre

Cause racine : Ordre des phases de compilation

La cause la plus courante (surtout après pod deintegrate + pod install) est que les phases de compilation Xcode se retrouvent dans le mauvais ordre :

MAUVAIS ordre (codesign s'exécute avant que les frameworks soient copiés) :

1. [CP] Check Pods Manifest.lock
2. Sources
3. Frameworks
4. Resources
5. Bundle Framework
6. ShellScript (Flutter assemble)
7. Codesign media_kit frameworks    ← NE SIGNE RIEN (frameworks pas encore embarqués)
8. [CP] Embed Pods Frameworks       ← copie les frameworks dans le bundle de l'app

BON ordre (embarquer d'abord, puis codesigner) :

1. [CP] Check Pods Manifest.lock
2. Sources
3. Frameworks
4. Resources
5. Bundle Framework
6. ShellScript (Flutter assemble)
7. [CP] Embed Pods Frameworks       ← copie les frameworks dans le bundle de l'app
8. Codesign media_kit frameworks    ← signe les frameworks embarqués
9. FlutterFire upload symbols        ← (si applicable, devrait être en dernier)

Solution

Étape 1 : Ajouter la phase de codesign via Podfile (si manquante)

Ajoutez ce bloc dans la section post_install do |installer| :

post_install do |installer|
  # Add script phase to codesign media_kit frameworks (fixes unsigned library crash)
  installer.pods_project.targets.each do |target|
    if target.name == 'media_kit_libs_macos_video'
      target.build_configurations.each do |config|
        config.build_settings['CODE_SIGN_IDENTITY'] = '-'
      end
    end
  end

  # Also add codesigning to the main project's frameworks
  main_project = installer.aggregate_targets.first.user_project
  main_project.targets.each do |target|
    if target.name == 'Runner'
      # Check if script phase already exists
      phase_name = 'Codesign media_kit frameworks'
      existing_phase = target.shell_script_build_phases.find { |p| p.name == phase_name }

      unless existing_phase
        phase = target.new_shell_script_build_phase(phase_name)
        phase.shell_script = <<-SCRIPT
# Codesign media_kit frameworks with ad-hoc signature
for framework in "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Frameworks"/*.framework; do
  if [ -d "$framework" ]; then
    codesign --force --deep --sign - "$framework" 2>/dev/null || true
  fi
done
        SCRIPT
        phase.shell_path = '/bin/bash'
      end
    end
  end
  main_project.save

  # ... rest of your existing post_install code ...

Étape 2 : Vérifier l'ordre des phases de compilation (CRITIQUE)

Le Podfile ajoute la phase de codesign mais ne peut pas garantir l'ordre. Après pod install, vérifiez macos/Runner.xcodeproj/project.pbxproj pour le tableau buildPhases de la cible Runner.

Recherchez le bloc buildPhases dans la section de la cible native Runner. Assurez-vous de cet ordre :

[CP] Embed Pods Frameworks          ← DOIT être AVANT codesign
Codesign media_kit frameworks       ← DOIT être APRÈS embed
FlutterFire: upload symbols         ← DEVRAIT être en dernier (si présent)

Si l'ordre est mauvais, inversez les lignes du tableau buildPhases. Exemple de correction :

 buildPhases = (
     ...
     3399D490228B24CF009A79C7 /* ShellScript */,
-    9AD7FD721DF2C6A84F6A1FC3 /* Codesign media_kit frameworks */,
-    51BD49356784271F7E3B2B6C /* [CP] Embed Pods Frameworks */,
-    BBC532B406767D40236ED3DB /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
+    51BD49356784271F7E3B2B6C /* [CP] Embed Pods Frameworks */,
+    9AD7FD721DF2C6A84F6A1FC3 /* Codesign media_kit frameworks */,
+    BBC532B406767D40236ED3DB /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
 );

Étape 3 : Regénérer

flutter clean
flutter pub get
cd macos && pod install && cd ..
flutter run -d macos

Correctif rapide d'urgence (Codesign manuel)

Si vous avez besoin que l'app fonctionne MAINTENANT avant de corriger les phases de compilation :

for fw in build/macos/Build/Products/Debug/<app>.app/Contents/Frameworks/*.framework; do
  codesign --force --deep --sign - "$fw"
done
codesign --force --deep --sign - "build/macos/Build/Products/Debug/<app>.app"
open "build/macos/Build/Products/Debug/<app>.app"

Vérification

  1. La sortie de compilation devrait afficher : « warning: Run script build phase 'Codesign media_kit frameworks' will be run during every build »
  2. L'app devrait se lancer sans plantage
  3. Vérifiez que les frameworks sont signés : codesign -v build/macos/.../app.app/Contents/Frameworks/Ass.framework

Diagnostic des problèmes d'ordre des phases de compilation

Si le script de codesign existe mais les frameworks sont toujours non signés, vérifiez l'ordre :

# Check which frameworks are unsigned in the built app
for fw in build/macos/Build/Products/Debug/<app>.app/Contents/Frameworks/*.framework; do
  result=$(codesign -v "$fw" 2>&1)
  if echo "$result" | grep -q "not signed"; then
    echo "UNSIGNED: $(basename $fw)"
  fi
done

Si TOUS les frameworks media_kit (Ass, Avcodec, Avformat, etc.) sont non signés mais que le script de codesign existe dans le projet, c'est presque certainement un problème d'ordre des phases de compilation.

Notes

  • Ceci affecte principalement les générations de débogage ; les générations de production avec signature de code appropriée peuvent ne pas avoir besoin de ceci
  • L'identité de signature - signifie une signature ad-hoc (aucun certificat requis)
  • Les frameworks affectés de media_kit incluent : Ass.framework, Avcodec.framework, Avformat.framework, Avutil.framework, Dav1d.framework, Freetype.framework, Fribidi.framework, Harfbuzz.framework, Mbedcrypto.framework, Mbedtls.framework, Mbedx509.framework, Mpv.framework, Png16.framework, Swresample.framework, Swscale.framework, Uchardet.framework, Xml2.framework
  • Le || true dans le script empêche les échecs de compilation si la signature échoue pour un framework
  • L'ordre des phases de compilation peut s'arrêter silencieusement après des cycles pod deintegrate + pod install
  • L'API CocoaPods new_shell_script_build_phase ajoute à la fin des phases de compilation, ce qui peut être APRÈS la propre phase d'embarquement de CocoaPods—mais après la réinstallation de pods, la phase d'embarquement peut être rajoutée à la très fin, la poussant APRÈS votre phase de codesign

Lié : Avertissement Mpv.framework en double

Si vous voyez des avertissements du runtime ObjC comme :

Class Application is implemented in both .../Mpv.framework/Versions/A/Mpv (0xADDR1) and
.../Mpv.framework/Versions/A/Mpv (0xADDR2). This may cause spurious casting failures.

Cela indique que Mpv.framework est chargé deux fois, souvent causé par l'utilisation d'un fork git de media_kit_video aux côtés du media_kit_libs_macos_video de pub.dev. Le podspec du fork lie -framework Mpv directement tandis que le package libs le vend aussi. Cela peut causer une corruption du cache de config mpv et des plantages comme :

Assertion failed: (group_index >= 0), function m_config_cache_from_shadow, file m_config_core.c

Une génération complète résout généralement ceci. Si persiste, envisagez de basculer vers la version publiée de media_kit_video.

Références

Skills similaires