使用ffmpeg以编程方式创建电影

时间:2018-11-18 15:45:29

标签: c++ video ffmpeg

我想用ffmpeg编程制作电影。

这是我的代码:

QString fileName = "test.mov";
static char errorString[AV_ERROR_MAX_STRING_SIZE];

printf("Video encoding\n");

AVOutputFormat *outputFormat = av_guess_format(nullptr, fileName.toStdString().c_str(), nullptr);

if (outputFormat == nullptr) {
    qDebug() << "Could not find suitable format for" << fileName;
    return false;
}

enum AVCodecID codec_id = AV_CODEC_ID_MJPEG;

qDebug() << "Format Name:" << outputFormat->name;
qDebug() << "Format Video Codec:" << outputFormat->video_codec;
outputFormat->video_codec = codec_id;

/// allocate the output media context, formatContext
AVFormatContext *formatContext = avformat_alloc_context();
formatContext->oformat = outputFormat;

// find the mpeg1 video encoder
AVCodec *codec = avcodec_find_encoder(codec_id);

if (!codec) {
    qDebug() << "codec not found";
    return false;
}

qDebug() << "Codec name:" << codec->name;

AVStream *videoStream = avformat_new_stream(formatContext, codec);
// put sample parameters
videoStream->codecpar->bit_rate = 400000;
videoStream->codecpar->width = width;
videoStream->codecpar->height = height;
videoStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
videoStream->codecpar->format = AV_PIX_FMT_YUVJ422P;
videoStream->time_base.num = 1;
videoStream->time_base.den = 25;

AVCodecContext *codecContext = avcodec_alloc_context3(nullptr);
codecContext->codec_id = codec_id;
codecContext->codec_type = AVMEDIA_TYPE_VIDEO;
codecContext->width = width;
codecContext->height = height;
codecContext->time_base.num = 1;
codecContext->time_base.den = 25;
codecContext->pix_fmt = AV_PIX_FMT_YUVJ422P;

if (int error = avcodec_parameters_to_context(codecContext, videoStream->codecpar)) {
    qDebug() << "Error parameting the context:" << av_make_error_string(errorString, AV_ERROR_MAX_STRING_SIZE, error);
    return false;
}

// open it
if (int error = avcodec_open2(codecContext, codec, nullptr)) {
    qDebug() << "Could not open codec:" << av_make_error_string(errorString, AV_ERROR_MAX_STRING_SIZE, error);
    return false;
}

// alloc image and output buffer
AVFrame *frame = av_frame_alloc();
frame->format = codecContext->pix_fmt;
frame->width = codecContext->width;
frame->height = codecContext->height;

if (int error = av_image_alloc(frame->data, frame->linesize, frame->width, frame->height, static_cast<enum AVPixelFormat>(frame->format), 0)) {
    qDebug() << "Error allocating image data:" << av_make_error_string(errorString, AV_ERROR_MAX_STRING_SIZE, error);
    return false;
}

// Open the output file, if needed
if (!(outputFormat->flags & AVFMT_NOFILE)) {
    if (avio_open(&formatContext->pb, fileName.toStdString().c_str(), AVIO_FLAG_WRITE) < 0) {
        qDebug() << "Could not open" << fileName;
        return false;
    }
}

// some formats want stream headers to be separate
if (formatContext->oformat->flags & AVFMT_GLOBALHEADER) {
    codecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
}

if (int error = avformat_write_header(formatContext, nullptr)) {
    qDebug() << "error writing header:" << av_make_error_string(errorString, AV_ERROR_MAX_STRING_SIZE, error);
    return false;
}

不幸的是,当我执行它时,我得到以下输出:

Format Name: mov
Format Video Codec: 27
Codec name: mjpeg
[mov @ 0x1048c7000] Could not find tag for codec none in stream #0, codec not currently supported in container
error writing header: Invalid argument

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

ffmpeg具有一个可以在C ++中使用的C库。

这里是参考: https://ffmpeg.org/doxygen/trunk/api-example_8c-source.html