代码之家  ›  专栏  ›  技术社区  ›  Martin Delille

用ffmpeg编程创建电影

  •  -2
  • Martin Delille  · 技术社区  · 5 年前

    我想用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 回复  |  直到 5 年前
        1
  •  1
  •   Brandon    5 年前

    FFMPEG有一个C库,可以在C++中使用。

    以下是参考资料: https://ffmpeg.org/doxygen/trunk/api-example_8c-source.html