diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/bind.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/bind.cpp index 612a755..d4c22d4 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/bind.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/bind.cpp @@ -38,7 +38,15 @@ static std::map roomMap; * 支持的编解码 */ static void printSupportCodec() { - + // TODO:是否需要释放 + OH_AVCapability* opus = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_OPUS, false); + OH_LOG_INFO(LOG_APP, "是否支持OPUS:%o", OH_AVCapability_IsHardware(opus)); + OH_AVCapability* pcmu = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_AUDIO_G711MU, false); + OH_LOG_INFO(LOG_APP, "是否支持PCMU:%o", OH_AVCapability_IsHardware(pcmu)); + OH_AVCapability* h264 = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, false); + OH_LOG_INFO(LOG_APP, "是否支持H264:%o", OH_AVCapability_IsHardware(h264)); + OH_AVCapability* h265 = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_HEVC, false); + OH_LOG_INFO(LOG_APP, "是否支持H264:%o", OH_AVCapability_IsHardware(h265)); } /** diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/Capturer.hpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/Capturer.hpp index 3182b68..27d289e 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/Capturer.hpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/Capturer.hpp @@ -14,21 +14,73 @@ #ifndef taoyao_Capturer_HPP #define taoyao_Capturer_HPP +#include + #include "api/media_stream_track.h" +#include +#include + namespace acgist { +/** + * 采集器 + * + * @tparam Sink 输出管道 + */ +template class Capturer { +public: + std::map map; + +public: + Capturer(); + virtual ~Capturer(); + +public: + // 开始采集 + virtual bool start() = 0; + // 结束采集 + virtual bool stop() = 0; + +}; + +/** + * 音频采集器 + */ +class AudioCapturer: public Capturer { + +public: + // 音频流构造器 + OH_AudioStreamBuilder* builder = nullptr; + // 音频采集器 + OH_AudioCapturer* audioCapturer = nullptr; + + +public: + AudioCapturer(); + virtual ~AudioCapturer(); + public: virtual bool start(); virtual bool stop(); }; -class AudioCapturer {}; - -class VideoCapturer {}; +/** + * 视频采集器 + */ +class VideoCapturer: public Capturer> { + +public: + VideoCapturer(); + virtual ~VideoCapturer(); + +public: + virtual bool start(); + virtual bool stop(); +}; } diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/MediaManager.hpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/MediaManager.hpp index 01c92c8..3ccff9a 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/MediaManager.hpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/include/MediaManager.hpp @@ -13,11 +13,25 @@ #include #include -#include "pc/peer_connection.h" -#include "pc/peer_connection_factory.h" +#include "api/media_stream_interface.h" +#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 { + +}; + class MediaManager { public: MediaManager(); @@ -35,12 +49,22 @@ public: int newLocalClient(); // 释放本地终端 int releaseLocalClient(); - void startCapture(); - void startAudioCapture(); - void startVideoCapture(); - void stopCapture(); - void stopAudioCapture(); - void stopVideoCapture(); + // 开始采集 + bool startCapture(); + // 开始采集音频 + bool startAudioCapture(); + // 开始采集视频 + bool startVideoCapture(); + // 结束采集 + bool stopCapture(); + // 结束采集音频 + bool stopAudioCapture(); + // 结束采集视频 + bool stopVideoCapture(); + // 音频来源 + rtc::scoped_refptr getAudioTrack(); + // 视频来源 + rtc::scoped_refptr getVideoTrack(); }; } diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/AudioCapturer.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/AudioCapturer.cpp index e69de29..9ddc753 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/AudioCapturer.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/AudioCapturer.cpp @@ -0,0 +1,91 @@ +#include "../include/Capturer.hpp" + +#include + +#include "rtc_base/time_utils.h" + +#include +#include + +// 采样率 +static int32_t samplingRate = 48000; +// 声道数 +static int32_t channelCount = 2; +// 音频场景 +static OH_AudioStream_LatencyMode latencyMode = OH_AudioStream_LatencyMode::AUDIOSTREAM_LATENCY_MODE_NORMAL; +// 音频格式 +static OH_AudioStream_SampleFormat sampleFormat = OH_AudioStream_SampleFormat::AUDIOSTREAM_SAMPLE_S16LE; + +static int32_t OnReadData(OH_AudioCapturer* capturer, void* userData, void* buffer, int32_t length); +static int32_t OnError(OH_AudioCapturer* capturer, void* userData, OH_AudioStream_Result error); +static int32_t OnStreamEvent(OH_AudioCapturer* capturer, void* userData, OH_AudioStream_Event event); +static int32_t OnInterruptEvent(OH_AudioCapturer* capturer, void* userData, OH_AudioInterrupt_ForceType type, OH_AudioInterrupt_Hint hint); + +acgist::AudioCapturer::AudioCapturer() { + OH_AudioStream_Result ret = OH_AudioStreamBuilder_Create(&builder, AUDIOSTREAM_TYPE_RENDERER); + OH_LOG_INFO(LOG_APP, "构造音频采集:%o", ret); +} + +acgist::AudioCapturer::~AudioCapturer() { + OH_AudioStream_Result ret = OH_AudioStreamBuilder_Destroy(builder); + // TODO: 是否需要delete + builder = nullptr; + OH_LOG_INFO(LOG_APP, "释放音频采集:%o", ret); +} + +bool acgist::AudioCapturer::start() { + // 配置采集参数 + OH_AudioStreamBuilder_SetSamplingRate(builder, samplingRate); + OH_AudioStreamBuilder_SetChannelCount(builder, channelCount); + OH_AudioStreamBuilder_SetLatencyMode(builder, latencyMode); + OH_AudioStreamBuilder_SetSampleFormat(builder, sampleFormat); + OH_LOG_DEBUG(LOG_APP, "配置音频格式:%d %d %o %o", samplingRate, channelCount, latencyMode, sampleFormat); + // 设置回调函数 + OH_AudioCapturer_Callbacks callbacks; + callbacks.OH_AudioCapturer_OnReadData = OnReadData; + callbacks.OH_AudioCapturer_OnError = OnError; + callbacks.OH_AudioCapturer_OnStreamEvent = OnStreamEvent; + callbacks.OH_AudioCapturer_OnInterruptEvent = OnInterruptEvent; + OH_AudioStream_Result ret = OH_AudioStreamBuilder_SetCapturerCallback(builder, callbacks, this); + OH_LOG_DEBUG(LOG_APP, "设置回调函数:%o", ret); + // 构造音频采集器 + ret = OH_AudioStreamBuilder_GenerateCapturer(builder, &audioCapturer); + OH_LOG_DEBUG(LOG_APP, "构造音频采集器:%o", ret); + // 开始录制 + ret = OH_AudioCapturer_Start(audioCapturer); + OH_LOG_DEBUG(LOG_APP, "开始录制:%o", ret); +} + +bool acgist::AudioCapturer::stop() { + // 停止录制 + OH_AudioStream_Result ret = OH_AudioCapturer_Stop(audioCapturer); + OH_LOG_DEBUG(LOG_APP, "停止录制:%o", ret); + // 释放音频采集器 + ret = OH_AudioCapturer_Release(audioCapturer); + audioCapturer = nullptr; + OH_LOG_DEBUG(LOG_APP, "释放音频采集器:%o", ret); +} + +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, 16, samplingRate, channelCount, sizeof(buffer) / 2, timeMillis); + } +} + +static int32_t OnError(OH_AudioCapturer* capturer, void* userData, OH_AudioStream_Result error) { + OH_LOG_ERROR(LOG_APP, "音频采集发生异常:%o", error); +} + +static int32_t OnStreamEvent(OH_AudioCapturer* capturer, void* userData, OH_AudioStream_Event event) { + OH_LOG_DEBUG(LOG_APP, "音频采集事件:%o", event); +} + +static int32_t OnInterruptEvent(OH_AudioCapturer* capturer, void* userData, OH_AudioInterrupt_ForceType type, OH_AudioInterrupt_Hint hint) { + OH_LOG_DEBUG(LOG_APP, "音频采集打断:%o %o", type, hint); +} diff --git a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/MediaManager.cpp b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/MediaManager.cpp index 807350a..a73ba53 100644 --- a/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/MediaManager.cpp +++ b/taoyao-client-openharmony/taoyao/media/src/main/cpp/media/MediaManager.cpp @@ -54,3 +54,29 @@ bool acgist::MediaManager::initPeerConnectionFactory() { int acgist::MediaManager::newLocalClient() { this->localClientRef++; } + +bool acgist::MediaManager::startCapture() { + this->startAudioCapture(); + this->startVideoCapture(); +} + +bool acgist::MediaManager::startAudioCapture() { + + return true; +} + +rtc::scoped_refptr acgist::MediaManager::getAudioTrack() { + cricket::AudioOptions options; + options.highpass_filter = true; + 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()); +} + +rtc::scoped_refptr acgist::MediaManager::getVideoTrack() { +// webrtc::VideoTrackSourceInterface videoSource; +// this->peerConnectionFactory->CreateVideoTrack("taoyao-video", videoSource); + return nullptr; +}