基于WebRTC m94 android版本编译 mediasoup-client-android
编译webrtc
准备工作
- 编译环境 Ubuntu 18.04
- webrtc 需要科学上网,代理一定要稳定!!! 代理一定要稳定!!! 代理一定要稳定!!!
- 安装 depot_tools(需要用到depot_tools工具来下载webrtc源码)
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
- 把depot_tools添加到path中去 将depot_tools的路径追加到用户目录的.bashrc文件中 xxx换成你的用户名
export WEBRTC_DEPOT_TOOLS=/home/xxx/webRTC_Source/depot_tools
export PATH=$PATH:$WEBRTC_DEPOT_TOOLS
- 使变量生效, 命令行执行
source ~/.bashrc
下载源码
- 下载 参考官网 Development | WebRTC
mkdir webrtc_android
cd webrtc_android
fetch --nohooks webrtc_android
gclient sync
如果fetch --nohooks webrtc_android 执行失败 直接执行gclient sync即可
- 切换到稳定分支 我切换到m94分支
cd src
git checkout -b m94 branch-heads/4606
/*同步代码*/
cd ..
gclient sync --nohooks
gclient runhooks
如果有执行失败,gclient sync --nohooks、gclient runhooks 哪个失败,重新执行哪个
- 安装编译 WebRTC 所需的依赖
cd src
./build/install-build-deps.sh
./build/install-build-deps-android.sh
编译
编译aar
./tools_webrtc/android/build_aar.py
./tools_webrtc/android/build_aar.py -h : 查看有哪些编译参数
编译libwebrtc.a 和 libwebrtc.jar
- 默认不会编译 webrtc 模块,我们需要在tools_webrtc/android/build_aar.py 文件中加入 ':webrtc'
TARGETS = [
':webrtc',
'sdk/android:libwebrtc',
'sdk/android:libjingle_peerconnection_so',
]
- 如果需要开启h264,需要添加licenses
- 修改 tools_webrtc/libs/generate_licenses.py 如下,添加 LICENSE
'openh264':['third_party/openh264/src/LICENSE'],
'ffmpeg':['third_party/ffmpeg/LICENSE.md'],
位置如下
'g722': ['modules/third_party/g722/LICENSE'],
'fft4g': ['common_audio/third_party/fft4g/LICENSE'],
'spl_sqrt_floor': ['common_audio/third_party/spl_sqrt_floor/LICENSE'],
+ 'openh264':['third_party/openh264/src/LICENSE'],
+ 'ffmpeg':['third_party/ffmpeg/LICENSE.md'],
# TODO(bugs.webrtc.org/1110): Remove this hack. This is not a lib.
- 修改 编译ffmpeg 配置项
third_party/ffmpeg/ffmpeg_generated.gni
-use_linux_config = is_linux || is_fuchsia
+use_linux_config = is_linux || is_fuchsia || is_android
third_party/ffmpeg/chromium/config/Chrome/android/{ABI}/config.h
-#define CONFIG_H264_DECODER 0
+#define CONFIG_H264_DECODER 1
third_party/ffmpeg/chromium/config/Chrome/android/{ABI}/libavcodec/codec_list.c
// 增加 ff_h264_decoder
+ &ff_h264_decoder,
NULL};
third_party/ffmpeg/chromium/config/Chrome/android/{ABI}/libavcodec/parser_list.c
// 增加 ff_h264_parser
+ &ff_h264_parser,
NULL};
- 修改 编译OpenH264 配置项
modules/video_coding/codecs/h264/include/h264.h
class RTC_EXPORT H264Encoder : public VideoEncoder {
public:
+
+ static std::unique_ptr<H264Encoder> Create();
modules/video_coding/codecs/h264/h264.cc
std::vector<SdpVideoFormat> SupportedH264Codecs() {
"0")};
}
+std::unique_ptr<H264Encoder> H264Encoder::Create() {
+#if defined(WEBRTC_USE_H264)
+RTC_LOG(LS_INFO) << "Creating H264EncoderImpl.";
+return std::make_unique<H264EncoderImpl>(cricket::VideoCodec("H264"));
+#else
+RTC_NOTREACHED();
+return nullptr;
+#endif
+}
增加文件 sdk/android/api/org/webrtc/LibH264Decoder.java
+
+package org.webrtc;
+
+public class LibH264Decoder extends WrappedNativeVideoDecoder {
+ @Override
+ public long createNativeVideoDecoder() {
+ return nativeCreateDecoder();
+ }
+
+ static native long nativeCreateDecoder();
+}
sdk/android/api/org/webrtc/LibH264Encoder.java
+package org.webrtc;
+
+public class LibH264Encoder extends WrappedNativeVideoEncoder {
+ @Override
+ public long createNativeVideoEncoder() {
+ return nativeCreateEncoder();
+ }
+
+ static native long nativeCreateEncoder();
+
+ @Override
+ public boolean isHardwareEncoder() {
+ return false;
+ }
+}
增加 sdk/android/src/jni/h264_codec.cc
+#include <jni.h>
+#include "modules/video_coding/codecs/h264/include/h264.h"
+#include "sdk/android/generated_libH264_jni/LibH264Decoder_jni.h"
+#include "sdk/android/generated_libH264_jni/LibH264Encoder_jni.h"
+#include "sdk/android/src/jni/jni_helpers.h"
+namespace webrtc {
+namespace jni {
+static jlong JNI_LibH264Encoder_CreateEncoder(JNIEnv* jni) {
+ return jlongFromPointer(H264Encoder::Create().release());
+}
+static jlong JNI_LibH264Decoder_CreateDecoder(JNIEnv* jni) {
+ return jlongFromPointer(H264Decoder::Create().release());
+}
+} // namespace jni
SoftwareVideoDecoderFactory.java 添加 LibH264Decoder
public class SoftwareVideoDecoderFactory implements VideoDecoderFactory {
@Nullable
@Override
public VideoDecoder createDecoder(VideoCodecInfo codecType) {
+ Logging.d("VideoDecoder", "createDecoder: "+codecType.getName()+" params = "+codecType.getParams());
+ if(codecType.getName().equalsIgnoreCase("H264")){
+ return new LibH264Decoder();
+ }
if (codecType.getName().equalsIgnoreCase("VP8")) {
return new LibvpxVp8Decoder();
}
@@ -43,7 +47,7 @@ public class SoftwareVideoDecoderFactory implements VideoDecoderFactory {
static VideoCodecInfo[] supportedCodecs() {
List<VideoCodecInfo> codecs = new ArrayList<VideoCodecInfo>();
-
+ codecs.add(new VideoCodecInfo("H264", H264Utils.getDefaultH264Params(false)));
codecs.add(new VideoCodecInfo("VP8", new HashMap<>()));
if (LibvpxVp9Decoder.nativeIsSupported()) {
codecs.add(new VideoCodecInfo("VP9", new HashMap<>()));
SoftwareVideoEncoderFactory.java 添加 LibH264Encoder
public class SoftwareVideoEncoderFactory implements VideoEncoderFactory {
@Nullable
@Override
public VideoEncoder createEncoder(VideoCodecInfo info) {
+ Logging.d("VideoEncoder", "createEncoder: "+info.getName()+" params = "+info.getParams());
+ if (info.name.equalsIgnoreCase("H264")) {
+ return new LibH264Encoder();
+ }
if (info.name.equalsIgnoreCase("VP8")) {
return new LibvpxVp8Encoder();
}
@@ -36,7 +40,7 @@ public class SoftwareVideoEncoderFactory implements VideoEncoderFactory {
static VideoCodecInfo[] supportedCodecs() {
List<VideoCodecInfo> codecs = new ArrayList<VideoCodecInfo>();
-
+ codecs.add(new VideoCodecInfo("H264", H264Utils.getDefaultH264Params(false)));
codecs.add(new VideoCodecInfo("VP8", new HashMap<>()));
if (LibvpxVp9Encoder.nativeIsSupported()) {
codecs.add(new VideoCodecInfo("VP9", new HashMap<>()));
sdk/android/BUILD.gn
--- a/sdk/android/BUILD.gn
+++ b/sdk/android/BUILD.gn
@@ -46,6 +46,7 @@ if (is_android) {
":libjingle_peerconnection_java",
":libjingle_peerconnection_metrics_default_java",
":libvpx_vp8_java",
+ ":libH264_java",
":libvpx_vp9_java",
":logging_java",
":peerconnection_java",
@@ -489,6 +490,20 @@ if (is_android) {
]
}
+ rtc_android_library("libH264_java") {
+ visibility = [ "*" ]
+ sources = [
+ "api/org/webrtc/LibH264Decoder.java",
+ "api/org/webrtc/LibH264Encoder.java",
+ ]
+ deps = [
+ ":base_java",
+ ":video_api_java",
+ ":video_java",
+ "//rtc_base:base_java",
+ ]
+ }
+
rtc_android_library("libvpx_vp9_java") {
visibility = [ "*" ]
sources = [
@@ -512,6 +527,7 @@ if (is_android) {
deps = [
":base_java",
+ ":libH264_java",
":libvpx_vp8_java",
":libvpx_vp9_java",
+ ":video_api_java",
+ ":video_java",
+ "//rtc_base:base_java",
+ ]
+ }
+
rtc_android_library("libvpx_vp9_java") {
visibility = [ "*" ]
sources = [
@@ -512,6 +527,7 @@ if (is_android) {
deps = [
":base_java",
+ ":libH264_java",
":libvpx_vp8_java",
":libvpx_vp9_java",
":video_api_java",
@@ -783,6 +799,18 @@ if (current_os == "linux" || is_android) {
]
}
+ rtc_library("libH264_jni") {
+ visibility = [ "*" ]
+ allow_poison = [ "software_video_codecs" ]
+ sources = [ "src/jni/h264_codec.cc" ]
+ deps = [
+ ":base_jni",
+ ":generated_libH264_jni",
+ ":video_jni",
+ "../../modules/video_coding:webrtc_h264",
+ ]
+ }
+
rtc_library("libvpx_vp9_jni") {
visibility = [ "*" ]
allow_poison = [ "software_video_codecs" ]
@@ -799,6 +827,7 @@ if (current_os == "linux" || is_android) {
visibility = [ "*" ]
allow_poison = [ "software_video_codecs" ]
deps = [
+ ":libH264_jni",
":libvpx_vp8_jni",
":libvpx_vp9_jni",
]
@@ -1203,6 +1232,16 @@ if (current_os == "linux" || is_android) {
jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
}
+ generate_jni("generated_libH264_jni") {
+ sources = [
+ "api/org/webrtc/LibH264Decoder.java",
+ "api/org/webrtc/LibH264Encoder.java",
+ ]
+
+ namespace = "webrtc::jni"
+ jni_generator_include = "//sdk/android/src/jni/jni_generator_helper.h"
+ }
+
- 如果需要支持h264 simulcast 分辨率不支持 需要修改文件 modules/video_coding/utility/simulcast_utility.cc
bool SimulcastUtility::ValidSimulcastParameters(const VideoCodec& codec,
} else {
// TODO(mirtad): H264 encoder implementation still assumes the default
// resolution downscaling is used.
- for (int i = 1; i < num_streams; ++i) {
- if (codec.simulcastStream[i].width !=
- codec.simulcastStream[i - 1].width * 2) {
- return false;
- }
- }
+// for (int i = 1; i < num_streams; ++i) {
+// if (codec.simulcastStream[i].width !=
+// codec.simulcastStream[i - 1].width * 2) {
+// return false;
+// }
+// }
}
- 编译命令
./tools_webrtc/android/build_aar.py --extra-gn-args 'is_debug=false is_component_build=false is_clang=true rtc_include_tests=false rtc_use_h264 = true ffmpeg_branding = "Chrome" rtc_enable_protobuf=false use_rtti=true use_custom_libcxx=false' --build-dir ./out/release-build/m94/
- 可能会遇到的问题
ModuleNotFoundError: No module named 'dataclasses'
缺少python依赖
//python2
sudo apt install python-pip
pip install dataclasses
//python3
sudo apt install python3-pip
pip3 install dataclasses
- 输出路径
out/release-build/m94/armeabi-v7a/obj/libwebrtc.a
out/release-build/m94/armeabi-v7a/lib.java/sdk/android/libwebrtc.jar
至此WebRTC编译完成,拷贝出libwebrtc.a libwebrtc.jar 备用
编译mediasoup
下载
mediasoup-client-android m94 编译 下载地址
git clone https://github.com/haiyangwu/mediasoup-client-android.git
git checkout -b 340 3.4.0-beta
编译
将编译好的 各个abi的libwebrtc.a 和libwebrtc.jar 导入mediasoup-client-android的 mediasoup-client/deps/webrtc/lib 目录中替换 用Android Studio 打开, 开始编译吧。。。
mediasoup 320版本编译
WebRTC m84编译
libmediasoupclient 对应的WebRTC版本是 branch-heads/4147
cd src
git checkout -b m84 branch-heads/4147
/*同步代码*/
cd ..
gclient sync --nohooks
gclient runhooks
编译和m94版本类似
libmediasoupclient编译
- 下载libmediasoupclient
- 切换分支 320
git clone https://github.com/versatica/libmediasoupclient
git checkout -b 320 3.2.0
mediasoup-client-android m84 编译 下载地址
git clone https://github.com/haiyangwu/mediasoup-client-android.git
git checkout -b 320 59315929fb2be499c474dd21a4e95b6b69116d80
- 将下载好的libmediasoupclient 320分支拷贝到mediasoup-client-android/mediasoup-client/deps目录下
- 删除SendTransport::ProduceData 相关的方法
- 将webrtc 84分支的头文件导入到mediasoup-client-android/mediasoup-client/deps/webrtc/src目录下 可以从webrtc源码中导出
cd ~/webrtc/android/src
mkdir -p ~/m84/include/third_party/
cp -r api/ ~/m84/include/
cp -r audio/ ~/m84/include/
cp -r base/ ~/m84/include/
cp -r build_overrides/ ~/m84/include/
cp -r call/ ~/m84/include/
cp -r common_audio/ ~/m84/include/
cp -r common_video/ ~/m84/include/
cp -r logging/ ~/m84/include/
cp -r media/ ~/m84/include/
cp -r modules/ ~/m84/include/
cp -r p2p/ ~/m84/include/
cp -r pc/ ~/m84/include/
cp -r rtc_base/ ~/m84/include/
cp -r rtc_tools/ ~/m84/include/
cp -r sdk/ ~/m84/include/
cp -r stats/ ~/m84/include/
cp -r style-guide/ ~/m84/include/
cp -r system_wrappers/ ~/m84/include/
cp -r test/ ~/m84/include/
cp -r third_party/abseil-cpp/ ~/m84/include/third_party/
cp -r tools_webrtc/ ~/m84/include/
cp -r video/ ~/m84/include/
cp .clang-format ~/m84/include/
cp .git-blame-ignore-revs ~/m84/include/
cp .gitignore ~/m84/include/
cp .vpython ~/m84/include/
cp abseil-in-webrtc.md ~/m84/include/
cp AUTHORS ~/m84/include/
cp BUILD.gn ~/m84/include/
cp codereview.settings ~/m84/include/
cp CODE_OF_CONDUCT.md ~/m84/include/
cp common_types.h ~/m84/include/
cp DEPS ~/m84/include/
cp ENG_REVIEW_OWNERS ~/m84/include/
cp LICENSE ~/m84/include/
cp license_template.txt ~/m84/include/
cp native-api.md ~/m84/include/
cp OWNERS ~/m84/include/
cp PATENTS ~/m84/include/
cp PRESUBMIT.py ~/m84/include/
cp presubmit_test.py ~/m84/include/
cp presubmit_test_mocks.py ~/m84/include/
cp pylintrc ~/m84/include/
cp README.chromium ~/m84/include/
cp README.md ~/m84/include/
cp style-guide.md ~/m84/include/
cp WATCHLISTS ~/m84/include/
cp webrtc.gni ~/m84/include/
cp whitespace.txt ~/m84/include/
用Android Studio 打开, 开始编译吧。。。