Runt
2025-04-12 eab7d2b372363da248e092adc5077fcfb532ab8e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
//
// Created by 倪路朋 on 9/20/24.
//
 
#include <string.h>
#include "audio_channel.h"
#include "macro.h"
#include "pusher/live_pusher.h"
#include "server_global.h"
 
AudioChannel::AudioChannel() {
}
 
AudioChannel::~AudioChannel() {
    DELETE(buffer);
    if(audioEncoder){
        faacEncClose(audioEncoder);
        audioEncoder = 0;
    }
}
 
void AudioChannel::initAudioEncoder(int sample_rate, int channels) {
    mChannels = channels;
    audioEncoder = faacEncOpen(static_cast<unsigned long>(sample_rate),static_cast<unsigned int>(channels),&inputSamples,&maxOutputBytes);
    //输出缓冲区
    buffer = new u_char[maxOutputBytes];
    if(!audioEncoder){
        LOGE("打开音频编码器失败");
        return;
    }
    //配置编码参数
    faacEncConfigurationPtr  config = faacEncGetCurrentConfiguration(audioEncoder);
    //mpeg4标准
    config->mpegVersion = MPEG4;
    //
    config->aacObjectType = LOW;
    //输入格式16位
    config->inputFormat = FAAC_INPUT_16BIT;
    //输出格式
    config->outputFormat = 0;
    int ret = faacEncSetConfiguration(audioEncoder,config);
    if(!ret){
        LOGE("音频编码器参数配置失败");
        return;
    }
}
 
void AudioChannel::encodeData(int8_t *data) {
    int byteLen = faacEncEncode(audioEncoder,reinterpret_cast<int32_t *>(data),inputSamples,buffer,maxOutputBytes);
    if(byteLen > 0){
        RTMPPacket *pPacket = allocPacket(byteLen, 0x01, buffer);
        audioCallback(pPacket);
    }
}
 
RTMPPacket *AudioChannel::getAudioSeqHeader() {
    u_char *buf;
    u_long len;
    faacEncGetDecoderSpecificInfo(audioEncoder, &buf, &len);
    return allocPacket(len,0x00,buf);
}
 
RTMPPacket *AudioChannel::allocPacket(int byteLen,char m_type,u_char *buffer) {
    RTMPPacket  *packet = new RTMPPacket ;
    int body_size = 2 + byteLen;
    RTMPPacket_Alloc(packet,body_size);
    packet->m_body[0] = 0xAF;//双声道
    if(mChannels == 1){
        packet->m_body[0] = 0xAE;//单声道
    }
    //音频数据
    packet->m_body[1] = m_type;
    memcpy(&packet->m_body[2],buffer,static_cast<size_t>(byteLen));
    packet->m_headerType  = RTMP_PACKET_SIZE_LARGE;
    packet->m_packetType = RTMP_PACKET_TYPE_AUDIO;
    packet->m_nBodySize = body_size;
    packet->m_nChannel  = 0x05;
    packet->m_nTimeStamp = -1;
    packet->m_hasAbsTimestamp = 0;
    return packet;
}
 
void AudioChannel::setAudioCallback(AudioChannel::AudioCallback audioCallback) {
    this->audioCallback = audioCallback;
}