WebRTC学习之三:录音和播放

WebRTC学习之三:录音和播放_第1张图片

VoiceEngine中与录音和播放相关的头文件有五个,如下表所示:

头文件

包含的类

说明

voe_base.h

VoiceEngineObserver

VoiceEngine

VoEBase


1.默认使用G.711通过RTP进行全双工的VoIP会话
2.初始化和终止
3.通过文件和回调函数跟踪信息
4.多通道支持(比如混合,发送到多个目的端)
5.如果想支持G.711外的编码,需要VoECodec

voe_errors.h


一些VoiceEngine相关错误的定义

voe_file.h

VoEFile

1.音频播放

2.音频录制

3.音频转换

voe_hardware.h

VoEHardware

1.管理音频设备

2.获取设备信息

3.采样率设置

voe_volume_control.h

VoEVolumeControl

1.扬声器音量控制

2.麦克风音量控制

3.非线性语音电平控制

4.静音

5.音量放大

     
     
     
     
     
     
 
一.环境

WebRTC版本:2016.6.22,详见 WebRTC学习之二:编译

Qt版本:Qt5.7.0 VS2015

需要安装Microsoft DirectX SDK (June 2010),否则链接的时候会报:

LNK2019:无法解析的外部符号_MoInitMediaType@8,该符号在......

LNK2019:无法解析的外部符号_MoFreeMediaType@8,该符号在......

LNK2019:无法解析的外部符号_IID_IMediaBuffer

LNK2019:无法解析的外部符号_IID_IMediaObject

LNK2019:无法解析的外部符号_CLSID_CWMAudioAEC

如下图所示:


二.实现

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include "myobserver.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_errors.h"
#include "webrtc/voice_engine/include/voe_file.h"
#include "webrtc/voice_engine/include/voe_hardware.h"
#include "webrtc/voice_engine/include/voe_volume_control.h"
using namespace webrtc;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    void creatVoiceEngine();
    int initialVoiceEngine();
    int setDevice();
    void setChannel();
    int getMicrophoneVolumeValue();
    int getSpeakerVolumeValue();
    int unInitialVoiceEngine();

private:
    Ui::MainWindow *ui;

    MyObserver myObserver;
    int error;
    int audioChannel;

    VoiceEngine* ptrVoEngine;
    VoEBase* ptrVoEBase;
    VoEVolumeControl* ptrVoEVolumeControl;
    VoEFile* ptrVoEFile;
    VoEHardware* ptrVoEHardware;

private slots:
    void on_pushButtonRecording_clicked();
    void on_pushButtonPlayout_clicked();
    void slotSetMicrophoneVolumeValue(int value);
    void slotSetSpeakerVolumeValue(int value);
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    error(0),
    audioChannel(0),
    ptrVoEngine(NULL),
    ptrVoEBase(NULL),
    ptrVoEVolumeControl(NULL),
    ptrVoEFile(NULL),
    ptrVoEHardware(NULL)
{
    ui->setupUi(this);
    creatVoiceEngine();
    initialVoiceEngine();
    setDevice();
    setChannel();

    connect(ui->horizontalSliderMicrophoneVolume,SIGNAL(valueChanged(int)),this,SLOT(slotSetMicrophoneVolumeValue(int)));
    connect(ui->horizontalSliderSpeakerVolume,SIGNAL(valueChanged(int)),this,SLOT(slotSetSpeakerVolumeValue(int)));

    int vol=getMicrophoneVolumeValue();
    ui->horizontalSliderMicrophoneVolume->setValue(vol);
    ui->lineEditMicrophoneVolumeValue->setText(QString::number(vol));

    vol=getSpeakerVolumeValue();
    ui->horizontalSliderSpeakerVolume->setValue(vol);
    ui->lineEditSpeakerVolumeValue->setText(QString::number(vol));
}

MainWindow::~MainWindow()
{
    delete ui;
    unInitialVoiceEngine();
}

