ZBLOG

c++实现

以下是使用C++和FFmpeg库实现从MP4文件中截取指定时刻的一帧的示例代码:

#include <iostream>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}

int main() {
    av_register_all();

    AVFormatContext* formatContext = nullptr;
    if (avformat_open_input(&formatContext, "input.mp4", nullptr, nullptr) != 0) {
        std::cerr << "Could not open input file" << std::endl;
        return -1;
    }

    if (avformat_find_stream_info(formatContext, nullptr) < 0) {
        std::cerr << "Failed to retrieve input stream information" << std::endl;
        return -1;
    }

    int videoStreamIndex = -1;
    for (unsigned int i = 0; i < formatContext->nb_streams; ++i) {
        if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }

    if (videoStreamIndex == -1) {
        std::cerr << "Could not find video stream in the input file" << std::endl;
        return -1;
    }

    AVCodecParameters* codecParameters = formatContext->streams[videoStreamIndex]->codecpar;

    AVCodec* codec = avcodec_find_decoder(codecParameters->codec_id);
    if (!codec) {
        std::cerr << "Unsupported codec" << std::endl;
        return -1;
    }

    AVCodecContext* codecContext = avcodec_alloc_context3(codec);
    if (!codecContext) {
        std::cerr << "Failed to allocate codec context" << std::endl;
        return -1;
    }

    if (avcodec_parameters_to_context(codecContext, codecParameters) < 0) {
        std::cerr << "Failed to copy codec parameters to codec context" << std::endl;
        return -1;
    }

    if (avcodec_open2(codecContext, codec, nullptr) < 0) {
        std::cerr << "Failed to open codec" << std::endl;
        return -1;
    }

    AVPacket packet;
    av_init_packet(&packet);

    while (av_read_frame(formatContext, &packet) >= 0) {
        if (packet.stream_index == videoStreamIndex) {
            AVFrame* frame = av_frame_alloc();
            int response = avcodec_send_packet(codecContext, &packet);
            if (response < 0 && response != AVERROR(EAGAIN) && response != AVERROR_EOF)
                break;

            response = avcodec_receive_frame(codecContext, frame);
            if (response == 0) {
                // 截取指定时刻的一帧
                int64_t timestampToSeek = static_cast<int64_t>(10 * AV_TIME_BASE); // 单位:微秒,此处表示第10秒
                if (frame->pts >= timestampToSeek || frame->pkt_pts >= timestampToSeek)
                    break; // 已经截取到指定时刻的一帧

                av_frame_unref(frame);
            }
            av_frame_free(&frame);
        }
        av_packet_unref(&packet);
    }

    avformat_close_input(&formatContext);
    avformat_free_context(formatContext);

    return 0;
}

请注意,这只是一个简单示例代码,仅提供了基本的流程和关键步骤,你可能需要根据实际情况进行更详细的错误处理和资源释放。同时,请确保已经将FFmpeg库正确地链接到你的项目中,并设置正确的包含路径。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://sdn.0voice.com/?id=4833

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?