环境
FFmpeg4.3 + vs2019
FFmpeg 相关api
avformat_open_input(); // 打开输入文件或者流
avformat_find_stream_info(); // 获取音视频流信息
av_find_best_stream(); // 获取指定流
av_read_frame(); // 读取数据包
av_packet_unref(); // 释放数据资源
avformat_close_input(); //关闭打开的文件或流,释放资源
实例
#include <iostream>
#include <string>
using namespace std;
#ifdef __cplusplus
extern "C"
{
#include <libavutil/log.h>
#include <libavformat/avformat.h>
}
#endif
#define ADTS_HEADER_LEN 7;
void adts_header(char* szAdtsHeader, int dataLen) {
int audio_object_type = 2;
int sampling_frequency_index = 7;
int channel_config = 2;
int adtsLen = dataLen + 7;
szAdtsHeader[0] = 0xff;
szAdtsHeader[1] = 0xf0;
szAdtsHeader[1] |= (0 << 3);
szAdtsHeader[1] |= (0 << 1);
szAdtsHeader[1] |= 1;
szAdtsHeader[2] = (audio_object_type - 1) << 6;
szAdtsHeader[2] |= (sampling_frequency_index & 0x0f) << 2;
szAdtsHeader[2] |= (0 << 1);
szAdtsHeader[2] |= (channel_config & 0x04) >> 2;
szAdtsHeader[3] = (channel_config & 0x03) << 6;
szAdtsHeader[3] |= (0 << 5);
szAdtsHeader[3] |= (0 << 4);
szAdtsHeader[3] |= (0 << 3);
szAdtsHeader[3] |= (0 << 2);
szAdtsHeader[3] |= ((adtsLen & 0x1800) >> 11);
szAdtsHeader[4] = (uint8_t)((adtsLen & 0x7f8) >> 3);
szAdtsHeader[5] = (uint8_t)((adtsLen & 0x7) << 5);
szAdtsHeader[5] |= 0x1f;
szAdtsHeader[6] = 0xfc;
}
void extractAudio()
{
av_log_set_level(AV_LOG_INFO);
string src = "./01.mp4";
string dst = "test.aac";
char errors[1024];
int audio_index;
FILE* dst_fd = nullptr;
errno_t err;
AVFormatContext* fmt_ctx = nullptr;
AVPacket pkt;
int ret = avformat_open_input(&fmt_ctx, src.c_str(), nullptr, nullptr);
if (ret < 0) {
av_log(nullptr, AV_LOG_ERROR, "Open failed!\n");
return;
}
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
av_strerror(ret, errors, 1024);
av_log(NULL, AV_LOG_DEBUG, "failed to find stream information: %s, %d(%s)\n",
src.c_str(),
ret,
errors);
return;
}
av_dump_format(fmt_ctx, 0, src.c_str(), 0);
err = fopen_s(&dst_fd,dst.c_str(), "wb");
if (err != 0) {
av_log(nullptr, AV_LOG_ERROR, "fopen failed!\n");
avformat_close_input(&fmt_ctx);
return;
}
audio_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, nullptr, 0);
if (ret < 0) {
av_log(nullptr, AV_LOG_ERROR, "Can not find best stream!\n");
fclose(dst_fd);
return;
}
av_init_packet(&pkt);
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
if (pkt.stream_index == audio_index && dst_fd != 0) {
char adts_header_buf[7];
adts_header(adts_header_buf, pkt.size);
size_t len = fwrite(adts_header_buf, 1, 7, dst_fd);
if (len != 7) {
av_log(nullptr, AV_LOG_WARNING, "fwrite header failed!\n");
}
len = fwrite(pkt.data, 1, pkt.size, dst_fd);
if (len != pkt.size) {
av_log(nullptr, AV_LOG_WARNING, "fwrite data failed!\n");
}
}
av_packet_unref(&pkt);
}
avformat_close_input(&fmt_ctx);
if (dst_fd) {
fclose(dst_fd);
}
}
int main()
{
extractAudio();
}