#!/bin/bash # # Этот скрипт автоматизирует подготовку окружения и сборку WebRTC libjingle_peerconnection_so с поддержкой H.265 # и сборкой libstream-webrtc-1.3.9.aar от getstream под Android с собранными .so # Что делает: # 1) Ставит пакеты apt, которые нужны для сборки (git, curl, python, ninja, cmake, JDK и т.д.). # 2) Качает набор инструментов depot_tools (fetch/gclient/gn) и добавляет его в PATH. # 3) Загружает исходники WebRTC, переписывает .gclient так, чтобы сборка была под Android (target_os = ["android"]). # 4) Подключает удалённый репозиторий GetStream, переходит на тег m137.0 (это версия, на которой собран их AAR 1.3.9), синхронизирует зависимости и запускает runhooks. # 5) Создаёт вспомогательный Python‑скрипт build_multiabi_aar.py, который поочерёдно собирает AAR для каждой архитектуры и потом объединяет .so в один libstream-webrtc-1.3.9.aar. # 6) Запускает сборку для arm64‑v8a, armeabi‑v7a, x86 и x86_64 с выключенным режимом отладки и включённым H.265. # # Итог: готовый libstream-webrtc-1.3.9.aar лежит в каталоге src, а промежуточные AAR‑файлы по ABI находятся в out/aar/_abi_aars и out/aar//. # # Запуск: запустите этот файл на Ubuntu (понадобятся sudo‑права для apt install). # Скрипт пропустит шаги, если каталоги или удалённый уже существуют. # set -e echo "=== Шаг 1: Обновляем список пакетов и ставим зависимости ===" sudo apt update sudo apt install -y git curl python3 python3-venv python3-pip ninja-build \ cmake default-jdk pkg-config echo "=== Шаг 2: Клонируем depot_tools и добавляем в PATH ===" mkdir -p WEBRTC cd WEBRTC if [ ! -d depot_tools ]; then echo "Клонируем depot_tools..." git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git else echo "Каталог depot_tools уже существует; пропускаем клонирование." fi # Добавляем depot_tools в PATH только для этого скрипта. Это позволит пользоваться # `fetch`, `gclient` и `gn`, не изменяя постоянные настройки пользователя. export PATH="$PWD/depot_tools:$PATH" echo "=== Шаг 3: Качаем исходники WebRTC ===" if [ ! -d src ]; then # `fetch` создаст каталог `src` и файл .gclient. fetch --nohooks webrtc else echo "Каталог src уже есть; пропускаем fetch." fi echo "=== Шаг 4: Правим .gclient под Android ===" # Перезаписываем .gclient и прописываем target_os = [ \"android\" ]. cat > .gclient <<'EOF' solutions = [ { "name": "src", "url": "https://webrtc.googlesource.com/src.git", "deps_file": "DEPS", "managed": False, "custom_deps": {}, }, ] target_os = [ "android" ] EOF echo "=== Шаг 5: Checkout тега m137.0 и синхронизация зависимостей ===" cd src # Добавляем удалённый репозиторий GetStream, если он ещё не добавлен. if ! git remote | grep -q '^stream$'; then echo "Добавляем удалённый репозиторий GetStream..." git remote add stream https://github.com/GetStream/webrtc.git else echo "Удалённый GetStream уже есть; пропускаем добавление." fi git fetch stream --tags # стягиваем теги, чтобы появился m137.0 git checkout tags/m137.0 # переключаемся на нужный тег echo "Запускаем gclient sync и gclient runhooks..." gclient sync --jobs 1 -D gclient runhooks echo "=== Шаг 6: Создаём обёрточный build_multiabi_aar.py ===" # Записываем вспомогательный скрипт в tools_webrtc/android/build_multiabi_aar.py. Он собирает AAR для каждой архитектуры, а потом склеивает их JNI‑библиотеки в единый libstream-webrtc-1.3.9.aar. cat > tools_webrtc/android/build_multiabi_aar.py <<'PY' #!/usr/bin/env python3 """ Обёртка для сборки libwebrtc.aar сразу под несколько ABI. Оригинальный скрипт tools_webrtc/android/build_aar.py за один запуск собирает только одну архитектуру, а итоговый libwebrtc.aar иногда содержит только последнюю собранную архитектуру. Этот скрипт решает проблему: он собирает AAR для каждого ABI по отдельности, потом извлекает из каждого файл jni//libjingle_peerconnection_so.so и собирает их в один архив. Аргумент --arch может повторяться для перечисления нужных ABI (arm64-v8a, armeabi-v7a, x86, x86_64). Дополнительные параметры GN передаются через --extra-gn-args, например чтобы включить H.265. Пример запуска: python3 build_multiabi_aar.py \ --build-dir=out/aar \ --arch=arm64-v8a --arch=armeabi-v7a --arch=x86 --arch=x86_64 \ --extra-gn-args='is_debug=false rtc_include_tests=false rtc_build_examples=false rtc_use_h265=true' \ --final-out=./libwebrtc.aar Итоговый AAR будет записан в файл, указанный параметром --final-out. """ import argparse import os import shutil import subprocess import zipfile import tempfile import sys # Compute the absolute repository root from this script's location. ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")) def run(cmd): """Выполняет команду в корне репозитория и выводит её в терминал.""" print(">>", " ".join(cmd)) subprocess.check_call(cmd, cwd=ROOT) def find_built_aar(build_dir): """Возвращает путь к AAR, собранному build_aar.py, если он существует.""" cand1 = os.path.join(build_dir, "libwebrtc.aar") cand2 = os.path.join(ROOT, "libwebrtc.aar") for c in (cand1, cand2): if os.path.exists(c): return c return None def unzip_member(zpath, member, dest_dir): """Извлекает один файл из ZIP‑архива в указанную директорию.""" with zipfile.ZipFile(zpath, "r") as zf: zf.extract(member, dest_dir) def main(): parser = argparse.ArgumentParser(description="Собрать libwebrtc.aar под несколько ABI") parser.add_argument("--build-dir", default="out/aar", help="Каталог, который использует build_aar.py") parser.add_argument("--arch", action="append", required=True, help="ABI для сборки; повторяйте для нескольких") parser.add_argument("--extra-gn-args", dest="extra_gn_args", default="", help="Дополнительные параметры GN, передаваемые build_aar.py") parser.add_argument("--final-out", default=os.path.join(ROOT, "libwebrtc.aar"), help="Путь к итоговому AAR") args = parser.parse_args() build_dir = os.path.join(ROOT, args.build_dir) os.makedirs(build_dir, exist_ok=True) # A directory to store per‑ABI AARs stash_dir = os.path.join(build_dir, "_abi_aars") os.makedirs(stash_dir, exist_ok=True) built = [] for abi in args.arch: # Construct the command to build the AAR for this ABI cmd = [sys.executable, os.path.join(ROOT, "tools_webrtc", "android", "build_aar.py"), "--build-dir=" + args.build_dir, "--arch=" + abi] if args.extra_gn_args: cmd.append("--extra-gn-args=" + args.extra_gn_args) run(cmd) produced = find_built_aar(build_dir) if not produced: raise RuntimeError(f"libwebrtc.aar not found after building {abi}") abi_aar = os.path.join(stash_dir, f"{abi}.aar") shutil.copy2(produced, abi_aar) print(f"[OK] Stored {abi} AAR -> {abi_aar}") built.append((abi, abi_aar)) # Use first ABI AAR as the base for non‑JNI files base_abi, base_aar = built[0] stage = tempfile.mkdtemp(prefix="webrtc_aar_") with zipfile.ZipFile(base_aar, "r") as zf: zf.extractall(stage) # Replace or create the jni directory with combined libs jni_dir = os.path.join(stage, "jni") shutil.rmtree(jni_dir, ignore_errors=True) os.makedirs(jni_dir, exist_ok=True) for abi, abi_aar in built: tmp = tempfile.mkdtemp(prefix="webrtc_abi_") try: member = f"jni/{abi}/libjingle_peerconnection_so.so" unzip_member(abi_aar, member, tmp) abi_dir = os.path.join(jni_dir, abi) os.makedirs(abi_dir, exist_ok=True) shutil.move(os.path.join(tmp, member), os.path.join(abi_dir, "libjingle_peerconnection_so.so")) finally: shutil.rmtree(tmp, ignore_errors=True) # Write final AAR final_aar = args.final_out if os.path.exists(final_aar): os.remove(final_aar) with zipfile.ZipFile(final_aar, "w", zipfile.ZIP_DEFLATED) as zf: for root, dirs, files in os.walk(stage): for f in files: full = os.path.join(root, f) rel = os.path.relpath(full, stage) zf.write(full, rel) print("\n[OK] Создан многоплатформенный AAR:", final_aar) with zipfile.ZipFile(final_aar, "r") as zf: for n in zf.namelist(): if n.startswith("jni/") and n.endswith(".so"): print(" ", n) if __name__ == "__main__": main() PY # Make the helper script executable chmod +x tools_webrtc/android/build_multiabi_aar.py echo "=== Шаг 7: Сборка libstream-webrtc-1.3.9.aar для нескольких ABI c H.265 ===" # Запускаем вспомогательный скрипт, передавая необходимые архитектуры и параметры GN. # Итоговый AAR будет записан в /libstream-webrtc-1.3.9.aar. python3 tools_webrtc/android/build_multiabi_aar.py \ --build-dir=out/aar \ --arch=arm64-v8a \ --arch=armeabi-v7a \ --arch=x86 \ --arch=x86_64 \ --extra-gn-args='is_debug=false rtc_include_tests=false rtc_build_examples=false rtc_use_h265=true' \ --final-out="$(pwd)/libstream-webrtc-1.3.9.aar" echo "Всё готово!" echo "Готовый libstream-webrtc-1.3.9.aar находится в: $(pwd)/libstream-webrtc-1.3.9.aar" echo "Промежуточные AAR‑файлы по архитектурам лежат в директории out/aar/_abi_aars"