Для извлечения аудио из видео на C++ с использованием библиотеки FFmpeg, вот пример кода:
#include <iostream>
#include <fstream>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswresample/swresample.h>
}
struct WAVHeader {
uint8_t RIFF[4] = {'R','I','F','F'};
uint32_t chunkSize;
uint8_t WAVE[4] = {'W','A','V','E'};
uint8_t fmt[4] = {'f','m','t',' '};
uint32_t fmtSize = 16;
uint16_t audioFormat = 1; // PCM
uint16_t numChannels;
uint32_t sampleRate;
uint32_t byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
uint8_t data[4] = {'d','a','t','a'};
uint32_t dataSize;
};
int main() {
av_log_set_level(AV_LOG_ERROR);
const char* inputFile = "input.mp4";
const char* outputFile = "output.wav";
// Инициализация FFmpeg
AVFormatContext* formatContext = nullptr;
if (avformat_open_input(&formatContext, inputFile, nullptr, nullptr) != 0) {
std::cerr << "Ошибка открытия файла" << std::endl;
return -1;
}
if (avformat_find_stream_info(formatContext, nullptr) < 0) {
std::cerr << "Ошибка получения информации о потоке" << std::endl;
return -1;
}
// Поиск аудио потока
int audioStreamIndex = -1;
AVCodecParameters* codecParams = nullptr;
const AVCodec* codec = nullptr;
for (int i = 0; i < formatContext->nb_streams; i++) {
if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStreamIndex = i;
codecParams = formatContext->streams[i]->codecpar;
break;
}
}
if (audioStreamIndex == -1) {
std::cerr << "Аудио поток не найден" << std::endl;
return -1;
}
// Инициализация декодера
codec = avcodec_find_decoder(codecParams->codec_id);
if (!codec) {
std::cerr << "Декодер не найден" << std::endl;
return -1;
}
AVCodecContext* codecContext = avcodec_alloc_context3(codec);
avcodec_parameters_to_context(codecContext, codecParams);
if (avcodec_open2(codecContext, codec, nullptr) < 0) {
std::cerr << "Ошибка открытия декодера" << std::endl;
return -1;
}
// Настройка ресемплера
SwrContext* swr = swr_alloc_set_opts(nullptr,
AV_CH_LAYOUT_STEREO,
AV_SAMPLE_FMT_S16,
44100,
codecContext->channel_layout,
codecContext->sample_fmt,
codecContext->sample_rate,
0,
nullptr);
swr_init(swr);
// Подготовка WAV заголовка
WAVHeader wavHeader;
wavHeader.numChannels = 2;
wavHeader.sampleRate = 44100;
wavHeader.bitsPerSample = 16;
wavHeader.blockAlign = wavHeader.numChannels * wavHeader.bitsPerSample / 8;
wavHeader.byteRate = wavHeader.sampleRate * wavHeader.blockAlign;
std::ofstream outFile(outputFile, std::ios::binary);
outFile.write(reinterpret_cast<char*>(&wavHeader), sizeof(WAVHeader));
// Декодирование аудио
AVPacket* packet = av_packet_alloc();
AVFrame* frame = av_frame_alloc();
uint32_t dataSize = 0;
while (av_read_frame(formatContext, packet) >= 0) {
if (packet->stream_index == audioStreamIndex) {
avcodec_send_packet(codecContext, packet);
while (avcodec_receive_frame(codecContext, frame) == 0) {
// Ресемплинг аудио
uint8_t* outputBuffer;
av_samples_alloc(&outputBuffer, nullptr,
wavHeader.numChannels,
frame->nb_samples,
AV_SAMPLE_FMT_S16, 0);
int sampleCount = swr_convert(swr, &outputBuffer, frame->nb_samples,
(const uint8_t**)frame->data, frame->nb_samples);
// Запись аудио данных
int dataLength = sampleCount * wavHeader.blockAlign;
outFile.write(reinterpret_cast<char*>(outputBuffer), dataLength);
dataSize += dataLength;
av_freep(&outputBuffer);
}
}
av_packet_unref(packet);
}
// Обновление WAV заголовка
wavHeader.dataSize = dataSize;
wavHeader.chunkSize = dataSize + sizeof(WAVHeader) - 8;
outFile.seekp(0);
outFile.write(reinterpret_cast<char*>(&wavHeader), sizeof(WAVHeader));
outFile.close();
// Очистка ресурсов
av_frame_free(&frame);
av_packet_free(&packet);
avcodec_free_context(&codecContext);
avformat_close_input(&formatContext);
swr_free(&swr);
std::cout << "Аудио успешно извлечено!" << std::endl;
return 0;
}
Для компиляции и запуска:
- Установите FFmpeg (для Linux:
sudo apt-get install libavformat-dev libavcodec-dev libswresample-dev
) - Скомпилируйте с флагами:
g++ -o extract_audio extract.cpp -lavformat -lavcodec -lswresample -lavutil
- Запустите с входным видеофайлом:
./extract_audio
Особенности:
- Конвертирует аудио в стандартный WAV (16-bit, 44100 Hz, Stereo)
- Использует аппаратный ресемплинг FFmpeg
- Автоматически определяет аудио поток
- Генерирует корректный WAV заголовок
Ограничения:
- Работает только с поддерживаемыми FFmpeg кодеками
- Для сложных случаев может потребоваться дополнительная обработка ошибок
- Для MP3/других форматов потребуется изменение логики кодирования