[*] 音频采集
This commit is contained in:
@@ -38,7 +38,15 @@ static std::map<std::string, acgist::Room*> 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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,21 +14,73 @@
|
||||
#ifndef taoyao_Capturer_HPP
|
||||
#define taoyao_Capturer_HPP
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "api/media_stream_track.h"
|
||||
|
||||
#include <ohaudio/native_audiocapturer.h>
|
||||
#include <ohaudio/native_audiostreambuilder.h>
|
||||
|
||||
namespace acgist {
|
||||
|
||||
/**
|
||||
* 采集器
|
||||
*
|
||||
* @tparam Sink 输出管道
|
||||
*/
|
||||
template <typename Sink>
|
||||
class Capturer {
|
||||
|
||||
public:
|
||||
std::map<std::string, Sink*> map;
|
||||
|
||||
public:
|
||||
Capturer();
|
||||
virtual ~Capturer();
|
||||
|
||||
public:
|
||||
// 开始采集
|
||||
virtual bool start() = 0;
|
||||
// 结束采集
|
||||
virtual bool stop() = 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 音频采集器
|
||||
*/
|
||||
class AudioCapturer: public Capturer<webrtc::AudioTrackSinkInterface> {
|
||||
|
||||
public:
|
||||
// 音频流构造器
|
||||
OH_AudioStreamBuilder* builder = nullptr;
|
||||
// 音频采集器
|
||||
OH_AudioCapturer* audioCapturer = nullptr;
|
||||
|
||||
|
||||
public:
|
||||
AudioCapturer();
|
||||
virtual ~AudioCapturer();
|
||||
|
||||
public:
|
||||
virtual bool start();
|
||||
virtual bool stop();
|
||||
|
||||
};
|
||||
|
||||
class AudioCapturer {};
|
||||
/**
|
||||
* 视频采集器
|
||||
*/
|
||||
class VideoCapturer: public Capturer<rtc::VideoSinkInterface<webrtc::RecordableEncodedFrame>> {
|
||||
|
||||
class VideoCapturer {};
|
||||
public:
|
||||
VideoCapturer();
|
||||
virtual ~VideoCapturer();
|
||||
|
||||
public:
|
||||
virtual bool start();
|
||||
virtual bool stop();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -13,11 +13,25 @@
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
|
||||
#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<webrtc::RecordableEncodedFrame> {
|
||||
|
||||
};
|
||||
|
||||
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<webrtc::AudioTrackInterface> getAudioTrack();
|
||||
// 视频来源
|
||||
rtc::scoped_refptr<webrtc::VideoTrackInterface> getVideoTrack();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
#include "../include/Capturer.hpp"
|
||||
|
||||
#include <hilog/log.h>
|
||||
|
||||
#include "rtc_base/time_utils.h"
|
||||
|
||||
#include <ohaudio/native_audiocapturer.h>
|
||||
#include <ohaudio/native_audiostreambuilder.h>
|
||||
|
||||
// 采样率
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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<webrtc::AudioTrackInterface> 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<webrtc::VideoTrackInterface> acgist::MediaManager::getVideoTrack() {
|
||||
// webrtc::VideoTrackSourceInterface videoSource;
|
||||
// this->peerConnectionFactory->CreateVideoTrack("taoyao-video", videoSource);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user