ffmpeg视频格式转换

方法1:命令转换

ffmpeg -i input.mp4 output.flv

方法2:代码转换

 main.c

#include "libavutil/log.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libavcodec/avcodec.h"


int main(int argc, char **argv) {
    av_log_set_level(AV_LOG_DEBUG);
    if (argc < 3) {
        av_log(NULL, AV_LOG_ERROR, "Usage: %s inputFile outputFile\n", argv[0]);
        return -1;
    }
    const char *inputFile = argv[1];
    const char *outputFile = argv[2];
    AVFormatContext *fCtx = NULL;
    int ret;
    ret = avformat_open_input(&fCtx, inputFile, NULL, NULL);
    if (ret != 0) {
        av_log(NULL, AV_LOG_ERROR, "Open input file %s failed: %s\n", inputFile, av_err2str(ret));
        return -1;
    }
    ret = avformat_find_stream_info(fCtx, NULL);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Find input file stream info failed: %s\n", av_err2str(ret));
        avformat_close_input(&fCtx);
        return -1;
    }
    AVFormatContext *outCtx = NULL;
    ret = avformat_alloc_output_context2(&outCtx, NULL, NULL, outputFile);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "avformat_alloc_output_context2 failed: %s\n", av_err2str(ret));
        avformat_close_input(&fCtx);
        avformat_free_context(outCtx);
        return -1;
    }
    unsigned int streamCount = fCtx->nb_streams;
    int *handleStreamIndexArray = av_mallocz_array(streamCount, sizeof(unsigned int));
    if (handleStreamIndexArray == NULL) {
        av_log(NULL, AV_LOG_ERROR, "av_mallocz_array failed: %s\n", av_err2str(ret));
        ret = -1;
        goto clean;
    }
    int streamIndex = 0;
    for (int i = 0; i < streamCount; i++) {
        AVStream *inStream = fCtx->streams[i];
        if (inStream->codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
            inStream->codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
            inStream->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
            handleStreamIndexArray[i] = -1;
            continue;
        } else {
            handleStreamIndexArray[i] = streamIndex++;
            AVStream *outStream = NULL;
            outStream = avformat_new_stream(outCtx, NULL);
            if (outStream == NULL) {
                av_log(NULL, AV_LOG_ERROR, "avformat_new_stream failed");
                ret = -1;
                goto clean;
            }
            avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
            outStream->codecpar->codec_tag = 0;
        }
    }
    if (!(outCtx->oformat->flags & AVFMT_NOFILE)) {
        ret = avio_open(&outCtx->pb, outputFile, AVIO_FLAG_WRITE);
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "avio_open failed: %s\n", av_err2str(ret));
            ret = -1;
            goto clean;
        }
    }

    ret = avformat_write_header(outCtx, NULL);
    if (ret != AVSTREAM_INIT_IN_WRITE_HEADER) {
        av_log(NULL, AV_LOG_ERROR, "avformat_write_header failed: %s\n", av_err2str(ret));
        ret = -1;
        goto clean;
    }

    AVPacket *packet = av_packet_alloc();
    while (av_read_frame(fCtx, packet) == 0) {
        if (packet->stream_index >= streamCount || handleStreamIndexArray[packet->stream_index] == -1) {
            av_packet_unref(packet);
            continue;
        }
        AVStream *inStream = fCtx->streams[packet->stream_index];
        AVStream *outStream = outCtx->streams[packet->stream_index];
        packet->stream_index = handleStreamIndexArray[packet->stream_index];
        packet->pts = av_rescale_q(packet->pts, inStream->time_base, outStream->time_base);
        packet->dts = av_rescale_q(packet->dts, inStream->time_base, outStream->time_base);
        packet->duration = av_rescale_q(packet->duration, inStream->time_base, outStream->time_base);
        packet->pos = -1;
        ret = av_interleaved_write_frame(outCtx, packet);
        if (ret != 0) {
            av_log(NULL, AV_LOG_ERROR, "av_interleaved_write_frame failed: %s\n", av_err2str(ret));
            ret = -1;
            goto clean;
        }
        av_packet_unref(packet);
    }
    ret = av_write_trailer(outCtx);
    if (ret != 0) {
        av_log(NULL, AV_LOG_ERROR, "av_write_trailer failed: %s\n", av_err2str(ret));
        ret = -1;
        goto clean;
    }
    ret = 0;
    clean:
    if (fCtx != NULL) {
        avformat_close_input(&fCtx);
    }
    if (outCtx != NULL) {
        avformat_free_context(outCtx);
    }

    return ret;
}

Makefile

TARGET=main
SRC=main.c
CC=gcc
CFLAGS=-I /usr/local/ffmpeg/include
LDFLAGS=-L /usr/local/ffmpeg/lib
LDFLAGS+= -lavutil -lavformat -lavcodec
all:$(TARGET)
$(TARGET):$(SRC)
    $(CC) $(SRC) $(CFLAGS) $(LDFLAGS) -o $(TARGET)
clean:
    rm -rf $(TARGET)

  

posted @ 2024-05-26 18:21  NAVYSUMMER  阅读(109)  评论(0)    收藏  举报
交流群 编程书籍