Berechtigung wird mit Android Q ffmpeg verweigert ": error = 13, Berechtigung verweigert

9

Ich möchte die Frames aus dem RTSP-Video mit ffmpeg abrufen. Aber für Android 10 oben bekomme ich Fehler wie unten.

 E/FFmpeg: Exception while trying to run: [Ljava.lang.String;@55e447f
java.io.IOException: Cannot run program "/data/user/0/com.example.downloadimagefromurl/files/ffmpeg": error=13, Permission denied
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1050)
    at java.lang.Runtime.exec(Runtime.java:698)
    at java.lang.Runtime.exec(Runtime.java:563)
    at com.github.hiteshsondhi88.libffmpeg.ShellCommand.run(ShellCommand.java:10)
    at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:38)
    at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:10)
    at android.os.AsyncTask$3.call(AsyncTask.java:378)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:919)
 Caused by: java.io.IOException: error=13, Permission denied
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:133)

Als Antwort von @Saurabh Thorat erlaubt Google Apps nicht, Binärdateien aus dem Verzeichnis / data / user auszuführen.

Eine schlechte Lösung, die ich kenne, besteht darin, compileSdkVersion und targetSdkVersion auf 28 oder niedriger zu ändern und meine Anwendung erneut freizugeben, was nicht empfohlen wird.

Daher suche ich auch für zukünftige Versionen nach praktikableren Lösungen.

Jeder Hinweis, Link oder Vorschlag wäre sehr dankbar. Danke im Voraus.

Gowthami
quelle
Vielleicht im Zusammenhang mit diesem stackoverflow.com/questions/8854359/…
Priyankagb
Nein @Priyankagb Ich habe meiner App bereits externe Speicherberechtigungen erteilt
gowthami
Verwenden Sie diese Bibliothek Ich habe github.com/PratikVekariya4445/FFmpegAndroid erstellt , dasselbe Problem, mit dem ich bei einem weiteren Problem der 64-Bit-Unterstützung konfrontiert war. Nach einigen Recherchen habe ich keine Lösung gefunden und eine eigene Bibliothek erstellt und Probleme behoben. Lassen Sie mich wissen, wenn Sie irgendwelche Zweifel oder ein Problem haben
pratik vekariya
Auch für Ihr Beispiel wird der gleiche Fehler angezeigt. 2020-02-24 12: 38: 16.934 2817-3054 / com.techdorid.ffmpegandroid.demo W / System.err: java.io.IOException: Programm "/ data / user kann nicht ausgeführt werden /0/com.techdorid.ffmpegandroid.demo/files/ffmpeg ": error = 13, Berechtigung verweigert
gowthami
In dieser Zeile erhalte ich eine Fehlermeldung (FFmpegExecuteAsyncTask.java:44)
Gowthami

Antworten:

4

Ab Android Q können Sie keine Binärdateien im privaten Datenverzeichnis Ihrer App ausführen.

Vom Issuetracker: https://issuetracker.google.com/issues/128554619

Die Änderung von block exec () in Anwendungsdatendateien für targetAPI> = Q funktioniert wie beabsichtigt. Hintergrundinformationen zu dieser Änderung finden Sie unter https://android-review.googlesource.com/c/platform/system/sepolicy/+/804149 . Das Aufrufen von exec () für beschreibbare Anwendungsdateien stellt eine Verletzung von W ^ X ( https://en.wikipedia.org/wiki/W%5EX ) dar und stellt eine unsichere Anwendungspraxis dar. Ausführbarer Code sollte immer aus der Anwendung APK geladen werden.

Während exec () nicht mehr für Dateien im Home-Verzeichnis der Anwendung funktioniert, wird es weiterhin für Dateien im schreibgeschützten Verzeichnis / data / app unterstützt. Insbesondere sollte es möglich sein, die Binärdateien in das native libs-Verzeichnis Ihrer Anwendung zu packen und android: extractNativeLibs = true zu aktivieren und dann exec () für die Artefakte / data / app aufzurufen. Ein ähnlicher Ansatz wird mit der Funktion wrap.sh durchgeführt, die unter https://developer.android.com/ndk/guides/wrap-script#packaging_wrapsh dokumentiert ist .