void MainWindow::creatVoiceEngine()
{
    ptrVoEngine = VoiceEngine::Create();
    ptrVoEBase = VoEBase::GetInterface(ptrVoEngine);
    ptrVoEVolumeControl = VoEVolumeControl::GetInterface(ptrVoEngine);
    ptrVoEFile = VoEFile::GetInterface(ptrVoEngine);
    ptrVoEHardware = VoEHardware::GetInterface(ptrVoEngine);
}

int MainWindow::initialVoiceEngine()
{
    error = ptrVoEBase->Init();
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEBase::Init";
        return error;
    }
    error = ptrVoEBase->RegisterVoiceEngineObserver(myObserver);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEBase:;RegisterVoiceEngineObserver";
        return error;
    }
    char temp[1024];
    error = ptrVoEBase->GetVersion(temp);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEBase::GetVersion";
        return error;
    }

    ui->lineEditVersion->setText(QString(temp));
    return 100;
}

int MainWindow::unInitialVoiceEngine()
{
    //Stop Playout
    error = ptrVoEBase->StopPlayout(audioChannel);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEBase::StopPlayout";
        return error;
    }
    error = ptrVoEFile->StopPlayingFileLocally(audioChannel);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEFile::StopPlayingFileLocally";
        return error;
    }
    //Stop Record
    error = ptrVoEFile->StopRecordingMicrophone();
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEFile::StopRecordingMicrophone";
        return error;
    }

    //Delete Channel
    error = ptrVoEBase->DeleteChannel(audioChannel);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEBase::DeleteChannel";
        return error;
    }
    //DeRegister observer
    ptrVoEBase->DeRegisterVoiceEngineObserver();
    error = ptrVoEBase->Terminate();
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEBase::Terminate";
        return error;
    }

    if(ptrVoEBase)
    {
        ptrVoEBase->Release();
    }

    if(ptrVoEVolumeControl)
    {
        ptrVoEVolumeControl->Release();
    }

    if(ptrVoEFile)
    {
        ptrVoEFile->Release();
    }

    if(ptrVoEHardware)
    {
        ptrVoEHardware->Release();
    }

    bool flag = VoiceEngine::Delete(ptrVoEngine);
    if (!flag)
    {
        qDebug()<<"ERROR in VoiceEngine::Delete";
        return -1;
    }
    return 100;
}

int MainWindow::setDevice()
{
    int rNum(-1), pNum(-1);
    error = ptrVoEHardware->GetNumOfRecordingDevices(rNum);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEHardware::GetNumOfRecordingDevices";
        return error;
    }
    error = ptrVoEHardware->GetNumOfPlayoutDevices(pNum);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEHardware::GetNumOfPlayoutDevices";
        return error;
    }

    char name[128] = { 0 };
    char guid[128] = { 0 };

    for (int j = 0; j < rNum; ++j)
    {
        error = ptrVoEHardware->GetRecordingDeviceName(j, name, guid);
        if (error != 0)
        {
            qDebug()<<"ERROR in VoEHardware::GetRecordingDeviceName";
            return error;
        }
        ui->comboBoxRecordingDevice->addItem(QString(name));
    }

    for (int j = 0; j < pNum; ++j)
    {
        error = ptrVoEHardware->GetPlayoutDeviceName(j, name, guid);
        if (error != 0)
        {
            qDebug()<<"ERROR in VoEHardware::GetPlayoutDeviceName";
            return error;
        }
        ui->comboBoxPlayoutDevice->addItem(QString(name));
    }

    error = ptrVoEHardware->SetRecordingDevice(ui->comboBoxRecordingDevice->currentIndex());
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEHardware::SetRecordingDevice";
        return error;
    }

    error = ptrVoEHardware->SetPlayoutDevice(ui->comboBoxPlayoutDevice->currentIndex());
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEHardware::SetPlayoutDevice";
        return error;
    }

    return 100;
}

