鸿蒙webrtc编译

harmonyos webrtc 编译

一 参考文档:

docs/webrtc_adapter_ohos.md · zhongluping/thirdparty_knowledge - Gitee.com

二 环境准备

1 编译环境

  • ubuntu 18.04
  • webrtc 版本 m80
  • OpenHarmony SDK版本(4.0.10.13)

2 OpenHarmony SDK获取

OpenHarmony 4.0 Release

标准系统Public SDK包(Windows/Linux)
备注: 建议使用最新的sdk

3 编译脚本

ohos_webrtc_compile.sh
备注:一般编译不需要拷贝libyuv库, 我们是由于项目原因拷贝的

#!/bin/bash
export OHOS_SDK=/sharefile/xhw/webrtc/webrtc_m80_src/src/buildtools/ohos-sdk/linux #这里根据自己的SDK解压目录设置
export AS=${OHOS_SDK}/native/llvm/bin/llvm-as
export CC="${OHOS_SDK}/native/llvm/bin/clang  --target=aarch64-linux-ohos"
export CXX="${OHOS_SDK}/native/llvm/bin/clang++  --target=aarch64-linux-ohos"
export LD=${OHOS_SDK}/native/llvm/bin/ld.lld
export STRIP=${OHOS_SDK}/native/llvm/bin/llvm-strip
export RANLIB=${OHOS_SDK}/native/llvm/bin/llvm-ranlib
export OBJDUMP=${OHOS_SDK}/native/llvm/bin/llvm-objdump
export OBJCOPY=${OHOS_SDK}/native/llvm/bin/llvm-objcopy
export NM=${OHOS_SDK}/native/llvm/bin/llvm-nm
export AR=${OHOS_SDK}/native/llvm/bin/llvm-ar
export CFLAGS="-fPIC -D__MUSL__=1"
export CXXFLAGS="-fPIC -D__MUSL__=1"

WORKSPACE=$(pwd)
echo "$WORKSPACE"
export PATH=$WORKSPACE/depot_tools:$WORKSPACE/depot_tools/python-bin:$WORKSPACE/src/buildtools/linux64:$PATH

cd $WORKSPACE/src/third_party
mv libyuv_m80 libyuv
cd $WORKSPACE/src

gn gen out/Release-ohos --args='
                        target_os="ohos" 
                        target_cpu="arm64"
                        rtc_use_x11=true
                        is_debug=false 
                        is_component_build=false
                        rtc_include_tests=false
                        rtc_use_h264=true
                        use_rtti=true
                        use_custom_libcxx=false
                        treat_warnings_as_errors=false
                        is_clang=false
                        rtc_enable_protobuf=false
                        symbol_level=0
                        rtc_build_examples=false
                        proprietary_codecs=true
                        rtc_use_vrv_disnoise = false
                        rtc_use_pipewire=true
                        rtc_build_ssl = false
                        rtc_build_tools =false
                        rtc_ssl_root = "//third_party/openssl"
                        ffmpeg_branding="Chrome"
                        rtc_include_pulse_audio=false
						rtc_use_dummy_audio_file_devices=true
                        '
						
ninja -C out/Release-ohos

cd $WORKSPACE/src/third_party
mv libyuv libyuv_m80
cd $WORKSPACE/src

三 源码修改

1 添加ohos平台

