Воля PCM Аудио-сэмплы кодируются в AAC Формат , Нужно использовать Кодер FAAC , В предыдущем блоге 【Android RTMP】Кодирование сбора аудиоданных ( кодирование сбора аудиоданных | AAC Расширенное кодирование звука | FAAC кодер | Ubuntu кросс-компиляция FAAC кодер ) Завершена пара. FAAC Аудиокодеризкросс-компиляция , Результаты кросс-компиляции следующие: :
root@octopus:~/rtmp/faac-1.29.9.2/android# tree
.
└── armeabi-v7a
├── bin
│ └── faac
├── include
│ ├── faaccfg.h
│ └── faac.h
├── lib
│ ├── libfaac.a
│ └── libfaac.la
└── share
└── man
└── man1
└── faac.1
Воля
заголовочный файл faaccfg.h , faac.h скопировать в Android Studio в проекте src/main/cpp/include в каталоге , Воля libfaac.a Статическая библиотека скопировать в src/main/cpp/libs/armeabi-v7a в каталоге ;
Воляголовадокументс библиотекой функцийскопировать в Android Studio После проекта, Конфигурация CMakeList.txt Создать скрипт , Путь поиска для основного документа заголовка конфигурации и библиотек функций. , Пусть инструмент компиляции найдет соответствующий FAAC Заголовочные файлы библиотеки и статические библиотеки ;
1. Установите путь поиска заголовочного файла:
# Установить путь поиска файла заголовка
include_directories(include)
2. Установите путь поиска библиотеки функций:
# Установив опцию компилировать, Установите путь поиска для библиотек функций
# Вот ANDROID_ABI находится в
# build.gradle android->defaultConfig->externalNativeBuild->cmake
# вниз abiFilters Средние настройки
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}")
3. Завершите файл CMakeList.txt:
cmake_minimum_required(VERSION 3.4.1)
# Связь src/main/cpp/librtmp Оглавлениевниз Создать скрипт
add_subdirectory(librtmp)
add_library( # Имя библиотеки функций
native-lib
# Тип динамической библиотеки
SHARED
# источникдокумент native-lib.cpp
VedioChannel.cpp)
find_library( # Библиотека журналов
log-lib
log )
# Установить путь поиска файла заголовка
include_directories(include)
# Установив опцию компилировать, Установите путь поиска для библиотек функций
# Вот ANDROID_ABI находится в
# build.gradle android->defaultConfig->externalNativeBuild->cmake
# вниз abiFilters Средние настройки
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}")
target_link_libraries( # Динамическая библиотека связи
native-lib
# компилироватьиз rtmp статическая библиотека
rtmp
# найденный x264 статическая библиотека
x264
# найденный faac статическая библиотека
faac
${log-lib} )
1. Инициализируйте аудиозапись:
① Рассчитать минимальный размер буфера : получать 44100 стерео / мононуклеоз 16 Минимальный размер буфера для частоты дискретизации битов , Используйте минимальный размер буфера, Нет никакой гарантии, что звук будет ровным и ровным, Здесь размер буфера Воля увеличен вдвое, Обеспечьте бесперебойный сбор данных , В противном случае будет генерироваться ток
int minBufferSize = AudioRecord.getMinBufferSize(44100,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT) * 2;
② создавать AudioRecord объект : AudioRecord Конструктор необходимо передать источник звука , Частота выборки ,голосовой тракт Конфигурация, Количество бит выборки , Размер буфера выборки информация ;
AudioRecord mAudioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, // источник звука микрофон
44100, // PCM Аудио Частота выборки 44100 Hz
AudioFormat.CHANNEL_IN_STEREO, // стерео
AudioFormat.ENCODING_PCM_16BIT, // Количество бит выборки 16 Кусочек
minBufferSize); // Минимальное количество буферов выборки
③ Прототип конструктора AudioRecord:
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes)
① int audioSource параметр : источник звука, микрофон ;
② int sampleRateInHz параметр : Аудио Частота выборки, Обычно 44100 Hz, Должен Частота выборки лучше поддерживаются на всех устройствах ;
③ int channelConfig параметр : мононуклеоз AudioFormat.CHANNEL_IN_MONO / стерео AudioFormat.CHANNEL_IN_STEREO ;
④ int audioFormat параметр : Количество бит выборки, 8 Кусочек AudioFormat.ENCODING_PCM_8BIT / 16 , AudioFormat.ENCODING_PCM_16BIT ;
⑤ int bufferSizeInBytes параметр : Максимальный размер буфера для каждого сбора данных ;
2. Поток выборки аудио PCM:
① Независимая упаковка ниток : Сэмплирование звука требует непрерывной работы , И эта операция очень трудоемкая , Его необходимо упаковать в отдельный поток. ;
② Начать отбор проб : вызов AudioRecord объектиз startRecording метод , Начать сэмплирование звука ;
mAudioRecord.startRecording();
③ Чтение данных : Циклическое чтение данных выборки микрофона ,вызов AudioRecord объектиз read метод, Данные, которые можно выбрать ;
④ Остановить выборку : вызов AudioRecord объектиз stop метод ,Может Остановить выборку ;
mAudioRecord.stop();
⑤ Пример кода:
/**
* тема сэмплирования звука
*/
class AudioSampling implements Runnable{
@Override
public void run() {
// Начать запись семпла
mAudioRecord.startRecording();
while (isStartPush){
// Чтение записей в цикле, Необходимо передать серию параметров
//mAudioRecord.read( ... );
}
// Остановить запись сэмпла
mAudioRecord.stop();
}
}
package kim.hsl.rtmp;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Класс обработки аудио
* выборка звука, кодирование, Нажмите управление
*/
public class AudioChannel {
/**
* Прямая трансляция
*/
private LivePusher mLivePusher;
/**
* Аудио Записыватьобъект */
private AudioRecord mAudioRecord;
/**
* Стрим начался?
*/
private boolean isStartPush;
/**
* однопоточный пул потоков, выборка в этой теме звука
*/
private ExecutorService mExecutorService;
public AudioChannel(LivePusher mLivePusher) {
this.mLivePusher = mLivePusher;
// инициализацияпул потоков, Однопоточный пул потоков
mExecutorService = Executors.newSingleThreadExecutor();
/*
получать 44100 стерео / мононуклеоз 16 Минимальный размер буфера для частоты дискретизации битов
Используйте минимальный размер буфера, Нет никакой гарантии, что звук будет ровным и ровным, Здесь размер буфера Воля увеличен вдвое, Обеспечьте бесперебойный сбор данных
В противном случае будет генерироваться ток
*/
int minBufferSize = AudioRecord.getMinBufferSize(44100,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT) * 2;
/*
public AudioRecord(int audioSource, int sampleRateInHz,
int channelConfig, int audioFormat,
int bufferSizeInBytes)
int audioSource параметр : источник звука, микрофон
int sampleRateInHz параметр : Аудио Частота выборки, Обычно 44100 Hz, Должен Частота выборки лучше поддерживаются на всех устройствах
int channelConfig параметр : мононуклеоз AudioFormat.CHANNEL_IN_MONO / стерео AudioFormat.CHANNEL_IN_STEREO,
int audioFormat параметр : Количество бит выборки, 8 Кусочек AudioFormat.ENCODING_PCM_8BIT / 16 Кусочек AudioFormat.ENCODING_PCM_16BIT
int bufferSizeInBytes параметр : Максимальный размер буфера для каждого сбора данных
*/
mAudioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, // источник звука микрофон
44100, // PCM Аудио Частота выборки 44100 Hz
AudioFormat.CHANNEL_IN_STEREO, // стерео
AudioFormat.ENCODING_PCM_16BIT, // Количество бит выборки 16 Кусочек
minBufferSize); // Минимальное количество буферов выборки
}
/**
* Начать трансляцию
*/
public void startLive() {
isStartPush = true;
// Выполнять сэмплирования звука
// Если вы начинаете тему, Последующие потоки будут стоять в очереди и ждать.
mExecutorService.submit(new AudioSampling());
}
/**
* Хватит давить
*/
public void stopLive() {
isStartPush = false;
}
public void release(){
//Освободить объект Аудиозаписи
mAudioRecord.release();
}
/**
* тема сэмплирования звука
*/
class AudioSampling implements Runnable{
@Override
public void run() {
// Начать запись семпла
mAudioRecord.startRecording();
while (isStartPush){
// Чтение записей в цикле
mAudioRecord.read();
}
// Остановить запись сэмпла
mAudioRecord.stop();
}
}
}