首页 > 其他分享 >ffmpeg截取文件

ffmpeg截取文件

时间:2024-05-26 20:13:07浏览次数:20  
标签:文件 ffmpeg fCtx 截取 packet avformat ret av NULL

方法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

相关文章

  • ffmpeg里的时间计算和转换
    main.c#include"libavutil/log.h"#include"libavformat/avformat.h"#include"libavutil/avutil.h"#include"libavcodec/avcodec.h"intmain(intargc,char*argv[]){av_log_set_level(AV_LOG_DEBUG);if(argc......
  • (附nuclei yaml文件)H3C多款企业路由器actionpolicy_status信息泄露漏洞复现(管理员密码
    (附nucleiyaml文件)H3C多款企业路由器actionpolicy_status信息泄露漏洞复现(管理员密码泄露)声明本文仅用于技术交流,请勿用于非法用途由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。1、漏洞简介漏......
  • 宏景eHR-OutputCode存在任意文件读取漏洞
    漏洞描述宏景eHR是一种企业人力资源管理系统,该漏洞存在于'OutputCode'模块中,该模块未能正确验证用户输入的文件路径参数'path'。由于缺乏充分的输入校验和路径处理,攻击者可以通过构造恶意的'path'参数,读取服务器上的任意文件fofaapp="HJSOFT-HCM"POCGET/servlet/OutputCode?......
  • LVS精益价值管理系统DownLoad.aspx存在任意文件读取漏洞
    漏洞描述该漏洞允许攻击者通过构造特定的请求,读取服务器上的任意文件,从而可能导致敏感信息泄露。DownLoad.aspx页面接受一个文件路径作为参数,并直接将其传递给文件读取函数。这个函数没有经过严格的检查和过滤,攻击者可以通过构造恶意请求,包含相对路径或绝对路径,从而读取服务器上......
  • Oracle 删除用户、表空间、数据文件、用户下的所有表
    1、删除用户DROPUSERuser_namecascade;2、删除表空间、数据文件--查看表空间SELECT*FROMUser_Tablespaces;--删除DROPTABLESPACEtablespaces_nameINCLUDINGCONTENTSANDDATAFILES;DROPTABLESPACEtemp_tablespaces_nameINCLUDINGCONTENTSANDDATAFILES;-......
  • Windows10/Windows11打开文件提示安全警告解决办法
    有用的方法打开Internet选项,在安全选项卡中点击"自定义级别",在"其他"项中,将"加载应用程序和不安全文件(不安全)"设置为"启用(不安全)".此搜索结果来自网络,由于我的电脑的Internet选项中的"自定义级别按钮"是被置灰了,找了一天的办法都没取消置灰,所以本人未尝试本办法,但......
  • ffmpeg提取H264视频数据
    方法1:命令提取ffmpeg-iinput.mp4-an-vcodeccopyout.h264ffmpeg-iinput.mp4-an-vcodeccopy-bsf:h264_mp4toannexbout1.h264方法2:代码提取 main.c#include"libavutil/log.h"#include"libavformat/avformat.h"#include"libavut......
  • 关于spring中使用 Undertow 作为嵌入式服务器上传文件但是限制的代码不生效问题
    背景:在做毕业设计的时候发现了使用Undertow作为嵌入式服务器上传文件限制的代码不生效,只能上传1MB以内的图片,一旦上传超过1MB的图片就会报错。代码:spring:datasource:hikari:idle-timeout:600000#10minmax-lifetime:1800000#30minservlet......
  • C# 混淆加密大师1.1.0更新, 新增资源文件加密, 防虚拟机, 异步混淆等新功能
    C#混淆加密大师是一款强大的工具,专为保护C#开发的dll和exe文件而设计,适用于各种应用程序,包括Winform、WPF、Unity游戏以及控制台程序。它支持从.NetFramework2.0到.NetFramework4.x,以及.NETCore2.0直至最新的.NET8版本。C#混淆加密大师不仅提供代码加密混淆功能,还能对EXE文......
  • 几种常用的配置文件格式对比分析——ini、json、xml、toml、yaml
    配置文件用于存储软件程序的配置信息,以便程序能够根据这些信息进行自定义和调整。常用的配置文件格式包括INI、XML、JSON和YAML。下面对它们进行简单介绍,并分析各自的优缺点。1.INI文件格式简介:INI(Initialization)文件是一种简单的配置文件格式,通常由节(section)、键(key)和......