方法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)
标签:文件,ffmpeg,fCtx,截取,packet,avformat,ret,av,NULL From: https://www.cnblogs.com/navysummer/p/18214215