CMakeLists.txt
cmake_minimum_required(VERSION 3.25)
project(test)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 14)
set(FFMPEG_DIR /usr/local/ffmpeg)
set(FFMPEG_INCLUDE_DIR ${FFMPEG_DIR}/include)
set(FFMPEG_LIBRARY_DIR ${FFMPEG_DIR}/lib)
include_directories(${FFMPEG_INCLUDE_DIR})
link_directories(${FFMPEG_LIBRARY_DIR})
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(
${PROJECT_NAME}
avcodec
avdevice
avfilter
avformat
avutil
)
main.cpp
#include <iostream>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}
using namespace std;
int main() {
const char *url = "/home/navy/Desktop/1.mp4";
AVFormatContext *formatContext = avformat_alloc_context();
if (avformat_open_input(&formatContext, url, nullptr, nullptr) != 0) {
// 打开文件失败,处理错误
return -1;
}
if (avformat_find_stream_info(formatContext, nullptr) < 0) {
// 读取流信息失败,处理错误
return -1;
}
av_dump_format(formatContext, 0, url, 0);
int videoStreamIndex = -1;
int audioStreamIndex = -1;
for (int i = 0; i < formatContext->nb_streams; i++) {
if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIndex = i;
} else if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStreamIndex = i;
}
}
if (videoStreamIndex == -1 || audioStreamIndex == -1) {
// 找不到视频流或音频流,处理错误
return -1;
}
AVCodecParameters *videoCodecParameters = formatContext->streams[videoStreamIndex]->codecpar;
AVCodecParameters *audioCodecParameters = formatContext->streams[audioStreamIndex]->codecpar;
const AVCodec *videoCodec = avcodec_find_decoder(videoCodecParameters->codec_id);
const AVCodec *audioCodec = avcodec_find_decoder(audioCodecParameters->codec_id);
if (videoCodec == nullptr || audioCodec == nullptr) {
// 找不到视频解码器或音频解码器,处理错误
return -1;
}
AVCodecContext *videoCodecContext = avcodec_alloc_context3(videoCodec);
AVCodecContext *audioCodecContext = avcodec_alloc_context3(audioCodec);
if (avcodec_parameters_to_context(videoCodecContext, videoCodecParameters) < 0
|| avcodec_parameters_to_context(audioCodecContext, audioCodecParameters) < 0) {
// 设置解码器上下文参数失败,处理错误
return -1;
}
if (avcodec_open2(videoCodecContext, videoCodec, nullptr) < 0
|| avcodec_open2(audioCodecContext, audioCodec, nullptr) < 0) {
// 打开解码器失败,处理错误
return -1;
}
AVPacket *packet = av_packet_alloc();
AVFrame *videoFrame = av_frame_alloc();
AVFrame *audioFrame = av_frame_alloc();
while (av_read_frame(formatContext, packet) >= 0) {
if (packet->stream_index == videoStreamIndex) {
// 视频帧
avcodec_send_packet(videoCodecContext, packet);
while (avcodec_receive_frame(videoCodecContext, videoFrame) == 0) {
// 处理视频帧
}
} else if (packet->stream_index == audioStreamIndex) {
// 音频帧
avcodec_send_packet(audioCodecContext, packet);
while (avcodec_receive_frame(audioCodecContext, audioFrame) == 0) {
// 处理音频帧
}
}
av_packet_unref(packet);
}
av_packet_free(&packet);
av_frame_free(&videoFrame);
av_frame_free(&audioFrame);
}