ffmpeg截取文件

方法1:命令截取

# 裁剪视频 -t支持数字和HH:MM:SS格式,数字格式是时长,从起始到指定时长,HH:MM:SS格式是结束时间,也可以通过 -ss 给出一个开始时间,-to 给出结束时间
ffmpeg -i input_video.mp4 -t 5 output_video.mp4
ffmpeg -i input_audio.wav -t 00:00:05 output_audio.wav

方法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 < 5) {
        av_log(NULL, AV_LOG_ERROR, "Usage: %s inputFile startTime endTime outputFile\n", argv[0]);
        return -1;
    }
    const char *inputFile = argv[1];
    int startTime = atoi(argv[2]);
    int endTime = atoi(argv[3]);
    const char *outputFile = argv[4];
    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;
    for (int i = 0; i < streamCount; i++) {
        AVStream *inStream = fCtx->streams[i];
        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;
        }
        ret = avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
        if (ret < 0) {
            goto clean;
        }
        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;
    }
    ret = av_seek_frame(fCtx, -1, startTime * AV_TIME_BASE, AVSEEK_FLAG_ANY);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "av_seek_frame failed: %s\n", av_err2str(ret));
        ret = -1;
        goto clean;
    }

    int64_t *startPts = av_mallocz_array(fCtx->nb_streams, sizeof(unsigned int));
    memset(startPts, 0, fCtx->nb_streams * sizeof(unsigned int));
    int64_t *startDts = av_mallocz_array(fCtx->nb_streams, sizeof(unsigned int));
    memset(startDts, 0, fCtx->nb_streams * sizeof(unsigned int));


    AVPacket *packet = av_packet_alloc();
    while (av_read_frame(fCtx, packet) == 0) {
        if (packet->stream_index >= streamCount) {
            av_packet_unref(packet);
            continue;
        }
        AVStream *inStream = fCtx->streams[packet->stream_index];
        AVStream *outStream = outCtx->streams[packet->stream_index];
        if (endTime < packet->pts * av_q2d(inStream->time_base)) {
            av_packet_unref(packet);
            break;
        }
        packet->pts = av_rescale_q(packet->pts - startPts[packet->stream_index], inStream->time_base,
                                   outStream->time_base);
        packet->dts = av_rescale_q(packet->dts - startDts[packet->stream_index], inStream->time_base,
                                   outStream->time_base);
        if (packet->pts < 0) {
            packet->pts = 0;
        }
        if (packet->dts < 0) {
            packet->dts = 0;
        }
        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 19:58  NAVYSUMMER  阅读(45)  评论(0)    收藏  举报
交流群 编程书籍