Beachten Sie außerdem, dass über exec () ausgeführte ausführbare Dateien nicht gemäß dem Android-Prozesslebenszyklus verwaltet werden und exec () generell von Android-Anwendungen abgeraten wird. Die Verwendung von "exec ()" mit NDK ist zwar keine Android-Dokumentation, behandelt dies jedoch ausführlich. Das Verlassen auf exec () kann in zukünftigen Android-Versionen problematisch sein.

Saurabh Thorat
quelle
Kannst du mir bitte sagen, was ich hinzufügen muss? Um diesen Code zu bearbeiten, ID Android 10
Gowthami
@gowthami hast du das gelöst?
Chitrang
@Chitrang nein ich habe keine Antwort bekommen. Wenn du etwas hast. Bitte teilen Sie mit mir
Gowthami
Deshalb habe ich dieses Kopfgeld angefangen, hoffen wir auf das Beste.
Chitrang
Mit bravobit ffmpeg passiert mir immer das Gleiche und genau das Gleiche ... Immer wenn Google eine neue Android-Version veröffentlicht, müssen Sie die Daumen drücken, damit Ihre App in keiner Weise aufhört zu funktionieren: ((
Diego Perez
4

Ändern Sie nur die Build.gradle-Datei targetSdkVersion 29 bis 28 und installieren Sie Ihre App erneut auf Ihrem Gerät

Ashwin Vavaliya
quelle
2
Vielen Dank. Dies war tatsächlich eine großartige Problemumgehung. Ich bin mir nicht sicher, warum du herabgestimmt wurdest.
Painor
Tolle Problemumgehung, danke!.
dgcipp
2

Die frühere Antwort erklärt das Problem, auf das Sie stoßen, richtig. Dies ist auch ein offenes Thema, das im letzten September angesprochen wurde und im Forum der von Ihnen verwendeten Bibliothek diskutiert wurde (nach dem, was ich im Stack-Trace sehen kann).

Die Lösung für die Kompilierung für SDK 29 besteht darin, keine Binärdateien mehr im Verzeichnis / data / abzulegen und sicherzustellen, dass sie sich im nativen libs-Verzeichnis befinden. Dies kann nicht erreicht werden, nachdem das APK auf nicht gerooteten Geräten installiert und entpackt wurde. Dies sollte daher bei der Vorbereitung des Android-Projekts (z. B. durch Gradle-Einstellungen) korrekt erfolgen und um sicherzustellen, dass der Inhalt bei der Installation ordnungsgemäß entpackt wird: android:extractNativeLibs=true.

In Ihrem Fall verschiebt dieser Code Binärdateien, die als "Assets" gepackt sind, in das Benutzerdatenverzeichnis:

https://github.com/WritingMinds/ffmpeg-android-java/blob/master/FFmpegAndroid/src/main/java/com/github/hiteshsondhi88/libffmpeg/FileUtils.java

Dies ist ein Sicherheitsrisiko, wenn ausführbare Dateien an einem lesbaren / beschreibbaren Speicherort ausgeführt werden. Der Quellcode, auf den ich oben verlinkt habe, müsste entfernt werden, stattdessen die in / libs gepackten nativen Binärdateien. Die Änderung ist sicherer, da der Speicherort / libs in Ihrem Apps-Installationsverzeichnis ausführbar, aber nicht beschreibbar ist.

Zusammenfassend muss die Bibliothek eines Drittanbieters darauf eingehen, oder Sie können dies tun und eine Pull-Anfrage einreichen. Oder teilen Sie Ihre eigenen und kompilieren Sie sie selbst neu.

Es gibt immer noch ein Problem, wenn Ihre App nach der Installation tatsächlich Inhalte herunterlädt und erwartet, dass Downloads ausgeführt werden. Soweit ich in Android 10 sagen kann, ist das jetzt unmöglich.

Die zukunftssichere Lösung besteht darin, keine externen Binärdateien mehr zu verwenden und die Abhängigkeiten als NDK-Projekte zu kompilieren. Sie benötigen JNI-Wrapper für nativen Code (ein bisschen Arbeit). Es gibt ein verwandtes Projekt , von dem ich weiß, dass Sie es untersuchen könnten.

dr_g
quelle
1
Es ist ein bisschen Arbeit, ich habe immer noch Probleme mit der Bibliothek, die Sie erwähnt haben.
Rohan Bojja