[*] 编译
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
## 支持版本
|
||||
|
||||
* SDK 11
|
||||
* WebRTC m114
|
||||
* WebRTC m120
|
||||
* libmediasoupclient m120
|
||||
|
||||
## C++终端
|
||||
@@ -25,12 +25,16 @@
|
||||
## 鸿蒙编译
|
||||
|
||||
```
|
||||
# WebRTC版本:m114
|
||||
# WebRTC版本:m120
|
||||
# libmediasoupclient版本:m120
|
||||
|
||||
gn gen ./out/ohos_webrtc --args='target_os="ohos" target_cpu="arm64" is_clang=true is_debug=false use_rtti=true rtc_use_h264=true use_custom_libcxx=false rtc_include_tests=false is_component_build=false treat_warnings_as_errors=false rtc_build_examples=false libyuv_include_tests=false rtc_use_dummy_audio_file_devices=true ohos_sdk_native_root="/data/dev/ohos-sdk/linux/native"'
|
||||
# armeabi-v7a
|
||||
gn gen ./out/armeabi-v7a --args='target_os="ohos" target_cpu="arm" is_clang=true is_debug=false use_rtti=true rtc_use_h264=true rtc_use_h265=true rtc_libvpx_build_vp9=true is_component_build=false rtc_include_tests=false libyuv_include_tests=false rtc_build_examples=false treat_warnings_as_errors=false ohos_sdk_native_root="/data/dev/ohos-sdk/linux/native"'
|
||||
ninja -C ./out/armeabi-v7a -j 32
|
||||
|
||||
ninja -C ./out/ohos_webrtc -j 32
|
||||
# arm64-v8a
|
||||
gn gen ./out/arm64-v8a --args='target_os="ohos" target_cpu="arm64" is_clang=true is_debug=false use_rtti=true rtc_use_h264=true rtc_use_h265=true rtc_libvpx_build_vp9=true is_component_build=false rtc_include_tests=false libyuv_include_tests=false rtc_build_examples=false treat_warnings_as_errors=false ohos_sdk_native_root="/data/dev/ohos-sdk/linux/native"'
|
||||
ninja -C ./out/arm64-v8a -j 32
|
||||
```
|
||||
|
||||
## openharmony-sig/ohos_webrtc
|
||||
|
||||
@@ -13,15 +13,15 @@
|
||||
{
|
||||
"name": "default",
|
||||
"material": {
|
||||
"signAlg" : "SHA256withECDSA",
|
||||
"keyAlias" : "debugKey",
|
||||
"signAlg" : "SHA256withECDSA",
|
||||
"profile" : "C:/Users/acgis/.ohos/config/openharmony/default_taoyao_RrmPaKOZ5zMCU4QlpK1kz_6UoyvfsA4RcQxqexSUJ_8=.p7b",
|
||||
"certpath" : "C:/Users/acgis/.ohos/config/openharmony/default_taoyao_RrmPaKOZ5zMCU4QlpK1kz_6UoyvfsA4RcQxqexSUJ_8=.cer",
|
||||
"storeFile": "C:/Users/acgis/.ohos/config/openharmony/default_taoyao_RrmPaKOZ5zMCU4QlpK1kz_6UoyvfsA4RcQxqexSUJ_8=.p12",
|
||||
"keyPassword" : "0000001B8701B2982D8D56F7049724D2E89B72966750D8E2D94B37DDF1538D9D16EB00C8D4DA39EE4C0FC7",
|
||||
"storePassword": "0000001B64642A0B174393A9875F6FCDE476F4BA4682F1EF92210832926366EA9E075136DCBB6361C9D4DD"
|
||||
}
|
||||
"keyPassword" : "0000001BD55750CF879F40EE4EA1B96386BD83692A36E1776974D52D7439FEEEFCB8D2EC5C798FC7C815AE",
|
||||
"storePassword": "0000001B2AC157AB2A1227E77D5E4925A0B59DE84E94B4D146D9C4DA5EAB030537941F0436A3C3E9F26424"
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
"modules": [
|
||||
|
||||
@@ -4,12 +4,17 @@
|
||||
"externalNativeOptions": {
|
||||
"path": "./src/main/cpp/CMakeLists.txt",
|
||||
"cppFlags" : "",
|
||||
"arguments" : "",
|
||||
"arguments" : " \
|
||||
-DMEDIASOUPCLIENT_LOG_DEV=OFF \
|
||||
-DMEDIASOUPCLIENT_LOG_TRACE=OFF \
|
||||
-DMEDIASOUPCLIENT_BUILD_TESTS=OFF \
|
||||
",
|
||||
// 不要自作多情添加一些配置🤡🤡🤡🤡
|
||||
// "cppFlags" : "-D_LIBCPP_STD_VER=17",
|
||||
// "arguments" : "-DOHOS_STL=c++_static",
|
||||
// "arguments" : "-DOHOS_STL=c++_shared",
|
||||
"abiFilters": [ "arm64-v8a" ]
|
||||
// "abiFilters": [ "arm64-v8a" ]
|
||||
"abiFilters": [ "armeabi-v7a" ]
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
|
||||
@@ -8,22 +8,20 @@ project(taoyao VERSION 1.0.0 LANGUAGES C CXX)
|
||||
|
||||
# C编译选项
|
||||
set(CMAKE_C_STANDARD 17)
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c17 -O3")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -std=c17 -O0 -g")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -std=c17 -O3")
|
||||
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -std=c17 -O3")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-rtti -std=c17 -O0 -g")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fno-rtti -std=c17 -O3")
|
||||
|
||||
# C++编译选项
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -O3")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -std=c++17 -O0 -g")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -std=c++17 -O3")
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -std=c++17 -O3")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-rtti -std=c++17 -O0 -g")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-rtti -std=c++17 -O3")
|
||||
|
||||
option(MEDIASOUPCLIENT_LOG_DEV OFF)
|
||||
option(MEDIASOUPCLIENT_LOG_TRACE OFF)
|
||||
option(MEDIASOUPCLIENT_BUILD_TESTS OFF)
|
||||
set(LIBWEBRTC_BINARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps/webrtc/lib/")
|
||||
set(LIBWEBRTC_BINARY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps/webrtc/lib/${OHOS_ARCH}/")
|
||||
set(LIBWEBRTC_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/deps/webrtc/src/")
|
||||
|
||||
ADD_DEFINITIONS(-DNDEBUG)
|
||||
ADD_DEFINITIONS(-DVK_USE_PLATFORM_OHOS=1)
|
||||
|
||||
add_subdirectory("./deps/libmediasoupclient")
|
||||
@@ -37,29 +35,27 @@ add_library(
|
||||
media/RoomClient.cpp
|
||||
media/LocalClient.cpp
|
||||
media/RemoteClient.cpp
|
||||
media/MediaManager.cpp
|
||||
media/Player.cpp
|
||||
media/AudioPlayer.cpp
|
||||
media/VideoPlayer.cpp
|
||||
media/VideoDecoder.cpp
|
||||
media/Capturer.cpp
|
||||
media/VideoEncoder.cpp
|
||||
media/AudioCapturer.cpp
|
||||
media/VideoCapturer.cpp
|
||||
media/VideoEncoder.cpp
|
||||
media/MediaManager.cpp
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
${PROJECT_NAME} PUBLIC
|
||||
"./include"
|
||||
"./deps/webrtc"
|
||||
"./deps/webrtc/src"
|
||||
"./deps/libmediasoupclient/include"
|
||||
"./deps/libmediasoupclient/deps/libsdptransform/include"
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME} PUBLIC
|
||||
mediasoupclient
|
||||
${LIBWEBRTC_BINARY_PATH}/libwebrtc.a
|
||||
# NAPI
|
||||
libace_napi.z.so
|
||||
# LOG
|
||||
@@ -76,14 +72,15 @@ target_link_libraries(
|
||||
libohcamera.so
|
||||
# 图片
|
||||
libnative_image.so
|
||||
# NativeBuffer
|
||||
libnative_buffer.so
|
||||
# NativeWindow
|
||||
libnative_window.so
|
||||
# 编码解码
|
||||
libnative_media_aenc.so
|
||||
libnative_media_venc.so
|
||||
libnative_media_core.so
|
||||
libnative_media_codecbase.so
|
||||
# NativeBuffer
|
||||
libnative_buffer.so
|
||||
# NativeWindow
|
||||
libnative_window.so
|
||||
# libmediasoupclient
|
||||
mediasoupclient
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
/**
|
||||
* 采集器
|
||||
*
|
||||
* TODO: 释放资源判断空指针
|
||||
*
|
||||
* @author acgist
|
||||
*
|
||||
* https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/media/camera/camera-overview.md
|
||||
@@ -19,6 +17,7 @@
|
||||
#ifndef TAOYAO_CAPTURER_HPP
|
||||
#define TAOYAO_CAPTURER_HPP
|
||||
|
||||
// OpenGL ES || VULKAN
|
||||
#define __VULKAN__ true
|
||||
#ifndef __VULKAN__
|
||||
#define __OPENGL__ true
|
||||
@@ -31,6 +30,7 @@
|
||||
#include <GLES3/gl32.h>
|
||||
|
||||
#include "./Signal.hpp"
|
||||
#include "./WebRTC.hpp"
|
||||
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <ohcamera/capture_session.h>
|
||||
|
||||
#include "api/media_stream_track.h"
|
||||
#include "api/media_stream_interface.h"
|
||||
|
||||
#include <ohaudio/native_audiocapturer.h>
|
||||
#include <ohaudio/native_audiostreambuilder.h>
|
||||
@@ -52,27 +53,22 @@ namespace acgist {
|
||||
/**
|
||||
* 采集器
|
||||
*
|
||||
* @tparam Sink 输出管道
|
||||
* @tparam Source 输出管道
|
||||
*/
|
||||
template <typename Sink>
|
||||
template <typename Source>
|
||||
class Capturer {
|
||||
|
||||
protected:
|
||||
bool running = false;
|
||||
|
||||
public:
|
||||
// id = rtc::scoped_refptr
|
||||
std::map<std::string, Sink*> map;
|
||||
Source* source;
|
||||
|
||||
public:
|
||||
Capturer();
|
||||
virtual ~Capturer();
|
||||
|
||||
public:
|
||||
// 添加管道
|
||||
virtual bool add(const std::string& id, Sink* sink);
|
||||
// 删除管道
|
||||
virtual bool remove(const std::string& id);
|
||||
// 开始采集
|
||||
virtual bool start() = 0;
|
||||
// 结束采集
|
||||
@@ -80,42 +76,19 @@ public:
|
||||
|
||||
};
|
||||
|
||||
template <typename Sink>
|
||||
acgist::Capturer<Sink>::Capturer() {}
|
||||
template <typename Source>
|
||||
acgist::Capturer<Source>::Capturer() {}
|
||||
|
||||
template <typename Sink>
|
||||
acgist::Capturer<Sink>::~Capturer() {
|
||||
for (auto iterator = this->map.begin(); iterator != this->map.end(); ++iterator) {
|
||||
template <typename Source>
|
||||
acgist::Capturer<Source>::~Capturer() {
|
||||
// TODO:释放
|
||||
// delete iterator->second;
|
||||
// iterator->second = nullptr;
|
||||
}
|
||||
this->map.clear();
|
||||
}
|
||||
|
||||
template <typename Sink>
|
||||
bool acgist::Capturer<Sink>::add(const std::string& id, Sink* sink) {
|
||||
this->map.insert({ id, sink });
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Sink>
|
||||
bool acgist::Capturer<Sink>::remove(const std::string& id) {
|
||||
auto iterator = this->map.find(id);
|
||||
if (iterator == this->map.end()) {
|
||||
return false;
|
||||
}
|
||||
// TODO:释放
|
||||
// delete iterator->second;
|
||||
// iterator->second = nullptr;
|
||||
this->map.erase(iterator);
|
||||
return true;
|
||||
// delete this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* 音频采集器
|
||||
*/
|
||||
class AudioCapturer: public Capturer<webrtc::AudioTrackSinkInterface> {
|
||||
class AudioCapturer: public Capturer<acgist::TaoyaoAudioTrackSource> {
|
||||
|
||||
public:
|
||||
// 音频构造器
|
||||
@@ -136,7 +109,7 @@ public:
|
||||
/**
|
||||
* 视频采集器
|
||||
*/
|
||||
class VideoCapturer: public Capturer<rtc::VideoSinkInterface<webrtc::VideoFrame>> {
|
||||
class VideoCapturer: public Capturer<acgist::TaoyaoVideoTrackSource> {
|
||||
|
||||
public:
|
||||
// ================ Vulkan ================
|
||||
|
||||
@@ -13,22 +13,13 @@
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#include "api/media_stream_interface.h"
|
||||
#include "./WebRTC.hpp"
|
||||
#include "./Capturer.hpp"
|
||||
|
||||
#include "api/peer_connection_interface.h"
|
||||
#include "api/video/video_sink_interface.h"
|
||||
#include "api/video/video_source_interface.h"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
class TaoyaoAudioSink : public webrtc::AudioTrackSinkInterface {
|
||||
};
|
||||
|
||||
class TaoyaoVideoSource : public webrtc::VideoTrackSourceInterface {
|
||||
};
|
||||
|
||||
class TaoyaoVideoSink : public rtc::VideoSinkInterface<webrtc::RecordableEncodedFrame> {
|
||||
};
|
||||
|
||||
class MediaManager {
|
||||
|
||||
public:
|
||||
@@ -37,6 +28,10 @@ public:
|
||||
|
||||
public:
|
||||
int localClientRef = 0;
|
||||
rtc::scoped_refptr<webrtc::AudioSourceInterface> audioTrackSource = nullptr;
|
||||
acgist::TaoyaoVideoTrackSource* videoTrackSource = nullptr;
|
||||
acgist::AudioCapturer* audioCapturer = nullptr;
|
||||
acgist::VideoCapturer* videoCapturer = nullptr;
|
||||
std::unique_ptr<rtc::Thread> networkThread = nullptr;
|
||||
std::unique_ptr<rtc::Thread> signalingThread = nullptr;
|
||||
std::unique_ptr<rtc::Thread> workerThread = nullptr;
|
||||
@@ -47,14 +42,6 @@ protected:
|
||||
bool newPeerConnectionFactory();
|
||||
// 释放PC工厂
|
||||
bool releasePeerConnectionFactory();
|
||||
|
||||
public:
|
||||
// 加载媒体
|
||||
bool init();
|
||||
// 新增本地终端
|
||||
int newLocalClient();
|
||||
// 释放本地终端
|
||||
int releaseLocalClient();
|
||||
// 开始采集
|
||||
bool startCapture();
|
||||
// 开始采集音频
|
||||
@@ -67,6 +54,14 @@ public:
|
||||
bool stopAudioCapture();
|
||||
// 结束采集视频
|
||||
bool stopVideoCapture();
|
||||
|
||||
public:
|
||||
// 加载媒体
|
||||
bool init();
|
||||
// 新增本地终端
|
||||
int newLocalClient();
|
||||
// 释放本地终端
|
||||
int releaseLocalClient();
|
||||
// 音频来源
|
||||
rtc::scoped_refptr<webrtc::AudioTrackInterface> getAudioTrack();
|
||||
// 视频来源
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#ifndef TAOYAO_SIGNAL_HPP
|
||||
#define TAOYAO_SIGNAL_HPP
|
||||
|
||||
#include <bits/alltypes.h>
|
||||
#include <string>
|
||||
|
||||
#include <json.hpp>
|
||||
|
||||
@@ -1,10 +1,36 @@
|
||||
/**
|
||||
* WebRTC功能
|
||||
*
|
||||
* 视频编码解码
|
||||
*
|
||||
* @author acgist
|
||||
*/
|
||||
|
||||
#ifndef TAOYAO_WEBRTC_HPP
|
||||
#define TAOYAO_WEBRTC_HPP
|
||||
|
||||
#include "./Signal.hpp"
|
||||
|
||||
#include <ohaudio/native_audiorenderer.h>
|
||||
#include <ohaudio/native_audiostreambuilder.h>
|
||||
//#include <ohaudio/native_audiorenderer.h>
|
||||
//#include <ohaudio/native_audiostreambuilder.h>
|
||||
|
||||
//#include "api/audio_codecs/audio_encoder.h"
|
||||
//#include "api/audio_codecs/audio_decoder.h"
|
||||
//#include "api/audio_codecs/audio_encoder_factory.h"
|
||||
//#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
|
||||
#include "api/media_stream_track.h"
|
||||
#include "api/media_stream_interface.h"
|
||||
#include "api/video/video_sink_interface.h"
|
||||
#include "api/video/video_source_interface.h"
|
||||
|
||||
#include "media/base/video_broadcaster.h"
|
||||
#include "media/base/adapted_video_track_source.h"
|
||||
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/video_decoder.h"
|
||||
#include "api/video_codecs/video_encoder_factory.h"
|
||||
#include "api/video_codecs/video_decoder_factory.h"
|
||||
|
||||
#include <multimedia/player_framework/native_avformat.h>
|
||||
#include <multimedia/player_framework/native_avbuffer.h>
|
||||
@@ -13,23 +39,50 @@
|
||||
#include <multimedia/player_framework/native_avcodec_videoencoder.h>
|
||||
#include <multimedia/player_framework/native_avcodec_videodecoder.h>
|
||||
|
||||
#include "api/rtp_sender_interface.h"
|
||||
#include "api/video_codecs/sdp_video_format.h"
|
||||
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
|
||||
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
|
||||
#include "api/video_codecs/builtin_video_decoder_factory.h"
|
||||
#include "api/video_codecs/builtin_video_encoder_factory.h"
|
||||
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
||||
#include "modules/video_coding/codecs/h264/include/h264.h"
|
||||
|
||||
namespace acgist {
|
||||
|
||||
/**
|
||||
* 音频轨道来源
|
||||
*/
|
||||
class TaoyaoAudioTrackSource : public webrtc::AudioTrackSinkInterface {
|
||||
|
||||
public:
|
||||
virtual void OnData(const void* audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels, size_t number_of_frames) override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 视频管道
|
||||
*/
|
||||
class VideoTrackSinkInterface {
|
||||
|
||||
public:
|
||||
virtual void OnData(const webrtc::VideoFrame& videoFrame) = 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 视频轨道来源
|
||||
*/
|
||||
class TaoyaoVideoTrackSource : public VideoTrackSinkInterface, public rtc::AdaptedVideoTrackSource {
|
||||
|
||||
public:
|
||||
TaoyaoVideoTrackSource();
|
||||
virtual ~TaoyaoVideoTrackSource() override;
|
||||
|
||||
public:
|
||||
virtual webrtc::MediaSourceInterface::SourceState state() const override;
|
||||
virtual bool remote() const override;
|
||||
virtual bool is_screencast() const override;
|
||||
virtual absl::optional<bool> needs_denoising() const override;
|
||||
virtual void OnData(const webrtc::VideoFrame& videoFrame) override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 视频编码
|
||||
*/
|
||||
class VideoEncoder : public webrtc::VideoEncoder {
|
||||
class TaoyaoVideoEncoder : public webrtc::VideoEncoder {
|
||||
|
||||
public:
|
||||
// 视频编码器
|
||||
@@ -38,8 +91,8 @@ public:
|
||||
OHNativeWindow* nativeWindow = nullptr;
|
||||
|
||||
public:
|
||||
VideoEncoder();
|
||||
virtual ~VideoEncoder();
|
||||
TaoyaoVideoEncoder();
|
||||
virtual ~TaoyaoVideoEncoder() override;
|
||||
|
||||
public:
|
||||
// 初始配置
|
||||
@@ -58,25 +111,34 @@ public:
|
||||
virtual bool start();
|
||||
// 结束编码
|
||||
virtual bool stop();
|
||||
virtual int32_t Release() override;
|
||||
virtual int32_t RegisterEncodeCompleteCallback(webrtc::EncodedImageCallback* callback) override;
|
||||
virtual void SetRates(const webrtc::VideoEncoder::RateControlParameters& parameters) override;
|
||||
virtual webrtc::VideoEncoder::EncoderInfo GetEncoderInfo() const override;
|
||||
virtual int32_t Encode(const webrtc::VideoFrame& frame, const std::vector<webrtc::VideoFrameType>* frame_types) override;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 视频解码器
|
||||
*/
|
||||
class VideoDecoder : public webrtc::VideoDecoder {
|
||||
class TaoyaoVideoDecoder : public webrtc::VideoDecoder {
|
||||
|
||||
public:
|
||||
VideoDecoder();
|
||||
virtual ~VideoDecoder();
|
||||
TaoyaoVideoDecoder();
|
||||
virtual ~TaoyaoVideoDecoder() override;
|
||||
|
||||
public:
|
||||
virtual bool start();
|
||||
virtual bool stop();
|
||||
virtual int32_t Release() override;
|
||||
virtual int32_t RegisterDecodeCompleteCallback(webrtc::DecodedImageCallback* callback) override;
|
||||
virtual bool Configure(const webrtc::VideoDecoder::Settings& settings) override;
|
||||
virtual int32_t Decode(const webrtc::EncodedImage& input_image, bool missing_frames, int64_t render_time_ms) override;
|
||||
|
||||
};
|
||||
|
||||
class TaoyaoVideoEncoderFactory : webrtc::VideoEncoderFactory {
|
||||
class TaoyaoVideoEncoderFactory : public webrtc::VideoEncoderFactory {
|
||||
|
||||
public:
|
||||
TaoyaoVideoEncoderFactory();
|
||||
@@ -88,7 +150,7 @@ public:
|
||||
|
||||
};
|
||||
|
||||
class TaoyaoVideoDecoderFactory : webrtc::VideoDecoderFactory {
|
||||
class TaoyaoVideoDecoderFactory : public webrtc::VideoDecoderFactory {
|
||||
|
||||
public:
|
||||
TaoyaoVideoDecoderFactory();
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/**
|
||||
* 音频采集不用实现(系统已经实现)
|
||||
* 这里只是用来学习使用
|
||||
*/
|
||||
#include "../include/Capturer.hpp"
|
||||
|
||||
#include <hilog/log.h>
|
||||
|
||||
#include "rtc_base/time_utils.h"
|
||||
|
||||
// 采集回调
|
||||
static int32_t OnError(OH_AudioCapturer* capturer, void* userData, OH_AudioStream_Result error);
|
||||
static int32_t OnReadData(OH_AudioCapturer* capturer, void* userData, void* buffer, int32_t length);
|
||||
@@ -77,10 +79,7 @@ static int32_t OnError(OH_AudioCapturer* capturer, void* userData, OH_AudioStrea
|
||||
|
||||
static int32_t OnReadData(OH_AudioCapturer* capturer, void* userData, void* buffer, int32_t length) {
|
||||
acgist::AudioCapturer* audioCapturer = (acgist::AudioCapturer*) userData;
|
||||
int64_t timeMillis = rtc::TimeMillis();
|
||||
for (auto iterator = audioCapturer->map.begin(); iterator != audioCapturer->map.end(); ++iterator) {
|
||||
iterator->second->OnData(buffer, acgist::bitsPerSample, acgist::samplingRate, acgist::channelCount, sizeof(buffer) / 2, timeMillis);
|
||||
}
|
||||
audioCapturer->source->OnData(buffer, acgist::bitsPerSample, acgist::samplingRate, acgist::channelCount, sizeof(buffer) / 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* 音频播放不用实现(系统已经实现)
|
||||
* 这里只是用来学习使用
|
||||
*/
|
||||
|
||||
#include "../include/Player.hpp"
|
||||
|
||||
#include <hilog/log.h>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "hilog/log.h"
|
||||
#include <hilog/log.h>
|
||||
|
||||
#include "api/create_peerconnection_factory.h"
|
||||
#include "api/audio_codecs/audio_decoder_factory.h"
|
||||
@@ -45,17 +45,23 @@ bool acgist::MediaManager::newPeerConnectionFactory() {
|
||||
}
|
||||
this->peerConnectionFactory = webrtc::CreatePeerConnectionFactory(
|
||||
this->networkThread.get(),
|
||||
// worker和signaling使用相同线程
|
||||
this->workerThread.get(),
|
||||
// this->signalingThread.get(),
|
||||
this->signalingThread.get(),
|
||||
nullptr /* default_adm */,
|
||||
// 音频设备
|
||||
nullptr,
|
||||
// 音频编码
|
||||
webrtc::CreateBuiltinAudioEncoderFactory(),
|
||||
// 音频解码
|
||||
webrtc::CreateBuiltinAudioDecoderFactory(),
|
||||
// 视频编码
|
||||
webrtc::CreateBuiltinVideoEncoderFactory(),
|
||||
// 视频解码
|
||||
webrtc::CreateBuiltinVideoDecoderFactory(),
|
||||
nullptr /* audio_mixer */,
|
||||
nullptr /* audio_processing */
|
||||
// 混音
|
||||
nullptr,
|
||||
// 音频处理
|
||||
nullptr
|
||||
);
|
||||
return this->peerConnectionFactory != nullptr;
|
||||
}
|
||||
@@ -65,7 +71,11 @@ bool acgist::MediaManager::releasePeerConnectionFactory() {
|
||||
return true;
|
||||
}
|
||||
OH_LOG_INFO(LOG_APP, "释放PeerConnectionFactory");
|
||||
// TODO:释放
|
||||
if(this->peerConnectionFactory != nullptr) {
|
||||
this->peerConnectionFactory->Release();
|
||||
// delete this->peerConnectionFactory;
|
||||
this->peerConnectionFactory = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -78,6 +88,7 @@ int acgist::MediaManager::newLocalClient() {
|
||||
this->startCapture();
|
||||
}
|
||||
}
|
||||
return this->localClientRef;
|
||||
}
|
||||
|
||||
int acgist::MediaManager::releaseLocalClient() {
|
||||
@@ -93,31 +104,56 @@ int acgist::MediaManager::releaseLocalClient() {
|
||||
}
|
||||
}
|
||||
}
|
||||
return this->localClientRef;
|
||||
}
|
||||
|
||||
bool acgist::MediaManager::startCapture() {
|
||||
this->startAudioCapture();
|
||||
this->startVideoCapture();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acgist::MediaManager::startAudioCapture() {
|
||||
|
||||
if(this->audioCapturer != nullptr) {
|
||||
return true;
|
||||
}
|
||||
this->audioCapturer = new acgist::AudioCapturer();
|
||||
this->audioCapturer->start();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acgist::MediaManager::startVideoCapture() {
|
||||
if(this->videoCapturer != nullptr) {
|
||||
return true;
|
||||
}
|
||||
this->videoCapturer = new acgist::VideoCapturer();
|
||||
this->videoCapturer->start();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acgist::MediaManager::stopCapture() {
|
||||
this->stopAudioCapture();
|
||||
this->stopVideoCapture();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acgist::MediaManager::stopAudioCapture() {
|
||||
if(this->audioCapturer == nullptr) {
|
||||
return true;
|
||||
}
|
||||
this->audioCapturer->stop();
|
||||
delete this->audioCapturer;
|
||||
this->audioCapturer = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acgist::MediaManager::stopVideoCapture() {
|
||||
if(this->videoCapturer == nullptr) {
|
||||
return true;
|
||||
}
|
||||
this->videoCapturer->stop();
|
||||
delete this->videoCapturer;
|
||||
this->videoCapturer = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -127,12 +163,11 @@ rtc::scoped_refptr<webrtc::AudioTrackInterface> acgist::MediaManager::getAudioTr
|
||||
options.auto_gain_control = true;
|
||||
options.echo_cancellation = true;
|
||||
options.noise_suppression = true;
|
||||
auto audioSource = this->peerConnectionFactory->CreateAudioSource(options);
|
||||
return this->peerConnectionFactory->CreateAudioTrack("taoyao-audio", audioSource.get());
|
||||
this->audioTrackSource = this->peerConnectionFactory->CreateAudioSource(options);
|
||||
return this->peerConnectionFactory->CreateAudioTrack("taoyao-audio", audioTrackSource.get());
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<webrtc::VideoTrackInterface> acgist::MediaManager::getVideoTrack() {
|
||||
// webrtc::VideoTrackSourceInterface videoSource;
|
||||
// this->peerConnectionFactory->CreateVideoTrack("taoyao-video", videoSource);
|
||||
return nullptr;
|
||||
this->videoTrackSource = new rtc::RefCountedObject<acgist::TaoyaoVideoTrackSource>();
|
||||
return this->peerConnectionFactory->CreateVideoTrack("taoyao-video", this->videoTrackSource);
|
||||
}
|
||||
|
||||
@@ -1 +1,34 @@
|
||||
#include "../include/WebRTC.hpp"
|
||||
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/video_decoder.h"
|
||||
|
||||
acgist::TaoyaoVideoDecoder::TaoyaoVideoDecoder() {
|
||||
}
|
||||
|
||||
acgist::TaoyaoVideoDecoder::~TaoyaoVideoDecoder() {
|
||||
}
|
||||
|
||||
bool acgist::TaoyaoVideoDecoder::start() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool acgist::TaoyaoVideoDecoder::stop() {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t acgist::TaoyaoVideoDecoder::Release() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t acgist::TaoyaoVideoDecoder::RegisterDecodeCompleteCallback(webrtc::DecodedImageCallback* callback) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool acgist::TaoyaoVideoDecoder::Configure(const webrtc::VideoDecoder::Settings& settings) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t acgist::TaoyaoVideoDecoder::Decode(const webrtc::EncodedImage& input_image, bool missing_frames, int64_t render_time_ms) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -9,13 +9,16 @@
|
||||
#include <multimedia/player_framework/native_avcodec_base.h>
|
||||
#include <multimedia/player_framework/native_avcapability.h>
|
||||
|
||||
#include "api/video_codecs/video_encoder.h"
|
||||
#include "api/video_codecs/video_decoder.h"
|
||||
|
||||
// 编码回调
|
||||
static void OnError(OH_AVCodec* codec, int32_t errorCode, void* userData);
|
||||
static void OnStreamChanged(OH_AVCodec* codec, OH_AVFormat* format, void* userData);
|
||||
static void OnNeedInputBuffer(OH_AVCodec* codec, uint32_t index, OH_AVBuffer* buffer, void* userData);
|
||||
static void OnNewOutputBuffer(OH_AVCodec* codec, uint32_t index, OH_AVBuffer* buffer, void* userData);
|
||||
|
||||
acgist::VideoEncoder::VideoEncoder() {
|
||||
acgist::TaoyaoVideoEncoder::TaoyaoVideoEncoder() {
|
||||
OH_AVCapability* capability = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
|
||||
const char* codecName = OH_AVCapability_GetName(capability);
|
||||
this->avCodec = OH_VideoEncoder_CreateByName(codecName);
|
||||
@@ -29,7 +32,7 @@ acgist::VideoEncoder::VideoEncoder() {
|
||||
this->initFormatConfig(format);
|
||||
ret = OH_VideoEncoder_Configure(this->avCodec, format);
|
||||
OH_AVFormat_Destroy(format);
|
||||
OH_LOG_INFO(LOG_APP, "配置编码参数:%o %d %d %f %ld", ret, acgist::width, acgist::height, acgist::frameRate, acgist::bitrate);
|
||||
OH_LOG_INFO(LOG_APP, "配置编码参数:%o %d %d %f %lld", ret, acgist::width, acgist::height, acgist::frameRate, acgist::bitrate);
|
||||
// 准备就绪
|
||||
ret = OH_VideoEncoder_Prepare(this->avCodec);
|
||||
OH_LOG_INFO(LOG_APP, "视频编码准备就绪:%o", ret);
|
||||
@@ -38,7 +41,7 @@ acgist::VideoEncoder::VideoEncoder() {
|
||||
OH_LOG_INFO(LOG_APP, "配置视频窗口:%o", ret);
|
||||
}
|
||||
|
||||
acgist::VideoEncoder::~VideoEncoder() {
|
||||
acgist::TaoyaoVideoEncoder::~TaoyaoVideoEncoder() {
|
||||
if(this->avCodec != nullptr) {
|
||||
OH_AVErrCode ret = OH_VideoEncoder_Destroy(this->avCodec);
|
||||
this->avCodec = nullptr;
|
||||
@@ -51,7 +54,7 @@ acgist::VideoEncoder::~VideoEncoder() {
|
||||
}
|
||||
}
|
||||
|
||||
void acgist::VideoEncoder::initFormatConfig(OH_AVFormat* format) {
|
||||
void acgist::TaoyaoVideoEncoder::initFormatConfig(OH_AVFormat* format) {
|
||||
// https://docs.openharmony.cn/pages/v4.1/zh-cn/application-dev/media/avcodec/video-encoding.md
|
||||
// 配置视频宽度
|
||||
OH_AVFormat_SetIntValue(format, OH_MD_KEY_WIDTH, acgist::width);
|
||||
@@ -81,21 +84,21 @@ void acgist::VideoEncoder::initFormatConfig(OH_AVFormat* format) {
|
||||
OH_AVFormat_SetIntValue(format, OH_MD_KEY_QUALITY, 0);
|
||||
}
|
||||
|
||||
void acgist::VideoEncoder::restart() {
|
||||
void acgist::TaoyaoVideoEncoder::restart() {
|
||||
OH_AVErrCode ret = OH_VideoEncoder_Flush(this->avCodec);
|
||||
OH_LOG_INFO(LOG_APP, "清空编码队列:%o", ret);
|
||||
ret = OH_VideoEncoder_Start(this->avCodec);
|
||||
OH_LOG_INFO(LOG_APP, "开始视频编码:%o", ret);
|
||||
}
|
||||
|
||||
void acgist::VideoEncoder::reset(OH_AVFormat* format) {
|
||||
void acgist::TaoyaoVideoEncoder::reset(OH_AVFormat* format) {
|
||||
OH_AVErrCode ret = OH_VideoEncoder_Reset(this->avCodec);
|
||||
OH_LOG_INFO(LOG_APP, "重置视频编码:%o", ret);
|
||||
ret = OH_VideoEncoder_Configure(this->avCodec, format);
|
||||
OH_LOG_INFO(LOG_APP, "配置视频编码:%o", ret);
|
||||
}
|
||||
|
||||
void acgist::VideoEncoder::resetIntConfig(const char* key, int32_t value) {
|
||||
void acgist::TaoyaoVideoEncoder::resetIntConfig(const char* key, int32_t value) {
|
||||
OH_AVFormat* format = OH_AVFormat_Create();
|
||||
OH_AVFormat_SetIntValue(format, key, value);
|
||||
OH_AVErrCode ret = OH_VideoEncoder_SetParameter(this->avCodec, format);
|
||||
@@ -103,15 +106,15 @@ void acgist::VideoEncoder::resetIntConfig(const char* key, int32_t value) {
|
||||
OH_AVFormat_Destroy(format);
|
||||
}
|
||||
|
||||
void acgist::VideoEncoder::resetLongConfig(const char* key, int64_t value) {
|
||||
void acgist::TaoyaoVideoEncoder::resetLongConfig(const char* key, int64_t value) {
|
||||
OH_AVFormat* format = OH_AVFormat_Create();
|
||||
OH_AVFormat_SetLongValue(format, key, value);
|
||||
OH_AVErrCode ret = OH_VideoEncoder_SetParameter(this->avCodec, format);
|
||||
OH_LOG_INFO(LOG_APP, "动态配置视频编码:%o %s %ld", ret, key, value);
|
||||
OH_LOG_INFO(LOG_APP, "动态配置视频编码:%o %s %lld", ret, key, value);
|
||||
OH_AVFormat_Destroy(format);
|
||||
}
|
||||
|
||||
void acgist::VideoEncoder::resetDoubleConfig(const char* key, double value) {
|
||||
void acgist::TaoyaoVideoEncoder::resetDoubleConfig(const char* key, double value) {
|
||||
OH_AVFormat* format = OH_AVFormat_Create();
|
||||
OH_AVFormat_SetDoubleValue(format, key, value);
|
||||
OH_AVErrCode ret = OH_VideoEncoder_SetParameter(this->avCodec, format);
|
||||
@@ -119,13 +122,13 @@ void acgist::VideoEncoder::resetDoubleConfig(const char* key, double value) {
|
||||
OH_AVFormat_Destroy(format);
|
||||
}
|
||||
|
||||
bool acgist::VideoEncoder::start() {
|
||||
bool acgist::TaoyaoVideoEncoder::start() {
|
||||
OH_AVErrCode ret = OH_VideoEncoder_Start(this->avCodec);
|
||||
OH_LOG_INFO(LOG_APP, "开始视频编码:%o", ret);
|
||||
return ret == OH_AVErrCode::AV_ERR_OK;
|
||||
}
|
||||
|
||||
bool acgist::VideoEncoder::stop() {
|
||||
bool acgist::TaoyaoVideoEncoder::stop() {
|
||||
OH_AVErrCode ret = OH_VideoEncoder_NotifyEndOfStream(this->avCodec);
|
||||
OH_LOG_INFO(LOG_APP, "通知视频编码结束:%o", ret);
|
||||
ret = OH_VideoEncoder_Stop(this->avCodec);
|
||||
@@ -133,6 +136,27 @@ bool acgist::VideoEncoder::stop() {
|
||||
return ret == OH_AVErrCode::AV_ERR_OK;
|
||||
}
|
||||
|
||||
int32_t acgist::TaoyaoVideoEncoder::Release() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t acgist::TaoyaoVideoEncoder::RegisterEncodeCompleteCallback(webrtc::EncodedImageCallback* callback) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void acgist::TaoyaoVideoEncoder::SetRates(const webrtc::VideoEncoder::RateControlParameters& parameters) {
|
||||
}
|
||||
|
||||
webrtc::VideoEncoder::EncoderInfo acgist::TaoyaoVideoEncoder::GetEncoderInfo() const {
|
||||
webrtc::VideoEncoder::EncoderInfo info;
|
||||
// TODO
|
||||
return info;
|
||||
}
|
||||
|
||||
int32_t acgist::TaoyaoVideoEncoder::Encode(const webrtc::VideoFrame& frame, const std::vector<webrtc::VideoFrameType>* frame_types) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void OnError(OH_AVCodec* codec, int32_t errorCode, void* userData) {
|
||||
OH_LOG_WARN(LOG_APP, "视频编码发送错误:%d", errorCode);
|
||||
}
|
||||
|
||||
@@ -2,8 +2,50 @@
|
||||
|
||||
#include <hilog/log.h>
|
||||
|
||||
#include "media/base/codec.h"
|
||||
#include "api/video_codecs/sdp_video_format.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/codecs/vp9/include/vp9.h"
|
||||
#include "modules/video_coding/codecs/h264/include/h264.h"
|
||||
|
||||
//#include "api/audio_codecs/builtin_audio_decoder_factory.h"
|
||||
//#include "api/audio_codecs/builtin_audio_encoder_factory.h"
|
||||
|
||||
#include "api/video_codecs/builtin_video_decoder_factory.h"
|
||||
#include "api/video_codecs/builtin_video_encoder_factory.h"
|
||||
|
||||
static const std::string h264ProfileLevelId = "42e01f";
|
||||
|
||||
void acgist::TaoyaoAudioTrackSource::OnData(const void* audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels, size_t number_of_frames) {
|
||||
// TODO: 数据转发
|
||||
}
|
||||
|
||||
acgist::TaoyaoVideoTrackSource::TaoyaoVideoTrackSource() {
|
||||
}
|
||||
|
||||
acgist::TaoyaoVideoTrackSource::~TaoyaoVideoTrackSource() {
|
||||
}
|
||||
|
||||
webrtc::MediaSourceInterface::SourceState acgist::TaoyaoVideoTrackSource::state() const {
|
||||
return webrtc::MediaSourceInterface::SourceState::kLive;
|
||||
}
|
||||
|
||||
bool acgist::TaoyaoVideoTrackSource::remote() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool acgist::TaoyaoVideoTrackSource::is_screencast() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
absl::optional<bool> acgist::TaoyaoVideoTrackSource::needs_denoising() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void acgist::TaoyaoVideoTrackSource::OnData(const webrtc::VideoFrame& videoFrame) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
acgist::TaoyaoVideoEncoderFactory::TaoyaoVideoEncoderFactory() {
|
||||
}
|
||||
|
||||
@@ -30,26 +72,78 @@ std::vector<webrtc::SdpVideoFormat> acgist::TaoyaoVideoEncoderFactory::GetSuppor
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::VideoEncoder> acgist::TaoyaoVideoEncoderFactory::CreateVideoEncoder(const webrtc::SdpVideoFormat& format) {
|
||||
OH_LOG_DEBUG(LOG_APP, "返回WebRTC编码器:%o", format.name.data());
|
||||
OH_LOG_DEBUG(LOG_APP, "返回WebRTC编码器:%s", format.name.data());
|
||||
// 硬编
|
||||
|
||||
// TODO: 大小写
|
||||
if (std::strcmp(format.name.data(), "H264") == 0) {
|
||||
// return std::unique_ptr<webrtc::VideoEncoder>(new acgist::TaoyaoVideoEncoder());
|
||||
}
|
||||
// 软便
|
||||
if (cricket::CodecNamesEq(format.name, cricket::kVp8CodecName)) {
|
||||
return VP8Encoder::Create();
|
||||
// TODO: 大小写
|
||||
if (std::strcmp(format.name.data(), cricket::kVp8CodecName) == 0) {
|
||||
return webrtc::VP8Encoder::Create();
|
||||
}
|
||||
if (cricket::CodecNamesEq(format.name, cricket::kVp9CodecName)) {
|
||||
return VP9Encoder::Create(cricket::VideoCodec(format));
|
||||
if (std::strcmp(format.name.data(), cricket::kVp9CodecName) == 0) {
|
||||
// return webrtc::VP9Encoder::Create();
|
||||
return webrtc::VP9Encoder::Create(cricket::CreateVideoCodec(format));
|
||||
}
|
||||
if (cricket::CodecNamesEq(format.name, cricket::kH264CodecName)) {
|
||||
return H264Encoder::Create(cricket::VideoCodec(format));
|
||||
if (std::strcmp(format.name.data(), cricket::kH264CodecName) == 0) {
|
||||
// return webrtc::H264Encoder::Create();
|
||||
return webrtc::H264Encoder::Create(cricket::CreateVideoCodec(format));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
acgist::TaoyaoVideoDecoderFactory::TaoyaoVideoDecoderFactory() {
|
||||
}
|
||||
|
||||
acgist::TaoyaoVideoDecoderFactory::~TaoyaoVideoDecoderFactory() {
|
||||
}
|
||||
|
||||
std::vector<webrtc::SdpVideoFormat> acgist::TaoyaoVideoDecoderFactory::GetSupportedFormats() const {
|
||||
std::vector<webrtc::SdpVideoFormat> supported_codecs;
|
||||
std::map<std::string, std::string> params;
|
||||
params["profile-level-id"] = h264ProfileLevelId;
|
||||
params["packetization-mode"] = "1";
|
||||
params["level-asymmetry-allowed"] = "1";
|
||||
webrtc::SdpVideoFormat dst_format("H264", params);
|
||||
for (const webrtc::SdpVideoFormat& format : webrtc::SupportedH264Codecs()) {
|
||||
if (format == dst_format) {
|
||||
supported_codecs.push_back(format);
|
||||
break;
|
||||
}
|
||||
}
|
||||
supported_codecs.push_back(webrtc::SdpVideoFormat(cricket::kVp8CodecName));
|
||||
supported_codecs.push_back(webrtc::SdpVideoFormat(cricket::kVp9CodecName));
|
||||
supported_codecs.push_back(webrtc::SdpVideoFormat(cricket::kH264CodecName));
|
||||
return supported_codecs;
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::VideoDecoder> acgist::TaoyaoVideoDecoderFactory::CreateVideoDecoder(const webrtc::SdpVideoFormat& format) {
|
||||
OH_LOG_DEBUG(LOG_APP, "返回WebRTC解码器:%s", format.name.data());
|
||||
// 硬解
|
||||
// TODO: 大小写
|
||||
if (absl::EqualsIgnoreCase(format.name.data(), "H264") == 0) {
|
||||
// return std::unique_ptr<webrtc::VideoDecoder>(new acgist::TaoyaoVideoDecoder());
|
||||
}
|
||||
// 软解
|
||||
// TODO: 大小写
|
||||
if (absl::EqualsIgnoreCase(format.name.data(), cricket::kVp8CodecName) == 0) {
|
||||
return webrtc::VP8Decoder::Create();
|
||||
}
|
||||
if (absl::EqualsIgnoreCase(format.name.data(), cricket::kVp9CodecName) == 0) {
|
||||
return webrtc::VP9Decoder::Create();
|
||||
}
|
||||
if (absl::EqualsIgnoreCase(format.name.data(), cricket::kH264CodecName) == 0) {
|
||||
return webrtc::H264Decoder::Create();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::VideoEncoderFactory> webrtc::CreateBuiltinVideoEncoderFactory() {
|
||||
return std::unique_ptr(new acgist::TaoyaoVideoEncoderFactory());
|
||||
return std::unique_ptr<webrtc::VideoEncoderFactory>(new acgist::TaoyaoVideoEncoderFactory());
|
||||
}
|
||||
|
||||
std::unique_ptr<webrtc::VideoDecoderFactory> webrtc::CreateBuiltinVideoDecoderFactory() {
|
||||
return std::unique_ptr(new acgist::TaoyaoVideoDecoderFactory());
|
||||
return std::unique_ptr<webrtc::VideoDecoderFactory>(new acgist::TaoyaoVideoDecoderFactory());
|
||||
}
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
import { signal } from "../taoyao/TaoyaoSignal";
|
||||
|
||||
import { setting } from "../taoyao/Setting";
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Button("加载系统")
|
||||
.fontSize(20)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.onClick(() => {
|
||||
signal.init();
|
||||
});
|
||||
}
|
||||
.width("50%");
|
||||
Column() {
|
||||
Button("连接信令")
|
||||
.fontSize(20)
|
||||
@@ -23,7 +16,8 @@ struct Index {
|
||||
signal.connect();
|
||||
});
|
||||
}
|
||||
.width("50%");
|
||||
.width("100%")
|
||||
.height("20%");
|
||||
Column() {
|
||||
Button("断开信令")
|
||||
.fontSize(20)
|
||||
@@ -32,7 +26,18 @@ struct Index {
|
||||
signal.close();
|
||||
});
|
||||
}
|
||||
.width("50%");
|
||||
.width("100%")
|
||||
.height("20%");
|
||||
Column() {
|
||||
Button("加载系统")
|
||||
.fontSize(20)
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.onClick(() => {
|
||||
signal.init();
|
||||
});
|
||||
}
|
||||
.width("100%")
|
||||
.height("20%");
|
||||
Column() {
|
||||
Button("卸载系统")
|
||||
.fontSize(20)
|
||||
@@ -41,7 +46,19 @@ struct Index {
|
||||
signal.shutdown();
|
||||
});
|
||||
}
|
||||
.width("50%");
|
||||
.width("100%")
|
||||
.height("20%");
|
||||
Column() {
|
||||
Text(
|
||||
`
|
||||
CA证书:${getContext(this).resourceDir + setting.caPath}
|
||||
信令地址:${setting.signalAddress}
|
||||
`
|
||||
)
|
||||
.fontSize(20)
|
||||
}
|
||||
.width("100%")
|
||||
.height("20%");
|
||||
}
|
||||
.height("100%");
|
||||
}
|
||||
|
||||
@@ -22,11 +22,14 @@ class Signal {
|
||||
class Setting {
|
||||
|
||||
// 信令地址
|
||||
signalAddress: string = "wss://192.168.1.100:8888/websocket.signal";
|
||||
signalAddress: string = "wss://192.168.8.57:8888/websocket.signal";
|
||||
// signalAddress: string = "wss://192.168.1.100:8888/websocket.signal";
|
||||
// 信令版本
|
||||
version: string = "1.0.0";
|
||||
// 信令配置
|
||||
signal : Signal = new Signal();
|
||||
// CA证书
|
||||
caPath : string = getContext(this) + "/cacert.pem";
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -5,17 +5,13 @@
|
||||
*/
|
||||
|
||||
import hilog from "@ohos.hilog";
|
||||
import { BusinessError } from '@ohos.base';
|
||||
import webSocket from "@ohos.net.webSocket";
|
||||
|
||||
import { setting } from "./Setting";
|
||||
|
||||
import taoyaoModule from "libtaoyao.so";
|
||||
|
||||
interface BusinessError<T = void> extends Error {
|
||||
code : number;
|
||||
data?: T;
|
||||
}
|
||||
|
||||
class TaoyaoSignal {
|
||||
|
||||
// WebSocket信令连接
|
||||
@@ -40,7 +36,7 @@ class TaoyaoSignal {
|
||||
}
|
||||
|
||||
shutdown() {
|
||||
taoyaoModule.shutdown("{}");
|
||||
taoyaoModule.shutdown(JSON.stringify(setting.signal));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,36 +44,40 @@ class TaoyaoSignal {
|
||||
*/
|
||||
connect() {
|
||||
if(this.socket) {
|
||||
hilog.info(0x0000, "TaoyaoSignal", "信令以及连接关闭旧的连接:%s", setting.signalAddress);
|
||||
hilog.info(0x0000, "TaoyaoSignal", "信令已经连接关闭旧的连接:%{public}s", setting.signalAddress);
|
||||
this.socket.close();
|
||||
}
|
||||
this.connected = false;
|
||||
this.socket = webSocket.createWebSocket();
|
||||
this.socket.on("open", (err: BusinessError, value: Object) => {
|
||||
hilog.info(0x0000, "TaoyaoSignal", "打开信令:%s", setting.signalAddress, value, err);
|
||||
hilog.info(0x0000, "TaoyaoSignal", "打开信令:%{public}s %{public}s %{public}s", setting.signalAddress, JSON.stringify(value), JSON.stringify(err));
|
||||
this.register();
|
||||
this.connected = true;
|
||||
});
|
||||
this.socket.on("message", (err: BusinessError, value: string | ArrayBuffer) => {
|
||||
const message = value?.toString();
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "信令消息:%s", message, err);
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "信令消息:%{public}s %{public}s", message, JSON.stringify(err));
|
||||
try {
|
||||
this.onMessage(message);
|
||||
} catch (error) {
|
||||
hilog.error(0x0000, "TaoyaoSignal", "处理信令消息异常:%s", message, error);
|
||||
hilog.error(0x0000, "TaoyaoSignal", "处理信令消息异常:%{public}s %{public}s", message, JSON.stringify(error));
|
||||
}
|
||||
});
|
||||
this.socket.on("close", (err: BusinessError, value: Object) => {
|
||||
hilog.error(0x0000, "TaoyaoSignal", "关闭信令:%s", setting.signalAddress, value, err);
|
||||
hilog.error(0x0000, "TaoyaoSignal", "关闭信令:%{public}s %{public}s %{public}s", setting.signalAddress, JSON.stringify(value), JSON.stringify(err));
|
||||
this.reconnect();
|
||||
});
|
||||
this.socket.on("error", (err: BusinessError) => {
|
||||
hilog.error(0x0000, "TaoyaoSignal", "信令异常:%s", setting.signalAddress, err);
|
||||
hilog.error(0x0000, "TaoyaoSignal", "信令异常:%{public}s %{public}s", setting.signalAddress, JSON.stringify(err));
|
||||
this.reconnect();
|
||||
});
|
||||
hilog.info(0x0000, "TaoyaoSignal", "连接信令:%s", setting.signalAddress);
|
||||
this.socket.connect(setting.signalAddress, (err: BusinessError, value: boolean) => {
|
||||
hilog.info(0x0000, "TaoyaoSignal", "信令连接成功:%s", setting.signalAddress, value, err);
|
||||
// 配置CA证书
|
||||
const options: webSocket.WebSocketRequestOptions = {
|
||||
caPath: setting.caPath
|
||||
};
|
||||
hilog.info(0x0000, "TaoyaoSignal", "连接信令:%{public}s %{public}s", setting.signalAddress, setting.caPath);
|
||||
this.socket.connect(setting.signalAddress, options, (err: BusinessError, value: boolean) => {
|
||||
hilog.info(0x0000, "TaoyaoSignal", "信令连接:%{public}s %{public}s %{public}s", setting.signalAddress, JSON.stringify(value), JSON.stringify(err));
|
||||
});
|
||||
};
|
||||
|
||||
@@ -88,7 +88,7 @@ class TaoyaoSignal {
|
||||
if(this.closed) {
|
||||
// 已经关闭忽略重连
|
||||
} else {
|
||||
hilog.info(0x0000, "TaoyaoSignal", "重连信令连接:%s", setting.signalAddress);
|
||||
hilog.info(0x0000, "TaoyaoSignal", "重连信令连接:%{public}s", setting.signalAddress);
|
||||
setTimeout((): void => this.connect(), 5000);
|
||||
}
|
||||
}
|
||||
@@ -97,7 +97,7 @@ class TaoyaoSignal {
|
||||
* 关闭信令
|
||||
*/
|
||||
close() {
|
||||
hilog.info(0x0000, "TaoyaoSignal", "关闭信令:%s", setting.signalAddress);
|
||||
hilog.info(0x0000, "TaoyaoSignal", "关闭信令:%{public}s", setting.signalAddress);
|
||||
this.closed = true;
|
||||
this.connected = false;
|
||||
if(this.socket) {
|
||||
@@ -121,7 +121,7 @@ class TaoyaoSignal {
|
||||
const body = response.body as Record<string, Object>;
|
||||
const index = body.index as number;
|
||||
this.clientIndex = index;
|
||||
hilog.info(0x0000, "TaoyaoSignal", "信令注册成功:%d", index);
|
||||
hilog.info(0x0000, "TaoyaoSignal", "信令注册成功:%{public}d", index);
|
||||
this.heartbeat();
|
||||
}
|
||||
|
||||
@@ -176,11 +176,12 @@ class TaoyaoSignal {
|
||||
"header": header,
|
||||
"body" : body
|
||||
};
|
||||
const json = JSON.stringify(message);
|
||||
try {
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "发送消息:%o", message);
|
||||
this.socket?.send(JSON.stringify(message));
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "发送消息:%{public}s", json);
|
||||
this.socket?.send(json);
|
||||
} catch (error) {
|
||||
hilog.error(0x0000, "TaoyaoSignal", "发送消息异常:%o", message, error);
|
||||
hilog.error(0x0000, "TaoyaoSignal", "发送消息异常:%{public}s %{public}s", json, JSON.stringify(error));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,11 +219,12 @@ class TaoyaoSignal {
|
||||
return true;
|
||||
});
|
||||
// 发送消息
|
||||
const json = JSON.stringify(message);
|
||||
try {
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "发送请求:%o", message);
|
||||
this.socket?.send(JSON.stringify(message));
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "发送请求:%{public}s", json);
|
||||
this.socket?.send(json);
|
||||
} catch (error) {
|
||||
hilog.error(0x0000, "TaoyaoSignal", "发送消息异常:%o", message, error);
|
||||
hilog.error(0x0000, "TaoyaoSignal", "发送消息异常:%{public}s %{public}s", json, JSON.stringify(error));
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
@@ -239,7 +241,7 @@ class TaoyaoSignal {
|
||||
const id : number = header.id as number;
|
||||
const signal: string = header.signal as string;
|
||||
if (this.callbackMapping.has(id)) {
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "处理同步消息:%s", message);
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "处理同步消息:%{public}s", message);
|
||||
try {
|
||||
const callback = this.callbackMapping.get(id) as Function;
|
||||
if(callback(json)) {
|
||||
@@ -292,10 +294,10 @@ class TaoyaoSignal {
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
hilog.warn(0x0000, "TaoyaoSignal", "没有适配信令:%s", signal);
|
||||
hilog.warn(0x0000, "TaoyaoSignal", "没有适配信令:%{public}s", signal);
|
||||
break;
|
||||
}
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "处理异步消息:%d %s", ret, message);
|
||||
hilog.debug(0x0000, "TaoyaoSignal", "处理异步消息:%{public}d %{public}s", ret, message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -64,12 +64,6 @@
|
||||
"when": "always"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ohos.permission.MEDIA_LOCATION",
|
||||
"usedScene": {
|
||||
"when": "always"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDjzCCAnegAwIBAgIJAKPjuujtbFnoMA0GCSqGSIb3DQEBCwUAMF4xCzAJBgNV
|
||||
BAYTAmNuMQswCQYDVQQIDAJnZDELMAkGA1UEBwwCZ3oxDzANBgNVBAoMBmFjZ2lz
|
||||
dDEPMA0GA1UECwwGYWNnaXN0MRMwEQYDVQQDDAphY2dpc3QuY29tMB4XDTIzMDIy
|
||||
NzEzMzUyNloXDTMzMDIyNDEzMzUyNlowXjELMAkGA1UEBhMCY24xCzAJBgNVBAgM
|
||||
AmdkMQswCQYDVQQHDAJnejEPMA0GA1UECgwGYWNnaXN0MQ8wDQYDVQQLDAZhY2dp
|
||||
c3QxEzARBgNVBAMMCmFjZ2lzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQDbt9orZnoTtzbaI9+S8uqqvi8rqOzi+b3tRHOYE+JVQNxWf8vTvKJ5
|
||||
mDDrBqICVy2SCtwkxXgrjDcRQVKK1IiDqxQ4oY6DCZetx4gQhYk9ychYsPPKnRg8
|
||||
bQEG48DM1EhmxhozUv7kaiUMS0LNODfzLTH/C25Nhgt3laGCtcIWOQliO9AVOxam
|
||||
EasfYP01AfL2qahk1s5N7fK9poLpbR9BS8ZUYMxZ5xOIUcc5eithBgGvuHUv9nEY
|
||||
Dart6XPC4z3YE9liwrxYwcBxztdvCA2EWeh1k0wNcrT/eJG3cuGgzsPDjI/BORq1
|
||||
DWFKJOXrWmhmIlw+VaQ6PIiD4/aQ50xfAgMBAAGjUDBOMB0GA1UdDgQWBBR98tbO
|
||||
eDI9mBcuZ96keDld1w54OzAfBgNVHSMEGDAWgBR98tbOeDI9mBcuZ96keDld1w54
|
||||
OzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCavKK+pJCmWDqFNMoX
|
||||
YwdRPDJS7LoCFV7C8oTkX5myCKNOi11bzlyqP/EkelubtRgaNr+GZCyhwxPiJvRx
|
||||
ZrWsoWpOH8OEdADM9lU+UXR23Ufmo9jFFEL7jZ9u9OmOJWAM5xM1KqCBd5+KRvfE
|
||||
oEHXdayfy6l00F+rsgaMm6IKdZcthAxVVEKO60GfwavcuvIiHVVLxW21H8BMoqd6
|
||||
Erigq7wJRRH+qm7Q5fVpmo1L7E6T2cBvGcFHKuQFdoxDlH4N6tPRDuRSODKFE//O
|
||||
D1ViQY65nn35mawbz2AgUUPvWiBDYYomeKIiGl859PukeP1jwDZcECFtrhH4s1p+
|
||||
at2z
|
||||
-----END CERTIFICATE-----
|
||||
Reference in New Issue
Block a user