diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 000000000..fba03d32d
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,202 @@
+# This is a basic workflow to help you get started with Actions
+
+name: build
+
+# Controls when the workflow will run
+on:
+ push:
+ branches:
+ - master
+ - ytdl-ci
+ pull_request:
+ branches: [master]
+
+
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+ vanilla:
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y autoconf pkg-config libtool ninja-build python3-pip \
+ python3-setuptools unzip openssl ca-certificates nasm
+ sudo pip3 install meson
+ - name: set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ cache: gradle
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+ - name: Setup Android SDK
+ uses: android-actions/setup-android@v2
+ - name: remove old ndk
+ run: sdkmanager --uninstall "ndk;21.4.7075529"
+ rm -rf sdkmanager /usr/local/lib/android/sdk/ndk-bundle
+ - name: Install NDK
+ run: sdkmanager "ndk;24.0.8215888"
+ - name: download-deps
+ working-directory: ./buildscripts
+ run: |
+ export mpvarchoverride=armv7l
+ chmod +x github-prepare.sh
+ ./github-prepare.sh
+ - name: build-apk
+ working-directory: ./buildscripts
+ run: |
+ ./buildall.sh -n
+ - name: relocate apks
+ run: |
+ mkdir -p app/build/outputs/apk/release
+ cp "./app/build/outputs/apk/default/release/app-default-release-unsigned.apk" app/build/outputs/apk/release/mpv-default.apk
+ cp "./app/build/outputs/apk/api29/release/app-api29-release-unsigned.apk" app/build/outputs/apk/release/mpv-api29.apk
+ cp "./app/build/outputs/apk/api29/debug/app-api29-debug.apk" app/build/outputs/apk/release/mpv-api29-debug.apk
+ cp "./app/build/outputs/apk/default/debug/app-default-debug.apk" app/build/outputs/apk/release/mpv-default-debug.apk
+ - name: Sign APK
+ uses: r0adkll/sign-android-release@v1
+ # ID used to access action output
+ id: sign_app
+ with:
+ releaseDirectory: app/build/outputs/apk/release
+ signingKeyBase64: ${{ secrets.SIGNING_KEY }}
+ alias: ${{ secrets.ALIAS }}
+ keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
+ # keyPassword: ${{ secrets.KEY_PASSWORD }}
+ - name : upload APKs
+ uses: actions/upload-artifact@v2
+ with:
+ name: Vanilla-Build
+ path: |
+ app/build/outputs/apk/release/mpv-default-signed.apk
+ app/build/outputs/apk/release/mpv-api29-signed.apk
+ app/build/outputs/apk/release/mpv-default-debug-signed.apk
+ app/build/outputs/apk/release/mpv-api29-debug-signed.apk
+
+
+ x86_64:
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y autoconf pkg-config libtool ninja-build python3-pip \
+ python3-setuptools unzip openssl ca-certificates nasm
+ sudo pip3 install meson
+ - name: set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ cache: gradle
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+ - name: Setup Android SDK
+ uses: android-actions/setup-android@v2
+ - name: remove old ndk
+ run: sdkmanager --uninstall "ndk;21.4.7075529"
+ rm -rf sdkmanager /usr/local/lib/android/sdk/ndk-bundle
+ - name: Install NDK
+ run: sdkmanager "ndk;24.0.8215888"
+ - name: download-deps
+ working-directory: ./buildscripts
+ run: |
+ export mpvarchoverride=x86_64
+ chmod +x github-prepare.sh
+ ./github-prepare.sh x86_64
+ - name: build-apk
+ working-directory: ./buildscripts
+ run: |
+ ./buildall.sh -n
+ - name: relocate apks
+ run: |
+ mkdir -p app/build/outputs/apk/release
+ cp "./app/build/outputs/apk/default/release/app-default-release-unsigned.apk" app/build/outputs/apk/release/mpv-default.apk
+ cp "./app/build/outputs/apk/api29/release/app-api29-release-unsigned.apk" app/build/outputs/apk/release/mpv-api29.apk
+ cp "./app/build/outputs/apk/api29/debug/app-api29-debug.apk" app/build/outputs/apk/release/mpv-api29-debug.apk
+ cp "./app/build/outputs/apk/default/debug/app-default-debug.apk" app/build/outputs/apk/release/mpv-default-debug.apk
+ - name: Sign APK
+ uses: r0adkll/sign-android-release@v1
+ # ID used to access action output
+ id: sign_app
+ with:
+ releaseDirectory: app/build/outputs/apk/release
+ signingKeyBase64: ${{ secrets.SIGNING_KEY }}
+ alias: ${{ secrets.ALIAS }}
+ keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
+ keyPassword: ${{ secrets.KEY_PASSWORD }}
+ - name : upload APKs
+ uses: actions/upload-artifact@v2
+ with:
+ name: x86_64-Build
+ path: |
+ app/build/outputs/apk/release/mpv-default-signed.apk
+ app/build/outputs/apk/release/mpv-api29-signed.apk
+ app/build/outputs/apk/release/mpv-default-debug-signed.apk
+ app/build/outputs/apk/release/mpv-api29-debug-signed.apk
+ Arm86:
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v3
+ - name: Install dependencies
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y autoconf pkg-config libtool ninja-build python3-pip \
+ python3-setuptools unzip openssl ca-certificates nasm
+ sudo pip3 install meson
+ - name: set up JDK 11
+ uses: actions/setup-java@v3
+ with:
+ java-version: '11'
+ distribution: 'temurin'
+ cache: gradle
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+ - name: Setup Android SDK
+ uses: android-actions/setup-android@v2
+ - name: remove old ndk
+ run: sdkmanager --uninstall "ndk;21.4.7075529"
+ rm -rf sdkmanager /usr/local/lib/android/sdk/ndk-bundle
+ - name: Install NDK
+ run: sdkmanager "ndk;24.0.8215888"
+ - name: download-deps
+ working-directory: ./buildscripts
+ run: |
+ export mpvarchoverride=arm64
+ chmod +x github-prepare.sh
+ ./github-prepare.sh arm64
+ - name: build-apk
+ working-directory: ./buildscripts
+ run: |
+ ./buildall.sh -n
+ - name: relocate apks
+ run: |
+ mkdir -p app/build/outputs/apk/release
+ cp "./app/build/outputs/apk/default/release/app-default-release-unsigned.apk" app/build/outputs/apk/release/mpv-default.apk
+ cp "./app/build/outputs/apk/api29/release/app-api29-release-unsigned.apk" app/build/outputs/apk/release/mpv-api29.apk
+ cp "./app/build/outputs/apk/api29/debug/app-api29-debug.apk" app/build/outputs/apk/release/mpv-api29-debug.apk
+ cp "./app/build/outputs/apk/default/debug/app-default-debug.apk" app/build/outputs/apk/release/mpv-default-debug.apk
+ - name: Sign APK
+ uses: r0adkll/sign-android-release@v1
+ # ID used to access action output
+ id: sign_app
+ with:
+ releaseDirectory: app/build/outputs/apk/release
+ signingKeyBase64: ${{ secrets.SIGNING_KEY }}
+ alias: ${{ secrets.ALIAS }}
+ keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
+ keyPassword: ${{ secrets.KEY_PASSWORD }}
+ - name : upload APKs
+ uses: actions/upload-artifact@v2
+ with:
+ name: Arm-Build
+ path: |
+ app/build/outputs/apk/release/mpv-default-signed.apk
+ app/build/outputs/apk/release/mpv-api29-signed.apk
+ app/build/outputs/apk/release/mpv-default-debug-signed.apk
+ app/build/outputs/apk/release/mpv-api29-debug-signed.apk
diff --git a/.gitignore b/.gitignore
index ae4d27e96..d34101282 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@ obj
build
local.properties
*~
+app/src/main/assets/ytdl/python*
diff --git a/app/build.gradle b/app/build.gradle
index 25b3d6bcc..a8af5cbf0 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -6,7 +6,7 @@ android {
defaultConfig {
minSdkVersion 21
- targetSdkVersion 30
+ targetSdkVersion 28
versionCode 28
versionName "2022-03-23-release"
vectorDrawables.useSupportLibrary = true
@@ -26,6 +26,10 @@ android {
buildFeatures {
viewBinding = true
}
+
+ lintOptions {
+ disable 'ExpiredTargetSdkVersion'
+ }
}
dependencies {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3da8357be..c733bceaf 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -166,6 +166,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ val choice = setupChoices[item]
+ dialog.dismiss()
+ runProcess("Setting up $choice:", mutableListOf("ytdl/wrapper", "setup.py", choice))
+ }
+ show()
+ }
+ }
+ binding.updateBtn.setOnClickListener {
+ runProcess("Running youtube-dl --update:", mutableListOf("youtube-dl", "--update"))
+ }
+ binding.updateBtn.isEnabled = File("${context.filesDir.path}/youtube-dl").exists()
+ }
+
+ private fun runProcess(initText: String, command: MutableList)
+ {
+ if (proc != null)
+ return
+
+ var text = initText + "\n"
+ binding.info.text = text
+
+ command[0] = "${context.filesDir.path}/${command[0]}"
+ try {
+ with (ProcessBuilder(command)) {
+ redirectErrorStream(true)
+ proc = start()
+ }
+ } catch (e: Exception) {
+ text += e.message
+ binding.info.text = text
+ return
+ }
+
+ thread {
+ val buf = ByteArray(1024)
+ try {
+ do {
+ val n = proc!!.inputStream.read(buf)
+ if (n > 0) {
+ text += String(buf.copyOfRange(0, n))
+ binding.info.post { binding.info.text = text }
+ }
+ } while (n != -1)
+ } catch (e: IOException) {}
+ proc = null
+ }
+ }
+
+ override fun onDialogClosed(positiveResult: Boolean) {
+ super.onDialogClosed(positiveResult)
+ proc?.destroy()
+ }
+
+ companion object {
+ private val setupChoices = arrayOf("youtube-dl", "yt-dlp")
+ }
+}
diff --git a/app/src/main/jni/Android.mk b/app/src/main/jni/Android.mk
index 102dd35e0..f71dd65ba 100644
--- a/app/src/main/jni/Android.mk
+++ b/app/src/main/jni/Android.mk
@@ -1,5 +1,7 @@
LOCAL_PATH:= $(call my-dir)
-
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+PREFIX = $(PREFIX32)
+endif
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
PREFIX = $(PREFIX64)
endif
diff --git a/app/src/main/jni/Application.mk b/app/src/main/jni/Application.mk
index fa5b0e51b..fcfa92c9d 100644
--- a/app/src/main/jni/Application.mk
+++ b/app/src/main/jni/Application.mk
@@ -1,4 +1,6 @@
+ifneq ($(PREFIX32),)
APP_ABI := armeabi-v7a
+endif
ifneq ($(PREFIX64),)
APP_ABI += arm64-v8a
endif
diff --git a/app/src/main/res/layout/ytdl_format_pref.xml b/app/src/main/res/layout/ytdl_format_pref.xml
new file mode 100644
index 000000000..edca76f00
--- /dev/null
+++ b/app/src/main/res/layout/ytdl_format_pref.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/ytdl_update_pref.xml b/app/src/main/res/layout/ytdl_update_pref.xml
new file mode 100644
index 000000000..1ab423731
--- /dev/null
+++ b/app/src/main/res/layout/ytdl_update_pref.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 5e5d55439..652e01d04 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -42,6 +42,7 @@
Subtitle delay
Showing all files
Showing media files only
+ To play content from video platforms youtube-dl needs to be set up first.\nGo to Settings > Advanced and install youtube-dl there.
Switch Orientation
@@ -104,6 +105,9 @@
Select if playback should continue while popups are open (e.g. playlist dialog)
audio-only
+ Youtube-dl format
+ The settings here influence the format/quality chosen by youtube-dl.
+
Smoother seeking
Horizontal drag
@@ -160,11 +164,19 @@
Edit input.conf
You can edit input.conf here, this is mainly useful for TV remotes and keyboards.\n\nImportant: mpv-android has some hardcoded keys which can\'t be redefined here, e.g. \'j\' to cycle subtitles.
+ Install/Update youtube-dl
+
Param 1:
Param 2:
Enable Interpolation
Video sync:
+ Install
+ Update
+ Select an option above.
+ Prefer H.264
+ Max. Quality:
+ Any
Name
diff --git a/app/src/main/res/xml/pref_advanced.xml b/app/src/main/res/xml/pref_advanced.xml
index 3b90feeb4..8f4b75ec2 100644
--- a/app/src/main/res/xml/pref_advanced.xml
+++ b/app/src/main/res/xml/pref_advanced.xml
@@ -17,6 +17,11 @@
android:positiveButtonText="@string/dialog_save"
android:negativeButtonText="@string/dialog_cancel" />
+
+
+
+
diff --git a/buildscripts/buildall.sh b/buildscripts/buildall.sh
index 8f34cde3f..48b7fdcad 100755
--- a/buildscripts/buildall.sh
+++ b/buildscripts/buildall.sh
@@ -7,7 +7,13 @@ cleanbuild=0
nodeps=0
clang=1
target=mpv-android
+
+if [ -z $mpvarchoverride ]
+then
arch=armv7l
+else
+arch=$mpvarchoverride
+fi
getdeps () {
varname="dep_${1//-/_}[*]"
@@ -114,6 +120,8 @@ build () {
usage () {
echo "Usage: buildall.sh [options] [target]"
echo "Builds the specified target (default: $target)"
+ echo "Setting the enviroment variable 'mpvarchoverride=[target]' will override default architecture"
+ echo "Running buildall.sh after setting mpvarchoverride=arm64 will build only arm64. Accepts same arguments as --arch"
echo "-n Do not build dependencies"
echo "--clean Clean build dirs before compiling"
echo "--gcc Use gcc compiler (unsupported!)"
diff --git a/buildscripts/github-prepare.sh b/buildscripts/github-prepare.sh
new file mode 100644
index 000000000..3e44a84dc
--- /dev/null
+++ b/buildscripts/github-prepare.sh
@@ -0,0 +1,36 @@
+#!/bin/bash -e
+
+. ./include/depinfo.sh
+export WGET="wget"
+
+echo "==> Fetching mpv"
+mkdir -p deps/mpv
+$WGET https://github.com/mpv-player/mpv/archive/master.tar.gz -O master.tgz
+tar -xzf master.tgz -C deps/mpv --strip-components=1 && rm master.tgz
+
+echo "==> Trying to fetch existing prefix"
+mkdir -p build_prefix
+
+echo "==> Fetching deps"
+./include/download-deps.sh
+
+
+if [ "$1" == "arm64" ]; then
+./buildall.sh --arch arm64 mpv
+elif [ "$1" == "x86_64" ]; then
+./buildall.sh --arch x86_64 mpv
+fi
+
+# build everything mpv depends on (but not mpv itself)
+for x in ${dep_mpv[@]}; do
+ echo "==> Building $x"
+ ./buildall.sh $x
+done
+
+echo "==> Building mpv"
+./buildall.sh -n mpv || {
+ # show logfile if configure failed
+ [ ! -f deps/mpv/_build/config.h ] && cat deps/mpv/_build/config.log
+ exit 1
+}
+exit 0
diff --git a/buildscripts/include/depinfo.sh b/buildscripts/include/depinfo.sh
index 6e6b349b6..304d3109d 100755
--- a/buildscripts/include/depinfo.sh
+++ b/buildscripts/include/depinfo.sh
@@ -11,6 +11,8 @@ v_harfbuzz=4.0.1
v_fribidi=1.0.11
v_freetype=2-11-1
v_mbedtls=2.28.0
+v_openssl=1.1.1n
+v_python=3.9.12
## Dependency tree
@@ -25,7 +27,9 @@ dep_harfbuzz=()
dep_libass=(freetype2 fribidi harfbuzz)
dep_lua=()
dep_mpv=(ffmpeg libass lua)
-dep_mpv_android=(mpv)
+dep_openssl=()
+dep_python=(openssl)
+dep_mpv_android=(mpv python)
## Travis-related
diff --git a/buildscripts/include/download-deps.sh b/buildscripts/include/download-deps.sh
index dafe8ae55..357745a80 100755
--- a/buildscripts/include/download-deps.sh
+++ b/buildscripts/include/download-deps.sh
@@ -53,4 +53,37 @@ fi
# mpv
[ ! -d mpv ] && git clone https://github.com/mpv-player/mpv
+# openssl
+if [ ! -d openssl ]; then
+ mkdir openssl
+ $WGET https://www.openssl.org/source/openssl-$v_openssl.tar.gz -O - | \
+ tar -xz -C openssl --strip-components=1
+fi
+
+# python
+if [ ! -d python ]; then
+ mkdir python
+ $WGET https://www.python.org/ftp/python/$v_python/Python-$v_python.tar.xz -O- | \
+ tar -xJ -C python --strip-components=1
+
+ cd python
+ for name in inplace static_modules; do
+ patch -p0 --verbose <../../include/py/$name.patch
+ done
+ # Enables all modules *except* these
+ python3 ../../include/py/uncomment.py Modules/Setup \
+ 'readline|_test|spwd|grp|_crypt|nis|termios|resource|audio|_md5|_sha[125]|_tkinter|syslog|_curses|_g?dbm|_(multibyte)?codec'
+ # SSL path is not used
+ sed 's|^SSL=.*|SSL=/var/empty|' -i Modules/Setup
+ # hashlib via openssl
+ echo '_hashlib _hashopenssl.c -lcrypto' >>Modules/Setup
+ cd ..
+fi
+
cd ..
+
+# youtube-dl
+$WGET https://kitsunemimi.pw/ytdl/dist.zip
+unzip dist.zip -d ../app/src/main/assets/ytdl
+rm -f ../app/src/main/assets/ytdl/youtube-dl # don't need it
+rm dist.zip
diff --git a/buildscripts/include/path.sh b/buildscripts/include/path.sh
index feb63ddb4..8cd72cce1 100755
--- a/buildscripts/include/path.sh
+++ b/buildscripts/include/path.sh
@@ -23,6 +23,7 @@ if [ -n "$ndk_triple" ]; then
unset PKG_CONFIG_PATH
fi
-toolchain=$(echo "$DIR/sdk/android-ndk-r24/toolchains/llvm/prebuilt/"*)
-export PATH="$toolchain/bin:$DIR/sdk/android-ndk-r24:$DIR/sdk/bin:$PATH"
-export ANDROID_HOME="$DIR/sdk/android-sdk-$os"
+SDK=/usr/local/lib/android/sdk
+NDK=$SDK/ndk/24.0.8215888
+toolchain=$(echo "$NDK/toolchains/llvm/prebuilt/"*)
+export PATH="$toolchain/bin:$NDK:$SDK/bin:$PATH"
diff --git a/buildscripts/include/py/inplace.patch b/buildscripts/include/py/inplace.patch
new file mode 100644
index 000000000..679a4a956
--- /dev/null
+++ b/buildscripts/include/py/inplace.patch
@@ -0,0 +1,11 @@
+--- Modules/getpath.c.orig 2021-03-11 11:47:42.769657798 +0100
++++ Modules/getpath.c 2021-03-11 11:52:26.920159439 +0100
+@@ -1293,7 +1293,7 @@
+ PyStatus res;
+
+ /* Path: / "pythonXY.zip" */
+- wchar_t *path = joinpath2(calculate->platlibdir,
++ wchar_t *path = _PyMem_RawWcsdup(
+ L"python" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION)
+ L".zip");
+ if (path == NULL) {
diff --git a/buildscripts/include/py/static_modules.patch b/buildscripts/include/py/static_modules.patch
new file mode 100644
index 000000000..1097aa1fb
--- /dev/null
+++ b/buildscripts/include/py/static_modules.patch
@@ -0,0 +1,10 @@
+--- setup.py 2019-03-25 21:21:05.000000000 +0100
++++ setup.py 2019-06-21 16:52:23.151217709 +0200
+@@ -379,6 +379,7 @@
+ print()
+
+ def build_extension(self, ext):
++ return print('WARNING: not building extension "%s"' % ext.name)
+
+ if ext.name == '_ctypes':
+ if not self.configure_ctypes(ext):
diff --git a/buildscripts/include/py/uncomment.py b/buildscripts/include/py/uncomment.py
new file mode 100644
index 000000000..d12802d8f
--- /dev/null
+++ b/buildscripts/include/py/uncomment.py
@@ -0,0 +1,13 @@
+import sys, re
+with open(sys.argv[1], "r") as f:
+ lines = f.readlines()
+for i, l in enumerate(lines):
+ if not l.startswith("#") or l[1] in " \t\n" or re.match(sys.argv[2], l[1:]): continue
+ elif l.startswith("#*shared*"): continue
+ elif l.startswith("#*disabled*"): break
+ lines[i] = l.lstrip("#")
+ while lines[i].strip().endswith("\\"):
+ i += 1
+ lines[i] = lines[i].lstrip("#")
+with open(sys.argv[1], "w") as f:
+ f.writelines(lines)
diff --git a/buildscripts/scripts/mpv-android.sh b/buildscripts/scripts/mpv-android.sh
index e7f849d79..a2ae4c3fb 100755
--- a/buildscripts/scripts/mpv-android.sh
+++ b/buildscripts/scripts/mpv-android.sh
@@ -24,11 +24,12 @@ nativeprefix () {
fi
}
+prefix32=$(nativeprefix "armv7l")
prefix64=$(nativeprefix "arm64")
prefix_x64=$(nativeprefix "x86_64")
prefix_x86=$(nativeprefix "x86")
-PREFIX=$BUILD/prefix/armv7l PREFIX64=$prefix64 PREFIX_X64=$prefix_x64 PREFIX_X86=$prefix_x86 \
+PREFIX=$BUILD/prefix/armv7l PREFIX64=$prefix64 PREFIX32=$prefix32 PREFIX_X64=$prefix_x64 PREFIX_X86=$prefix_x86 \
ndk-build -C app/src/main -j$cores
./gradlew assembleDebug assembleRelease
diff --git a/buildscripts/scripts/openssl.sh b/buildscripts/scripts/openssl.sh
new file mode 100755
index 000000000..79ba6fcf8
--- /dev/null
+++ b/buildscripts/scripts/openssl.sh
@@ -0,0 +1,36 @@
+#!/bin/bash -e
+
+. ../../include/path.sh
+
+if [ "$1" == "build" ]; then
+ true
+elif [ "$1" == "clean" ]; then
+ rm -rf _build$ndk_suffix
+ exit 0
+else
+ exit 255
+fi
+
+export CFLAGS="-Os"
+
+mkdir -p _build$ndk_suffix
+cd _build$ndk_suffix
+
+case "$ndk_triple" in
+ arm*)
+ target=linux-armv4
+ ;;
+ aarch64*)
+ target=linux-aarch64
+ ;;
+ i686*)
+ target=linux-x86-clang
+ ;;
+ x86_64*)
+ target=linux-x86_64-clang
+ ;;
+esac
+
+../Configure $target no-shared
+make -j$cores
+make DESTDIR="$prefix_dir" install_sw
diff --git a/buildscripts/scripts/python.sh b/buildscripts/scripts/python.sh
new file mode 100755
index 000000000..1968930ba
--- /dev/null
+++ b/buildscripts/scripts/python.sh
@@ -0,0 +1,83 @@
+#!/bin/bash -e
+
+. ../../include/path.sh
+. ../../include/depinfo.sh
+
+if [ "$1" == "build" ]; then
+ true
+elif [ "$1" == "clean" ]; then
+ rm -rf _build$ndk_suffix
+ exit 0
+else
+ exit 255
+fi
+
+# TODO figure this out
+if [[ -z "$mpvarchoverride" && "$ndk_triple" != "arm"* ]]; then
+ echo "Skipping build for $ndk_triple, only supposed to run on ARM (for now)"
+ echo "To build anyway set DOIT=1 env variable"
+ exit 0
+fi
+#
+
+hostpy=python${v_python:0:3}
+if ! command -v $hostpy; then
+ echo "compatible Python ($hostpy) is required to build"
+ exit 1
+fi
+
+# the NDK no longer ships binutils but python requires it...
+export READELF=$(command -v readelf)
+if ! command -v $READELF; then
+ echo "binutils ($READELF) is required to build"
+ exit 1
+fi
+
+function recompile_py () {
+ find . -name '*.pyc' -delete
+ $hostpy -OO -m compileall -b -j4 .
+ # leave only the legacy locations (*.pyc next to *.py)
+ find . -name "__pycache__" -print0 | xargs -0 -- rm -rf
+}
+
+function stub_ctypes () {
+ rm -rf ctypes && mkdir -p ctypes
+ cat >ctypes/__init__.py <<"FILE"
+class cdll():
+ @staticmethod
+ def LoadLibrary(lib):
+ raise OSError
+FILE
+}
+
+export CFLAGS="-Os -I$prefix_dir/include"
+export LDFLAGS="-L$prefix_dir/lib"
+
+mkdir -p _build$ndk_suffix
+cd _build$ndk_suffix
+
+ac_cv_file__dev_ptmx=no ac_cv_file__dev_ptc=no \
+../configure --host=$ndk_triple --build=${ndk_triple%%-*} \
+ --enable-ipv6 --disable-shared --without-ensurepip
+make -j$cores
+rm -rf dest
+make DESTDIR="$PWD/dest" install
+inst=$PWD/dest/usr/local
+
+out=$(realpath ../../../../app/src/main/assets/ytdl)
+rm -f $out/python*
+# copy & strip executable
+cp -v python $out/python3
+llvm-strip -s $out/python3
+# clean stdlib to save space
+pushd $inst/lib/python3.*
+rm -r pydoc_data turtledemo # docs
+rm -r test unittest/test # unittests
+rm -r tkinter sqlite3 venv ensurepip # non-functional anyway
+stub_ctypes # not compiled but needed by youtube-dl
+rm -r lib2to3 idlelib distutils multiprocessing # not used by youtube-dl
+# package stdlib into .zip file
+recompile_py
+zip -9 $out/python3${v_python:2:1}.zip -R '*.pyc'
+popd
+cd ..