--- a/src/build/config/BUILDCONFIG.gn
+++ b/src/build/config/BUILDCONFIG.gn
@@ -222,6 +222,8 @@ if (target_os == "android") {
   assert(host_os == "linux" || host_os == "mac",
          "Android builds are only supported on Linux and Mac hosts.")
   _default_toolchain = "//build/toolchain/android:android_clang_$target_cpu"
+} else if (target_os == "ohos") {
+   _default_toolchain = "//build/toolchain/ohos:ohos_clang_$target_cpu"
 } else if (target_os == "chromeos" || target_os == "linux") {
   # See comments in build/toolchain/cros/BUILD.gn about board compiles.
   if (is_clang) {
@@ -283,6 +285,7 @@ if (custom_toolchain != "") {
 # aix or one of the BSDs. If you need to check these, just check the
 # current_os value directly.
 
+is_ohos = current_os == "ohos"
 is_android = current_os == "android"
 is_chromeos = current_os == "chromeos"
 is_fuchsia = current_os == "fuchsia"
@@ -366,6 +369,10 @@ if (is_android) {
       [ "//build/config/android:default_orderfile_instrumentation" ]
 }
 
+if (is_ohos) {
+  default_compiler_configs += [ "//build/config/ohos:compiler" ]
+}
+

2 设置ohos平台clang 工具链相关路径

--- a/src/build/config/clang/clang.gni
+++ b/src/build/config/clang/clang.gni
@@ -11,13 +11,27 @@ if(is_mac){
 if(is_win){
   default_clang_base_path+="win"
 }
+
+if (is_ohos) {
+  declare_args() {
+    ohos_sdk_native_root = "//buildtools/ohos-sdk/linux/native"
+  }
+  default_clang_base_path = "${ohos_sdk_native_root}/llvm"
+  clang_lib_path = "${default_clang_base_path}/lib"
+}
+
+
 declare_args() {
   # Indicates if the build should use the Chrome-specific plugins for enforcing
   # coding guidelines, etc. Only used when compiling with Chrome's Clang, not
   # Chrome OS's.
+ 
+if (is_ohos) {
+   clang_use_chrome_plugins = false
+} else {
   clang_use_chrome_plugins =
       is_clang && !is_nacl && !use_xcode_clang &&
       default_toolchain != "//build/toolchain/cros:target"
-
+}
   clang_base_path = default_clang_base_path
 }

备注: 此处ohos_sdk_native_root配置默认的路径,用户需将ohos的SDK拷贝到buildtools目录,且目录需要和配置的保持一致,或者可以在编译时手动配置ohos sdk路径

3 设置ohos平台的sysroot

--- a/src/build/config/sysroot.gni
+++ b/src/build/config/sysroot.gni
@@ -35,6 +35,9 @@ if (sysroot == "") {
 
     # Android uses unified headers, and thus a single compile time sysroot
     sysroot = "$android_toolchain_root/sysroot"
+  } else if (is_ohos) {
+    import("//build/config/clang/clang.gni")
+    sysroot = "${ohos_sdk_native_root}/sysroot"
   } else if ((is_linux || is_chromeos) && use_sysroot) {
     # By default build against a sysroot image downloaded from Cloud Storage
     # during gclient runhooks

4 设置ohos平台clang版本

--- a/src/build/toolchain/toolchain.gni
+++ b/src/build/toolchain/toolchain.gni
@@ -38,7 +38,11 @@ if (generate_linker_map) {
 }
 
 declare_args() {
-  clang_version = "13.0.0"
+  if (is_ohos) {
+    clang_version = "15.0.4"
+  } else {
+   clang_version = "13.0.0"
+  }
 }

5 扩充原本的gcc_toolchain模板功能

备注: 未对此处做修改

这里主要是添加了ohos的用于启动引导程序的.o,gcc_toolchain.gni中template(“single_gcc_toolchain”)添加这几个参数的识别:

--- a/src/build/toolchain/gcc_toolchain.gni
+++ b/src/build/toolchain/gcc_toolchain.gni
@@ -117,6 +117,33 @@ template("gcc_toolchain") {
       rebuild_string = ""
     }
 
+
+   if (defined(invoker.libs_section_prefix)) {
+      libs_section_prefix = invoker.libs_section_prefix
+    } else {
+      libs_section_prefix = ""
+    }
+
+    if (defined(invoker.libs_section_postfix)) {
+      libs_section_postfix = invoker.libs_section_postfix
+    } else {
+      libs_section_postfix = ""
+    }
+
+    if (defined(invoker.solink_libs_section_prefix)) {
+      solink_libs_section_prefix = invoker.solink_libs_section_prefix
+    } else {
+      solink_libs_section_prefix = ""
+    }
+
+    if (defined(invoker.solink_libs_section_postfix)) {
+      solink_libs_section_postfix = invoker.solink_libs_section_postfix
+    } else {
+      solink_libs_section_postfix = ""
+    }
+
+
+
     # GN's syntax can't handle more than one scope dereference at once, like
     # "invoker.toolchain_args.foo", so make a temporary to hold the toolchain
     # args so we can do "invoker_toolchain_args.foo".
@@ -463,7 +490,7 @@ template("gcc_toolchain") {
       if (target_cpu == "mipsel" && is_component_build && is_android) {
         rspfile_content = "-Wl,--start-group -Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}} -Wl,--end-group"
       } else {
-        rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
+        rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive  $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix"
       }
 
       description = "SOLINK $sofile"
@@ -534,7 +561,7 @@ template("gcc_toolchain") {
         strip_command = "${invoker.strip} -o \"$sofile\" \"$unstripped_sofile\""
         command += " && " + strip_command
       }
-      rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
+      rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive  $solink_libs_section_prefix {{libs}} $solink_libs_section_postfix"
 
       description = "SOLINK_MODULE $sofile"
 
@@ -589,7 +616,7 @@ template("gcc_toolchain") {
         start_group_flag = "-Wl,--start-group"
         end_group_flag = "-Wl,--end-group "
       }
-      link_command = "$ld {{ldflags}}${extra_ldflags} -o \"$unstripped_outfile\" $start_group_flag @\"$rspfile\" {{solibs}} $end_group_flag {{libs}}"
+      link_command = "$ld {{ldflags}}${extra_ldflags} -o \"$unstripped_outfile\"  $libs_section_prefix $start_group_flag @\"$rspfile\" {{solibs}} {{libs}} $end_group_flag  $libs_section_postfix"

6 设置各个架构的ohos_clang_toolchain

新建build/toolchain/ohos/BUILD.gn

import("//build/config/sysroot.gni")
import("//build/toolchain/gcc_toolchain.gni")

declare_args() {
  # Whether unstripped binaries, i.e. compiled with debug symbols, should be
  # considered runtime_deps rather than stripped ones.
  ohos_unstripped_runtime_outputs = true
  ohos_extra_cflags = ""
  ohos_extra_cppflags = ""
  ohos_extra_cxxflags = ""
  ohos_extra_asmflags = ""
  ohos_extra_ldflags = ""
}

# The ohos clang toolchains share most of the same parameters, so we have this
# wrapper around gcc_toolchain to avoid duplication of logic.
#
# Parameters:
#  - toolchain_root
#      Path to cpu-specific toolchain within the ndk.
#  - sysroot
#      Sysroot for this architecture.
#  - lib_dir
#      Subdirectory inside of sysroot where libs go.
#  - binary_prefix
#      Prefix of compiler executables.
template("ohos_clang_toolchain") {
  gcc_toolchain(target_name) {
    assert(defined(invoker.toolchain_args),
           "toolchain_args must be defined for ohos_clang_toolchain()")
    toolchain_args = invoker.toolchain_args
    toolchain_args.current_os = "ohos"

    # Output linker map files for binary size analysis.
    enable_linker_map = true

    ohos_libc_dir =
        rebase_path(invoker.sysroot + "/" + invoker.lib_dir, root_build_dir)
 #   libs_section_prefix = "${ohos_libc_dir}/Scrt1.o"
 #   libs_section_prefix += " ${ohos_libc_dir}/crti.o"
 #   libs_section_postfix = "${ohos_libc_dir}/crtn.o"

    if (invoker.target_name == "ohos_clang_arm") {
      abi_target = "arm-linux-ohos"
    } else if (invoker.target_name == "ohos_clang_arm64") {
      abi_target = "aarch64-linux-ohos"
    } else if (invoker.target_name == "ohos_clang_x86_64") {
      abi_target = "x86_64-linux-ohos"
    }

    clang_rt_dir =
        rebase_path("${clang_lib_path}/${abi_target}/nanlegacy",
                    root_build_dir)
    print("ohos_libc_dir :", ohos_libc_dir)
    print("clang_rt_dir :", clang_rt_dir)
#    solink_libs_section_prefix = "${ohos_libc_dir}/crti.o"
#    solink_libs_section_prefix += " ${clang_rt_dir}/clang_rt.crtbegin.o"
#    solink_libs_section_postfix = "${ohos_libc_dir}/crtn.o"
#    solink_libs_section_postfix += " ${clang_rt_dir}/clang_rt.crtend.o"

    _prefix = rebase_path("${clang_base_path}/bin", root_build_dir)
    cc = "${_prefix}/clang"
    cxx = "${_prefix}/clang++"
    ar = "${_prefix}/llvm-ar"
    ld = cxx
    readelf = "${_prefix}/llvm-readobj"
    nm = "${_prefix}/llvm-nm"
    if (!is_debug) {
      strip = rebase_path("${clang_base_path}/bin/llvm-strip", root_build_dir)
      use_unstripped_as_runtime_outputs = ohos_unstripped_runtime_outputs
    }
    extra_cflags = ohos_extra_cflags
    extra_cppflags = ohos_extra_cppflags
    extra_cxxflags = ohos_extra_cxxflags
    extra_asmflags = ohos_extra_asmflags
    extra_ldflags = ohos_extra_ldflags
  }
}


ohos_clang_toolchain("ohos_clang_arm") {
  sysroot = "${sysroot}"
  lib_dir = "usr/lib/arm-linux-ohos"
  toolchain_args = {
    current_cpu = "arm"
  }
}

ohos_clang_toolchain("ohos_clang_arm64") {
  sysroot = "${sysroot}"
  lib_dir = "usr/lib/aarch64-linux-ohos"
  toolchain_args = {
    current_cpu = "arm64"
  }
}

ohos_clang_toolchain("ohos_clang_x86_64") {
  sysroot = "${sysroot}"
  lib_dir = "usr/lib/x86_64-linux-ohos"
  toolchain_args = {
    current_cpu = "x86_64"
  }
}

7 设置ohos的一些编译参数,将其加入到BUILDCONFIG.gn中

新建build/config/ohos/BUILD.gn,该文件主要是定义一个config,该config会被注册到所有的编译目标,该config主要设置了基础的编译选项、宏定义等:

import("//build/config/sysroot.gni")
import("//build/config/clang/clang.gni")
assert(is_ohos)

ohos_clang_base_path = "${ohos_sdk_native_root}/llvm"
ohos_clang_version = "15.0.4"

if (is_ohos) {
  if (current_cpu == "arm") {
    abi_target = "arm-linux-ohos"
  } else if (current_cpu == "x86") {
    abi_target = ""
  } else if (current_cpu == "arm64") {
    abi_target = "aarch64-linux-ohos"
  } else if (current_cpu == "x86_64") {
    abi_target = "x86_64-linux-ohos"
  } else {
    assert(false, "Architecture not supported")
  }
}


config("compiler") {
  cflags = [
    "-ffunction-sections",
    "-fno-short-enums",
    "-fno-addrsig",
  ]

  cflags += [
    "-Wno-unknown-warning-option",
    "-Wno-int-conversion",
    "-Wno-unused-variable",
    "-Wno-misleading-indentation",
    "-Wno-missing-field-initializers",
    "-Wno-unused-parameter",
    "-Wno-c++11-narrowing",
    "-Wno-unneeded-internal-declaration",
    "-Wno-undefined-var-template",
    "-Wno-implicit-int-float-conversion",
  ]
  defines = [
    # The NDK has these things, but doesn't define the constants to say that it
    # does. Define them here instead.
    "HAVE_SYS_UIO_H",
  ]

  defines += [
    "OHOS",
    "__MUSL__",
    "_LIBCPP_HAS_MUSL_LIBC",
    "__BUILD_LINUX_WITH_CLANG",
    "__GNU_SOURCE",
    "_GNU_SOURCE",
  ]

  ldflags = [
    "-Wl,--no-undefined",
    "-Wl,--exclude-libs=libunwind_llvm.a",
    "-Wl,--exclude-libs=libc++_static.a",

    # Don't allow visible symbols from libraries that contain
    # assembly code with symbols that aren't hidden properly.
    # http://crbug.com/448386
    "-Wl,--exclude-libs=libvpx_assembly_arm.a",
  ]

  cflags += [ "--target=$abi_target" ]
  include_dirs = [
    "${sysroot}/usr/include/${abi_target}",
    "${ohos_clang_base_path}/lib/clang/${ohos_clang_version}/include",
  ]

  ldflags += [ "--target=$abi_target" ]

  # Assign any flags set for the C compiler to asmflags so that they are sent
  # to the assembler.
  asmflags = cflags
}

8 build/config/compiler/BUILD.gn 增加对is_ohos得判断

--- a/src/build/config/compiler/BUILD.gn
+++ b/src/build/config/compiler/BUILD.gn
@@ -1242,9 +1242,15 @@ config("compiler_deterministic") {
 config("clang_revision") {
   if (is_clang && clang_base_path == default_clang_base_path) {
     update_args = [
-      "--print-revision",
-      "--verify-version=$clang_version",
+#      "--print-revision",
+#      "--verify-version=$clang_version",
+      "--print-revision"
     ]
+
+    if (!is_ohos) {
+        update_args += [ "--verify-version=$clang_version" ]
+    }
+
     if (llvm_force_head_revision) {
       update_args += [ "--llvm-force-head-revision" ]
     }

9 代码修改

(1) src/base/third_party/libevent

(2) src/third_party/libevent

src/base/third_party/libevent/BUILD.gn

src/third_party/libevent/BUILD.gn

// src/third_party/libevent/BUILD.gn 修改相同
--- a/src/base/third_party/libevent/BUILD.gn
+++ b/src/base/third_party/libevent/BUILD.gn
@@ -43,13 +43,13 @@ static_library("libevent") {
       "mac/event-config.h",
     ]
     include_dirs = [ "mac" ]
-  } else if (is_linux || is_chromeos) {
+  } else if (is_linux || is_chromeos || is_ohos) {
     sources += [
       "epoll.c",
       "linux/config.h",
       "linux/event-config.h",
     ]
-    include_dirs = [ "linux" ]
+    include_dirs = [ "linux", "compat" ]
   } else if (is_android) {
     sources += [
       "android/config.h",

(3) src/third_pary/libsrtp

(4) src/third_pary/usrsctp

(5) src/rtc_base

// libsrtp  usrsctp 修改相同
--- a/src/rtc_base/BUILD.gn
+++ b/src/rtc_base/BUILD.gn
@@ -30,6 +30,9 @@ if (!rtc_build_ssl) {
     if(is_mac){
       lib_ext = "a"
     }
+    if(is_ohos) {
+      lib_ext = "so"
+    }
     if(is_linux){
       lib_cpu_dir = ""
       lib_ext = "so"

(6) sys 下面找不到文件

/sharefile/xhw/webrtc/webrtc_m80_src/src/buildtools/ohos-sdk/linux/native/sysroot/usr/include/ffrt 内容 拷贝到 
/sharefile/xhw/webrtc/webrtc_m80_src/src/buildtools/ohos-sdk/linux/native/sysroot/usr/include/sys

(7) AudioDeviceLinuxALSA 未定义错误

// 处理方式增加编译参数, 先不编译audio
// 编译时增加 rtc_use_dummy_audio_file_devices=true 参数

(8) ffmpeg 编译

third_party/ffmpeg/BUILD.gn

platform_config_root =
    "chromium/config/$ffmpeg_branding/$os_config/$ffmpeg_arch"
修改为:
if(is_ohos)  {
    platform_config_root = "chromium/config/Chromium/linux/arm64"
}
else {
    platform_config_root =
        "chromium/config/$ffmpeg_branding/$os_config/$ffmpeg_arch"
}

(9) modules/video_capture

--- a/src/modules/video_capture/BUILD.gn
+++ b/src/modules/video_capture/BUILD.gn
@@ -90,7 +90,7 @@ if (!build_with_chromium) {
       "../../system_wrappers",
     ]
 
-    if (is_linux || is_chromeos) {
+    if (is_linux || is_chromeos || is_ohos) {
       sources = [
         "linux/device_info_linux.cc",
         "linux/device_info_linux.h",

**(10) src/third_party/zlib **

src/third_party/zlib/BUILD.gn

    defines = [ "CRC32_ARMV8_CRC32" ]
    if (is_android) {
      defines += [ "ARMV8_OS_ANDROID" ]
-    } else if (is_linux || is_chromeos) {
+    } else if (is_linux || is_chromeos || is_ohos) {
      defines += [ "ARMV8_OS_LINUX" ]
    } else if (is_mac) {
      defines += [ "ARMV8_OS_MACOS" ]

11

修改当前项目中不支持ohos的接口

  1. rtc_base/platform_thread_types.cc需要识别到ohos然后调用gettid()

首先需要在根目录的BUILD.gn中配置识别ohos系统的变量:

diff -uprN src/BUILD.gn src_ohos/BUILD.gn
--- src/BUILD.gn	2023-12-15 19:42:56.000000000 -0800
+++ src_ohos/BUILD.gn	2023-12-18 01:12:39.553298189 -0800
@@ -214,6 +214,9 @@ config("common_inherited_config") {
       "WEBRTC_IOS",
     ]
   }
+  if (is_ohos) {
+    defines += [ "WEBRTC_OHOS", "WEBRTC_LINUX" ]
+  }
   if (is_linux || is_chromeos) {
     defines += [ "WEBRTC_LINUX" ]
   }

当前很多业务模块还未进行识别,暂时走linux分支。具体模块需要用户进行分析。

修改rtc_base/platform_thread_types.c业务代码:

--- src/rtc_base/platform_thread_types.cc	2023-12-15 19:42:56.000000000 -0800
+++ src_ohos/rtc_base/platform_thread_types.cc	2023-12-18 00:42:49.393883643 -0800
@@ -40,7 +40,7 @@ PlatformThreadId CurrentThreadId() {
 #elif defined(WEBRTC_POSIX)
 #if defined(WEBRTC_MAC) || defined(WEBRTC_IOS)
   return pthread_mach_thread_np(pthread_self());
-#elif defined(WEBRTC_ANDROID)
+#elif defined(WEBRTC_ANDROID) || defined(WEBRTC_OHOS)
   return gettid();
 #elif defined(WEBRTC_FUCHSIA)
   return zx_thread_self();

当前ohos支持的函数接口为gettid(),因此我们可以将WEBRTC_OHOS判断和WEBRTC_ANDROID放在一起,也可以单独建一个分支,单独建分支时需要注意,其判断需要放在WEBRTC_LINUX之前。

  1. 屏蔽third_party/dav1d中不支持的接口pthread_getaffinity_np

通过分析可知,pthread_getaffinity_np接口是在宏HAVE_PTHREAD_GETAFFINITY_NP生效时调用,故我们只需要将该宏在ohos平台时设置为不生效即可:

--- src/third_party/dav1d/BUILD.gn	2023-12-15 21:08:22.000000000 -0800
+++ src_ohos/third_party/dav1d/BUILD.gn	2023-12-18 17:39:15.988668172 -0800
@@ -56,7 +56,7 @@ config("public_dav1d_config") {
     defines = [ "CONFIG_LOG=1" ]
   }
 
-  if (!is_android && !is_win) {
+  if (!is_android && !is_win && !is_ohos) {
     defines += [
       "HAVE_PTHREAD_GETAFFINITY_NP=1",
       "HAVE_PTHREAD_SETAFFINITY_NP=1",

四 编译带ffmpeg的webrtc

备注: 如果不修改下面配置, 则webrtc无法解码h264数据

1 增加鸿蒙选项

/src/third_party/ffmpeg/ffmpeg_generated.gni
15行

use_linux_config = is_linux || is_fuchsia || is_android
修改为:
use_linux_config = is_linux || is_fuchsia || is_android || is_ohos

2 启动h264解码器

备注:
(1) 如果不做下面配置,解码时找不到解码器
(2) 因为鸿蒙的cpu架构是arm64,所以改的是arm64目录

/sharefile/xhw/allPlat/webrtc/webrtc_m80_src/src/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/libavcodec/codec_list.c 
增加:
&ff_h264_decoder,


/sharefile/xhw/allPlat/webrtc/webrtc_m80_src/src/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/libavcodec/parser_list.c
增加:
&ff_h264_parser,

/sharefile/xhw/allPlat/webrtc/webrtc_m80_src/src/third_party/ffmpeg/chromium/config/ChromeOS/linux/arm64/config.h
801行
修改
#define CONFIG_H264_DECODER 0#define CONFIG_H264_DECODER 1
### WebRTC 源码获取 WebRTC 是一个开源项目,其源码托管在 Google 的代码仓库中。可以通过以下方式获取 WebRTC 的源码: ```bash # 安装 depot_tools git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git export PATH=$PATH:/path/to/depot_tools # 获取 WebRTC 源码 fetch --nohooks webrtc ``` WebRTC 的官方源码地址为:[https://webrtc.googlesource.com/src](https://webrtc.googlesource.com/src) [^1]。 ### WebRTC 的语音通信支持 WebRTC 原生支持语音通信,其音频模块支持多种音频编解码器,如 G.711、G.722、Opus 等。WebRTC 的语音通信功能包括音频采集、编码、网络传输、解码和播放。开发者可以通过 WebRTC 提供的 API 实现高质量的语音通信功能 。 ### WebRTC鸿蒙系统上的使用 目前,WebRTC 官方并未提供专门针对鸿蒙系统的封装版本。不过,由于鸿蒙系统兼容 Android 应用,并支持使用 C/C++ 编写底层模块,因此可以将 WebRTC 源码移植到鸿蒙系统中使用。开发者可以通过以下方式在鸿蒙系统中集成 WebRTC: 1. **使用 NDK 编译 WebRTC**:通过鸿蒙系统的 NDK 工具链将 WebRTC 源码编译为适用于鸿蒙的动态库或静态库。 2. **封装为 HarmonyOS 组件**:将 WebRTC 功能封装为 HarmonyOS 的 Ability 或 Service,供上层应用调用。 3. **利用现有框架**:参考已有 WebRTC 封装方案(如 libjingle、PJSIP 等),结合鸿蒙的开发框架进行适配和集成 [^2]。 ### 示例代码 以下是一个简单的 WebRTC 音频通话初始化代码示例: ```cpp #include "api/audio_codecs/builtin_audio_decoder_factory.h" #include "api/audio_codecs/builtin_audio_encoder_factory.h" #include "api/peer_connection_interface.h" #include "api/create_peerconnection_factory.h" rtc::scoped_refptr<webrtc::PeerConnectionFactoryInterface> peer_connection_factory = webrtc::CreatePeerConnectionFactory( nullptr /* network_thread */, nullptr /* worker_thread */, nullptr /* signaling_thread */, nullptr /* default_adm */, webrtc::CreateBuiltinAudioEncoderFactory(), webrtc::CreateBuiltinAudioDecoderFactory(), nullptr /* audio_processing */); webrtc::PeerConnectionInterface::RTCConfiguration config; config.servers.push_back(webrtc::PeerConnectionInterface::IceServer()); webrtc::PeerConnectionInterface* peer_connection = peer_connection_factory->CreatePeerConnection(config, nullptr, nullptr, nullptr); ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值