[*] 音频采集
This commit is contained in:
@@ -38,7 +38,15 @@ static std::map<std::string, acgist::Room*> roomMap;
|
|||||||
* 支持的编解码
|
* 支持的编解码
|
||||||
*/
|
*/
|
||||||
static void printSupportCodec() {
|
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
|
#ifndef taoyao_Capturer_HPP
|
||||||
#define taoyao_Capturer_HPP
|
#define taoyao_Capturer_HPP
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#include "api/media_stream_track.h"
|
#include "api/media_stream_track.h"
|
||||||
|
|
||||||
|
#include <ohaudio/native_audiocapturer.h>
|
||||||
|
#include <ohaudio/native_audiostreambuilder.h>
|
||||||
|
|
||||||
namespace acgist {
|
namespace acgist {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 采集器
|
||||||
|
*
|
||||||
|
* @tparam Sink 输出管道
|
||||||
|
*/
|
||||||
|
template <typename Sink>
|
||||||
class Capturer {
|
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:
|
public:
|
||||||
virtual bool start();
|
virtual bool start();
|
||||||
virtual bool stop();
|
virtual bool stop();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioCapturer {};
|
/**
|
||||||
|
* 视频采集器
|
||||||
class VideoCapturer {};
|
*/
|
||||||
|
class VideoCapturer: public Capturer<rtc::VideoSinkInterface<webrtc::RecordableEncodedFrame>> {
|
||||||
|
|
||||||
|
public:
|
||||||
|
VideoCapturer();
|
||||||
|
virtual ~VideoCapturer();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool start();
|
||||||
|
virtual bool stop();
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,25 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "pc/peer_connection.h"
|
#include "api/media_stream_interface.h"
|
||||||
#include "pc/peer_connection_factory.h"
|
#include "api/peer_connection_interface.h"
|
||||||
|
#include "api/video/video_sink_interface.h"
|
||||||
|
#include "api/video/video_source_interface.h"
|
||||||
|
|
||||||
namespace acgist {
|
namespace acgist {
|
||||||
|
|
||||||
|
class TaoyaoAudioSink : public webrtc::AudioTrackSinkInterface {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class TaoyaoVideoSource : public webrtc::VideoTrackSourceInterface {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class TaoyaoVideoSink : public rtc::VideoSinkInterface<webrtc::RecordableEncodedFrame> {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class MediaManager {
|
class MediaManager {
|
||||||
public:
|
public:
|
||||||
MediaManager();
|
MediaManager();
|
||||||
@@ -35,12 +49,22 @@ public:
|
|||||||
int newLocalClient();
|
int newLocalClient();
|
||||||
// 释放本地终端
|
// 释放本地终端
|
||||||
int releaseLocalClient();
|
int releaseLocalClient();
|
||||||
void startCapture();
|
// 开始采集
|
||||||
void startAudioCapture();
|
bool startCapture();
|
||||||
void startVideoCapture();
|
// 开始采集音频
|
||||||
void stopCapture();
|
bool startAudioCapture();
|
||||||
void stopAudioCapture();
|
// 开始采集视频
|
||||||
void stopVideoCapture();
|
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() {
|
int acgist::MediaManager::newLocalClient() {
|
||||||
this->localClientRef++;
|
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