├── .gitignore ├── LICENSE ├── README.md ├── android ├── Dockerfile ├── build_openh264.sh ├── build_openssl.sh ├── build_opus.sh └── build_pjsip.sh ├── build_android.sh ├── build_ios.sh ├── ios └── Dockerfile └── release.sh /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | android-dist 3 | ios-dist 4 | .vagrant 5 | .DS_Store 6 | *.tar.gz -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Vadim Ruban 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-pjsip-builder 2 | Easily build PJSIP with: OpenSSL, OpenH264, Opus and G.729 for Android and iOS, by using Docker and xCode. 3 | 4 | ## Versions 5 | | Library | Version | 6 | |----------------------|---------| 7 | | Android API | 23 | 8 | | Android NDK | r12b | 9 | | PJSIP | 2.7.1 | 10 | | OPENSSL | 1.0.2g | 11 | | OPENH264 | 1.7.0 | 12 | | OPUS | 1.2.1 | 13 | 14 | ## Build for Android 15 | ``` 16 | git clone https://github.com/datso/react-native-pjsip-builder 17 | cd react-native-pjsip-builder; ./build_android 18 | ``` 19 | 20 | ## Build for iOS 21 | ``` 22 | TODO: Will be available soon. 23 | ``` 24 | -------------------------------------------------------------------------------- /android/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | ############################## 4 | # Download dependencies 5 | ############################## 6 | 7 | RUN dpkg --add-architecture i386 && \ 8 | apt-get -y upgrade && \ 9 | apt-get -y dist-upgrade && \ 10 | apt-get update 11 | 12 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y install \ 13 | software-properties-common git curl bzip2 gcc g++ binutils make autoconf openssl \ 14 | libssl-dev ant libopus0 libpcre3 libpcre3-dev build-essential nasm libc6:i386 libstdc++6:i386 zlib1g:i386 \ 15 | openjdk-8-jdk unzip 16 | 17 | ############################## 18 | # Configuration 19 | ############################## 20 | 21 | # ENV TARGET_ARCHS "armeabi armeabi-v7a x86 mips arm64-v8a x86_64 mips64" 22 | ENV TARGET_ARCHS "armeabi-v7a x86 arm64-v8a x86_64" 23 | ENV ANDROID_NDK_DOWNLOAD_URL "https://dl.google.com/android/repository/android-ndk-r12b-linux-x86_64.zip" 24 | ENV ANDROID_SDK_DOWNLOAD_URL "https://dl.google.com/android/repository/tools_r25.2.5-linux.zip" 25 | ENV ANDROID_SETUP_APIS "23 25" 26 | ENV ANDROID_BUILD_TOOLS_VERSION 25 27 | ENV ANDROID_TARGET_API 23 28 | 29 | ENV PJSIP_DOWNLOAD_URL "http://www.pjsip.org/release/2.7.1/pjproject-2.7.1.tar.bz2" 30 | 31 | ENV SWIG_DOWNLOAD_URL "http://prdownloads.sourceforge.net/swig/swig-3.0.7.tar.gz" 32 | 33 | ENV OPENSSL_DOWNLOAD_URL "https://www.openssl.org/source/openssl-1.0.2g.tar.gz" 34 | 35 | ENV OPENH264_DOWNLOAD_URL "https://github.com/cisco/openh264/archive/v1.7.0.tar.gz" 36 | ENV OPENH264_TARGET_NDK_LEVEL 23 37 | 38 | ENV OPUS_DOWNLOAD_URL "http://downloads.xiph.org/releases/opus/opus-1.2.1.tar.gz" 39 | ENV OPUS_ANDROID_MK_DOWNLOAD_URL "https://trac.pjsip.org/repos/raw-attachment/ticket/1904/Android.mk" 40 | 41 | ENV PATH /sources/android_ndk:$PATH 42 | 43 | ############################## 44 | # Download sources 45 | ############################## 46 | 47 | RUN mkdir -p /sources/android_ndk && \ 48 | mkdir -p /sources/android_sdk && \ 49 | mkdir -p /sources/pjsip && \ 50 | mkdir -p /sources/swig && \ 51 | mkdir -p /sources/openssl && \ 52 | mkdir -p /sources/opus && \ 53 | mkdir -p /sources/openh264 54 | 55 | # Download Android NDK 56 | RUN cd /sources/android_ndk && \ 57 | curl -L -# -o ndk.zip "$ANDROID_NDK_DOWNLOAD_URL" && \ 58 | unzip ndk.zip && \ 59 | rm -rf ndk.zip && \ 60 | mv android-*/* ./ 61 | 62 | # Download Android SDK & APIs 63 | RUN cd /sources/android_sdk && \ 64 | curl -L -# -o sdk.zip "$ANDROID_SDK_DOWNLOAD_URL" && \ 65 | unzip sdk.zip 66 | 67 | RUN cd /sources/android_sdk/tools && \ 68 | ALL_SDK=$(./android list sdk --all) && \ 69 | IFS=" " && \ 70 | for api in $ANDROID_SETUP_APIS; \ 71 | do \ 72 | PACKAGE=$(echo "${ALL_SDK}" | grep "API ${api}" | head -n 1 | awk '{print $1}' | cut -d'-' -f 1); \ 73 | echo yes | ./android update sdk --all --filter ${PACKAGE} --no-ui --force; \ 74 | done && \ 75 | PACKAGE=$(echo "${ALL_SDK}" | grep "Android SDK Platform-tools" | head -n 1 | awk '{print $1}' | cut -d'-' -f 1) && \ 76 | echo yes | ./android update sdk --all --filter ${PACKAGE} --no-ui --force && \ 77 | PACKAGE=$(echo "${ALL_SDK}" | grep "Build-tools" | grep "${BUILD_TOOLS_VERSION}" | head -n 1 | awk '{print $1}' | cut -d'-' -f 1) && \ 78 | echo yes | ./android update sdk --all --filter ${PACKAGE} --no-ui --force 79 | 80 | # Download Pjsip 81 | RUN cd /sources/pjsip && \ 82 | curl -L -# -o pjsip.tar.bz2 "$PJSIP_DOWNLOAD_URL" && \ 83 | tar xjf pjsip.tar.bz2 && \ 84 | rm -rf pjsip.tar.bz2 && \ 85 | mv pjproject-*/* ./ 86 | 87 | # Download Swig 88 | RUN cd /sources/swig && \ 89 | curl -L -# -o swig.tar.gz "$SWIG_DOWNLOAD_URL" && \ 90 | tar xzf swig.tar.gz && \ 91 | rm -rf swig.tar.gz && \ 92 | mv swig-*/* ./ 93 | 94 | # Download OpenSSL 95 | RUN cd /sources/openssl && \ 96 | curl -L -# -o openssl.tar.gz "$OPENSSL_DOWNLOAD_URL" && \ 97 | tar xzf openssl.tar.gz && \ 98 | rm -rf openssl.tar.gz && \ 99 | mv openssl-*/* ./ 100 | 101 | # Download Opus 102 | RUN cd /sources/opus && \ 103 | curl -L -# -o opus.tar.gz "$OPUS_DOWNLOAD_URL" && \ 104 | tar xzf opus.tar.gz && \ 105 | rm -rf opus.tar.gz && \ 106 | mv opus-*/* ./ && \ 107 | mkdir ./jni && \ 108 | cd ./jni && \ 109 | curl -L -# -o Android.mk "$OPUS_ANDROID_MK_DOWNLOAD_URL" 110 | 111 | # Download OpenH264 112 | RUN cd /sources/openh264 && \ 113 | curl -L -# -o openh264.tar.gz "$OPENH264_DOWNLOAD_URL" && \ 114 | tar xzf openh264.tar.gz && \ 115 | rm -rf openh264.tar.gz && \ 116 | mv openh264-*/* ./ 117 | 118 | ############################## 119 | # Build swig, openssl, opus, openh264 120 | ############################## 121 | 122 | RUN mkdir -p /output/openssl/ && \ 123 | mkdir -p /output/openh264/ && \ 124 | mkdir -p /output/pjsip && \ 125 | mkdir -p /output/opus 126 | 127 | # Build opus 128 | ADD ./build_opus.sh /usr/local/sbin/ 129 | RUN IFS=" " && \ 130 | for arch in $TARGET_ARCHS; \ 131 | do \ 132 | build_opus.sh ${arch}; \ 133 | done 134 | 135 | # Build swig 136 | RUN cd /sources/swig && \ 137 | ./configure && \ 138 | make && \ 139 | make install 140 | 141 | # Build OpenH264 142 | ADD ./build_openh264.sh /usr/local/sbin/ 143 | RUN IFS=" " && \ 144 | for arch in $TARGET_ARCHS; \ 145 | do \ 146 | build_openh264.sh ${arch}; \ 147 | done 148 | 149 | # Build openssl 150 | ADD ./build_openssl.sh /usr/local/sbin/ 151 | RUN IFS=" " && \ 152 | for arch in $TARGET_ARCHS; \ 153 | do \ 154 | build_openssl.sh ${arch}; \ 155 | done 156 | 157 | # Build pjsip 158 | ADD ./build_pjsip.sh /usr/local/sbin/ 159 | RUN IFS=" " && \ 160 | for arch in $TARGET_ARCHS; \ 161 | do \ 162 | build_pjsip.sh ${arch}; \ 163 | done 164 | 165 | # Dist 166 | RUN mkdir -p /dist/android/src/main && \ 167 | mv /output/pjsip/* /dist/android/src/main && \ 168 | rm -rf /dist/android/src/main/java/org/pjsip/pjsua2/app 169 | 170 | RUN IFS=" " && \ 171 | for arch in $TARGET_ARCHS; \ 172 | do \ 173 | mv /output/openh264/${arch}/lib/libopenh264.so /dist/android/src/main/jniLibs/${arch}/; \ 174 | done 175 | -------------------------------------------------------------------------------- /android/build_openh264.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | TARGET_ARCH=$1 5 | TARGET_PATH=/output/openh264/${TARGET_ARCH} 6 | 7 | cp -r /sources/openh264 /tmp/openh264 8 | cd /tmp/openh264 9 | 10 | sed -i "s*PREFIX=/usr/local*PREFIX=${TARGET_PATH}*g" Makefile 11 | 12 | ARGS="OS=android ENABLEPIC=Yes NDKROOT=/sources/android_ndk NDKLEVEL=${OPENH264_TARGET_NDK_LEVEL} " 13 | ARGS="${ARGS}TARGET=android-${ANDROID_TARGET_API} ARCH=" 14 | 15 | if [ "$TARGET_ARCH" == "armeabi" ] 16 | then 17 | ARGS="${ARGS}arm APP_ABI=armeabi" 18 | elif [ "$TARGET_ARCH" == "armeabi-v7a" ] 19 | then 20 | ARGS="${ARGS}arm" 21 | elif [ "$TARGET_ARCH" == "x86" ] 22 | then 23 | ARGS="${ARGS}x86" 24 | elif [ "$TARGET_ARCH" == "x86_64" ] 25 | then 26 | ARGS="${ARGS}x86_64" 27 | elif [ "$TARGET_ARCH" == "arm64-v8a" ] 28 | then 29 | ARGS="${ARGS}arm64" 30 | elif [ "$TARGET_ARCH" == "mips" ] 31 | then 32 | ARGS="${ARGS}mips" 33 | elif [ "$TARGET_ARCH" == "mips64" ] 34 | then 35 | ARGS="${ARGS}mips64" 36 | fi 37 | 38 | make ${ARGS} install 39 | 40 | rm -rf /tmp/openh264 -------------------------------------------------------------------------------- /android/build_openssl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #@see http://stackoverflow.com/questions/11929773/compiling-the-latest-openssl-for-android 3 | set -e 4 | 5 | GCC_VERSION=$(gcc --version | grep gcc | awk '{print $4}' | cut -d'.' -f1,2) 6 | 7 | TARGET_ARCH=$1 8 | TARGET_PATH=/output/openssl/${TARGET_ARCH} 9 | 10 | cp -r /sources/openssl /tmp/openssl 11 | 12 | if [ "$TARGET_ARCH" == "armeabi-v7a" ] 13 | then 14 | TARGET=android-armv7 15 | TOOLCHAIN=arm-linux-androideabi-4.9 16 | export TOOL=arm-linux-androideabi 17 | export ARCH_FLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16" 18 | export ARCH_LINK="-march=armv7-a -Wl,--fix-cortex-a8" 19 | elif [ "$TARGET_ARCH" == "arm64-v8a" ] 20 | then 21 | TARGET=android 22 | TOOLCHAIN=aarch64-linux-android-4.9 23 | export TOOL=aarch64-linux-android 24 | export ARCH_FLAGS= 25 | export ARCH_LINK= 26 | elif [ "$TARGET_ARCH" == "armeabi" ] 27 | then 28 | TARGET=android 29 | TOOLCHAIN=arm-linux-androideabi-4.9 30 | export TOOL=arm-linux-androideabi 31 | export ARCH_FLAGS="-mthumb" 32 | export ARCH_LINK= 33 | elif [ "$TARGET_ARCH" == "x86" ] 34 | then 35 | TARGET=android-x86 36 | TOOLCHAIN=x86-4.9 37 | export TOOL=i686-linux-android 38 | export ARCH_FLAGS="-march=i686 -msse3 -mstackrealign -mfpmath=sse" 39 | export ARCH_LINK= 40 | elif [ "$TARGET_ARCH" == "x86_64" ] 41 | then 42 | TARGET=linux-x86_64 43 | TOOLCHAIN=x86_64-4.9 44 | export TOOL=x86_64-linux-android 45 | elif [ "$TARGET_ARCH" == "mips" ] 46 | then 47 | TARGET=android-mips 48 | TOOLCHAIN=mipsel-linux-android-4.9 49 | export TOOL=mipsel-linux-android 50 | export ARCH_FLAGS= 51 | export ARCH_LINK= 52 | elif [ "$TARGET_ARCH" == "mips64" ] 53 | then 54 | TARGET=android-mips64 55 | TOOLCHAIN=mips64el-linux-android-4.9 56 | export TOOL=mips64el-linux-android 57 | export ARCH_FLAGS= 58 | export ARCH_LINK= 59 | else 60 | echo "Unsupported target ABI: $TARGET_ARCH" 61 | exit 1 62 | fi 63 | 64 | export TOOLCHAIN_PATH="/tmp/openssl/android-toolchain/bin" 65 | export PATH=$TOOLCHAIN_PATH:$PATH 66 | export NDK_TOOLCHAIN_BASENAME=${TOOLCHAIN_PATH}/${TOOL} 67 | export CC=$NDK_TOOLCHAIN_BASENAME-gcc 68 | export CXX=$NDK_TOOLCHAIN_BASENAME-g++ 69 | export LINK=${CXX} 70 | export LD=$NDK_TOOLCHAIN_BASENAME-ld 71 | export AR=$NDK_TOOLCHAIN_BASENAME-ar 72 | export RANLIB=$NDK_TOOLCHAIN_BASENAME-ranlib 73 | export STRIP=$NDK_TOOLCHAIN_BASENAME-strip 74 | export CPPFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 " 75 | export CXXFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 -frtti -fexceptions " 76 | export CFLAGS=" ${ARCH_FLAGS} -fpic -ffunction-sections -funwind-tables -fstack-protector -fno-strict-aliasing -finline-limit=64 " 77 | export LDFLAGS=" ${ARCH_LINK} " 78 | 79 | 80 | ################################ 81 | # TODO 82 | ################################ 83 | 84 | cd /sources/android_ndk/build/tools/ 85 | 86 | ./make-standalone-toolchain.sh \ 87 | --ndk-dir=/sources/android_ndk \ 88 | --platform=android-${ANDROID_TARGET_API} \ 89 | --toolchain=${TOOLCHAIN} \ 90 | --install-dir="/tmp/openssl/android-toolchain" 91 | 92 | cd /tmp/openssl/ 93 | 94 | ################################ 95 | # TODO 96 | ################################ 97 | 98 | ./Configure ${TARGET} no-asm no-unit-test --openssldir=${TARGET_PATH} 99 | make && make install 100 | 101 | rm -rf /tmp/openssl/ 102 | 103 | -------------------------------------------------------------------------------- /android/build_opus.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | TARGET_ARCH=$1 5 | TARGET_PATH=/output/opus/${TARGET_ARCH} 6 | 7 | cp -r /sources/opus /tmp/opus 8 | 9 | cd /tmp/opus/jni 10 | ndk-build APP_ABI="${TARGET_ARCH}" 11 | 12 | mkdir -p ${TARGET_PATH}/include 13 | mkdir -p ${TARGET_PATH}/lib 14 | cp -r ../include ${TARGET_PATH}/include/opus 15 | cp ../obj/local/${TARGET_ARCH}/libopus.a ${TARGET_PATH}/lib/ 16 | 17 | rm -rf /tmp/pjsip -------------------------------------------------------------------------------- /android/build_pjsip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | TARGET_ARCH=$1 5 | TARGET_PATH=/output/pjsip/${TARGET_ARCH} 6 | cp -r /sources/pjsip /tmp/pjsip 7 | 8 | # TODO: Use flags like in vialerpjsip for config.h 9 | cat < "/tmp/pjsip/pjlib/include/pj/config_site.h" 10 | #define PJ_CONFIG_ANDROID 1 11 | #define PJMEDIA_HAS_G729_CODEC 1 12 | #define PJMEDIA_HAS_G7221_CODEC 1 13 | #include 14 | #define PJMEDIA_HAS_VIDEO 1 15 | #define PJMEDIA_AUDIO_DEV_HAS_ANDROID_JNI 0 16 | #define PJMEDIA_AUDIO_DEV_HAS_OPENSL 1 17 | #define PJSIP_AUTH_AUTO_SEND_NEXT 0 18 | EOF 19 | 20 | cd /tmp/pjsip 21 | 22 | export TARGET_ABI=${TARGET_ARCH} 23 | export APP_PLATFORM=android-${ANDROID_TARGET_API} 24 | export ANDROID_NDK_ROOT=/sources/android_ndk 25 | 26 | ./configure-android \ 27 | --use-ndk-cflags \ 28 | --with-ssl="/output/openssl/${TARGET_ARCH}" \ 29 | --with-openh264="/output/openh264/${TARGET_ARCH}" \ 30 | --with-opus="/output/opus/${TARGET_ARCH}" 31 | 32 | make dep 33 | make 34 | 35 | cd /tmp/pjsip/pjsip-apps/src/swig 36 | make 37 | 38 | mkdir -p /output/pjsip/jniLibs/${TARGET_ARCH}/ 39 | mv ./java/android/app/src/main/jniLibs/**/libpjsua2.so /output/pjsip/jniLibs/${TARGET_ARCH}/ 40 | 41 | if [ ! -d "/output/pjsip/java" ]; then 42 | mv ./java/android/app/src/main/java /output/pjsip/java 43 | fi 44 | 45 | rm -rf /tmp/pjsip -------------------------------------------------------------------------------- /build_android.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | IMAGE_NAME="react-native-pjsip-builder/android" 5 | CONTAINER_NAME="react-native-pjsip-builder-${RANDOM}" 6 | 7 | rm -rf ./dist/android; 8 | mkdir -p ./dist/; 9 | 10 | docker build -t react-native-pjsip-builder/android ./android/; 11 | docker run --name ${CONTAINER_NAME} ${IMAGE_NAME} bin/true 12 | 13 | docker cp ${CONTAINER_NAME}:/dist/android ./dist/android 14 | 15 | docker rm ${CONTAINER_NAME} 16 | -------------------------------------------------------------------------------- /build_ios.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | IMAGE_NAME="react-native-pjsip-builder/ios" 5 | CONTAINER_NAME="react-native-pjsip-builder-${RANDOM}" 6 | 7 | rm -rf ./dist/ios; 8 | mkdir -p ./dist/; 9 | 10 | docker build -t react-native-pjsip-builder/ios ./ios/; 11 | docker run --name ${CONTAINER_NAME} ${IMAGE_NAME} bin/true 12 | 13 | docker cp ${CONTAINER_NAME}:/dist/ios ./dist/ios 14 | 15 | docker rm ${CONTAINER_NAME} 16 | -------------------------------------------------------------------------------- /ios/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | RUN apt-get -y upgrade && \ 4 | apt-get -y dist-upgrade && \ 5 | apt-get update 6 | 7 | RUN DEBIAN_FRONTEND=noninteractive apt-get -y install \ 8 | wget unzip 9 | 10 | 11 | ############################## 12 | # Download VialerPJSIP until iOS version is not released 13 | ############################## 14 | 15 | RUN mkdir -p /vialer/ && \ 16 | cd /vialer/ && \ 17 | wget https://github.com/VoIPGRID/Vialer-pjsip-iOS/archive/3.2.0.zip && \ 18 | wget https://github.com/VoIPGRID/Vialer-pjsip-iOS/blob/3.2.0/VialerPJSIP.framework/Versions/A/VialerPJSIP?raw=true && \ 19 | unzip 3.2.0.zip 20 | 21 | RUN mkdir -p /dist/ios/VialerPJSIP.framework && \ 22 | mv /vialer/Vialer-pjsip-iOS-3.2.0/VialerPJSIP.framework/Versions/Current/* /dist/ios/VialerPJSIP.framework && \ 23 | mv /vialer/VialerPJSIP?raw=true /dist/ios/VialerPJSIP.framework/VialerPJSIP -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | rm -rf ./dist; 5 | ./build_android.sh; 6 | ./build_ios.sh; 7 | 8 | cd ./dist; 9 | 10 | tar -czvf ../release.tar.gz ./ --------------------------------------------------------------------------------