void MainWindow::setChannel()
{
    audioChannel = ptrVoEBase->CreateChannel();
    if (audioChannel < 0)
    {
        qDebug()<<"ERROR in VoEBase::CreateChannel";
    }
    error = ptrVoEBase->StartPlayout(audioChannel);
    if(error != 0)
    {
        qDebug()<<"ERROR in VoEBase::StartPlayout";
    }
}

int MainWindow::getMicrophoneVolumeValue()
{
    unsigned int vol = 999;
    error = ptrVoEVolumeControl->GetMicVolume(vol);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEVolume::GetMicVolume";
        return 0;
    }
    if ((vol > 255) || (vol < 0))
    {
        qDebug()<<"ERROR in GetMicVolume";
        return 0;
    }
    return vol;
}

int MainWindow::getSpeakerVolumeValue()
{
    unsigned int vol = 999;
    error = ptrVoEVolumeControl->GetSpeakerVolume(vol);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEVolume::GetSpeakerVolume";
        return 0;
    }
    if ((vol > 255) || (vol < 0))
    {
        qDebug()<<"ERROR in GetSpeakerVolume";
        return 0;
    }
    return vol;
}

void MainWindow::on_pushButtonRecording_clicked()
{
    static bool flag=true;
    if(flag)
    {
        //录制麦克风的音频,默认采样率是8000HZ
        error = ptrVoEFile->StartRecordingMicrophone("RecordingMicrophone.pcm");
        if (error != 0)
        {
            qDebug()<<"ERROR in VoEFile::StartRecordingMicrophone";
        }
        else
        {
            ui->pushButtonRecording->setText(QStringLiteral("停止录音"));
        }
    }
    else
    {
        error = ptrVoEFile->StopRecordingMicrophone();
        if (error != 0)
        {
            qDebug()<<"ERROR in VoEFile::StopRecordingMicrophone";
        }
        else
        {
            ui->pushButtonRecording->setText(QStringLiteral("开始录音"));
        }
    }

    flag=!flag;
}

void MainWindow::on_pushButtonPlayout_clicked()
{
    static bool flag=true;
    if(flag)
    {
        error = ptrVoEFile->StartPlayingFileLocally(audioChannel,"RecordingMicrophone.pcm");
        if (error != 0)
        {
            qDebug()<<"ERROR in VoEFile::StartPlayingFileLocally";
        } 
        else
        {

             ui->pushButtonPlayout->setText(QStringLiteral("停止播放"));
        }
    }
    else
    {
        error = ptrVoEFile->StopPlayingFileLocally(audioChannel);
        if (error != 0)
        {
            qDebug()<<"ERROR in VoEFile::StopPlayingFileLocally";
        }
        else
        {
            ui->pushButtonPlayout->setText(QStringLiteral("开始播放"));
        }
    }

    flag=!flag;
}

void MainWindow::slotSetMicrophoneVolumeValue(int value)
{
    error = ptrVoEVolumeControl->SetMicVolume(value);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEVolume::SetMicVolume";
    }
    else
    {
        ui->lineEditMicrophoneVolumeValue->setText(QString::number(value));
    }
}
void MainWindow::slotSetSpeakerVolumeValue(int value)
{
    error = ptrVoEVolumeControl->SetSpeakerVolume(value);
    if (error != 0)
    {
        qDebug()<<"ERROR in VoEVolume::SetSpeakerVolume";
    }
    else
    {
        ui->lineEditSpeakerVolumeValue->setText(QString::number(value));
    }
}

三.效果

WebRTC学习之三:录音和播放_第2张图片

通过“录音音量”滑块可以实时调节录音的音量大小(0—255)。

通过“播放音量”滑块可以调节播放的音量大小(0—255),类似音乐播放器的音量调节,这里只是调节本软件的音量,而不是调节音频设备的音量。


源码链接:见http://blog.csdn.net/caoshangpa/article/details/53446916的评论



你可能感兴趣的:(WebRTC,WebRTC学习)