Skip to content

Commit 2ea6f08

Browse files
committed
ffmpeg: include binary
1 parent 6494ac1 commit 2ea6f08

File tree

2 files changed

+51
-7
lines changed

2 files changed

+51
-7
lines changed

pythonforandroid/recipes/android/src/android/_android.pyx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,41 @@ class AndroidBrowser(object):
280280
import webbrowser
281281
webbrowser.register('android', AndroidBrowser)
282282

283+
# Native executable support on Android.
284+
#
285+
# Android restricts execve() to specific app-owned paths (including the native
286+
# library directory) and resolves native dependencies via the dynamic linker.
287+
# To run standalone binaries (e.g. ffmpeg), they are placed in
288+
# ApplicationInfo.nativeLibraryDir and LD_LIBRARY_PATH is set accordingly.
289+
290+
from android import mActivity
291+
from os.path import join
292+
from os import environ
293+
294+
_NATIVE_LIB_DIR = mActivity.getApplicationInfo().nativeLibraryDir
295+
296+
# ensure dynamic linker can resolve bundled native dependencies
297+
environ["LD_LIBRARY_PATH"] = _NATIVE_LIB_DIR
298+
299+
_EXECUTABLES = {
300+
"ffmpeg": "libffmpegbin.so",
301+
}
302+
303+
def get_executable(name):
304+
"""
305+
Return absolute path to an executable stored in the app's native
306+
library directory.
307+
"""
308+
try:
309+
filename = _EXECUTABLES[name]
310+
except KeyError:
311+
available = ", ".join(sorted(_EXECUTABLES))
312+
raise KeyError(
313+
f"Unknown executable {name}. Available executables: {available}"
314+
)
315+
316+
return join(_NATIVE_LIB_DIR, filename)
317+
283318

284319
def start_service(title="Background Service",
285320
description="", arg="",

pythonforandroid/recipes/ffmpeg/__init__.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
11
from pythonforandroid.toolchain import Recipe, current_directory, shprint
22
from os.path import exists, join, realpath
33
import sh
4+
from multiprocessing import cpu_count
45

56

67
class FFMpegRecipe(Recipe):
78
version = 'n6.1.2'
89
# Moved to github.com instead of ffmpeg.org to improve download speed
910
url = 'https://github.com/FFmpeg/FFmpeg/archive/{version}.zip'
10-
depends = ['sdl2'] # Need this to build correct recipe order
11+
depends = [('sdl2', 'sdl3')] # Need this to build correct recipe order
1112
opts_depends = ['openssl', 'ffpyplayer_codecs', 'av_codecs']
1213
patches = ['patches/configure.patch']
14+
_libs = [
15+
"libavcodec.so",
16+
"libavfilter.so",
17+
"libavutil.so",
18+
"libswscale.so",
19+
"libavdevice.so",
20+
"libavformat.so",
21+
"libswresample.so",
22+
"libffmpegbin.so",
23+
]
24+
built_libraries = dict.fromkeys(_libs, "./lib")
1325

1426
def should_build(self, arch):
1527
build_dir = self.get_build_dir(arch.arch)
@@ -98,9 +110,8 @@ def build_arch(self, arch):
98110
'--disable-symver',
99111
]
100112

101-
# disable binaries / doc
113+
# disable doc
102114
flags += [
103-
'--disable-programs',
104115
'--disable-doc',
105116
]
106117

@@ -148,11 +159,9 @@ def build_arch(self, arch):
148159

149160
configure = sh.Command('./configure')
150161
shprint(configure, *flags, _env=env)
151-
shprint(sh.make, '-j4', _env=env)
162+
shprint(sh.make, '-j', f"{cpu_count()}", _env=env)
152163
shprint(sh.make, 'install', _env=env)
153-
# copy libs:
154-
sh.cp('-a', sh.glob('./lib/lib*.so'),
155-
self.ctx.get_libs_dir(arch.arch))
164+
shprint(sh.cp, "ffmpeg", "./lib/libffmpegbin.so")
156165

157166

158167
recipe = FFMpegRecipe()

0 commit comments

Comments
 (0)