ffmpeg提取H264影片資料

NAVYSUMMER發表於2024-05-26

方法1:命令提取

ffmpeg -i input.mp4 -an -vcodec copy out.h264

ffmpeg -i input.mp4 -an -vcodec copy -bsf: h264_mp4toannexb out1.h264

  

方法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 = 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;
    }
    int videoIndex = av_find_best_stream(fCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
    if (videoIndex < 0) {
        av_log(NULL, AV_LOG_ERROR, "Find best stream failed: %d\n", videoIndex);
        avformat_close_input(&fCtx);
        return -1;
    }
    av_log(NULL, AV_LOG_INFO, "videoIndex=%d\n", videoIndex);
    FILE *dst = fopen(outputFile, "wb");
    if (dst == NULL) {
        av_log(NULL, AV_LOG_ERROR, "Open output file: %s failed\n", outputFile);
        avformat_close_input(&fCtx);
        return -1;
    }
    AVPacket *packet = av_packet_alloc();
    packet->data = NULL;
    packet->size = 0;
    while (av_read_frame(fCtx, packet) == 0) {
        if (packet->stream_index == videoIndex) {
            size_t size = fwrite(packet->data, sizeof(uint8_t), packet->size, dst);
            if (size != packet->size) {
                av_log(NULL, AV_LOG_ERROR, "Write size: %zu, packet size: %d\n", size, packet->size);
                fclose(dst);
                avformat_close_input(&fCtx);
                av_packet_unref(packet);
                return -1;
            }
        }
        av_packet_unref(packet);
    }

    if (fCtx != NULL) {
        avformat_close_input(&fCtx);
    }
    fclose(dst);

    return 0;
}

 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)

  

相關文章