ffmpeg视频处理

发布时间 2023-07-30 22:35:19作者: NAVYSUMMER

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);

}