利用FFmpeg完成 mp4格式转avi格式

2023-05-16

我们可以用ffmpeg来完成一些很有用的功能。这篇文章就来说说,怎样用ffmpeg来完成视频格式的转换。

首先在我们搭建好ffmpeg环境的基础上,如下链接所示

https://blog.csdn.net/laibowon/article/details/103746594

我们需要把输入的MP4视频文件转换为.avi格式的文件

主要是有两方面的问题:1.如何将输入文件传入给ffmpeg

2.如何调用ffmpeg进行格式转换

首先是第一个问题,在取得读写磁盘的权限以后,c++可以通过JNIEnv取得java层传递过来的绝对路径。

const char *in_filename;
in_filename =  env->GetStringUTFChars(str, &b);

通过传入两个地址,写入地址和写出地址,来告诉C层写入路径和输出路径分别是什么。

然后是第二步骤

需要引入的头文件有

jint _tmain(JNIEnv *env, int argc,jstring str,jstring output){

    const char* testfilepath =env->GetStringUTFChars(str,0);

    if(testfilepath == NULL){
        return -1;
    }
    env->ReleaseStringUTFChars(str, testfilepath);

    AVOutputFormat * ofmt = NULL;
    AVBitStreamFilterContext * vbsf = NULL;
    //定义输入、输出AVFormatContext
    AVFormatContext * ifmt_ctx = NULL, * ofmt_ctx = NULL;
    AVPacket pkt;
    const char *in_filename, *out_filename;
    int ret,i;
    int frame_index = 0;
    jboolean b=false;

    in_filename =  env->GetStringUTFChars(str, &b);
    //in_filename = "C:\\tst\\test.mp4";//input file URL
    int len = strlen(in_filename);

    out_filename = env->GetStringUTFChars(output, &b);
    av_register_all();
    //输入
    if((ret = avformat_open_input(&ifmt_ctx, in_filename,0,0)) < 0 )
    //打开媒体文件
    {
        char *buf;
        printf("Could not open input file.");
        goto end;
    }
    if((ret = avformat_find_stream_info(ifmt_ctx, 0 ))< 0 ){
        printf("Failed to go retrieve input stream information");
        goto end;
    }
    //MP4中使用的是H264编码,而H264编码有两种封装格式
    //一种是annexb模式,它是传统模式,有startcode,SPS和PPS在Element Stream中;
    //另一种是MP4模式,一般mp4、MKV、AVI都没有startcode,SPS和PPS以及其他信息被封装在容器中
    //每一帧前面都是这一帧的长度值,很多解码器只支持annexb模式,因此需要对MP4模式做转换
    //在ffmpeg中用h264_+mp4toannexb_fllter可以进行模式转换;使用-bsf h264_mp4toannexb就可以实现转换

    vbsf  = av_bitstream_filter_init("h264_mp4toannexb");
    av_dump_format(ifmt_ctx, 0, in_filename, 0);
    //初始化输出视频码流的AVFormatContext
    avformat_alloc_output_context2(&ofmt_ctx, NULL,NULL,out_filename);
    if (!ofmt_ctx) {
        printf("Could not create output contrxt\n");
        ret = AVERROR_UNKNOWN;
        goto end;
    }
    ofmt = ofmt_ctx -> oformat;

    for (int i = 0; i < ifmt_ctx->nb_streams; i++) {
        //通过输入的AVStream创建输出的AVStream
        AVStream *in_stream = ifmt_ctx->streams[i];
        AVStream *out_stream = avformat_new_stream(ofmt_ctx, in_stream->codec->codec);
        if (!out_stream) {
            printf("Failed allocating out stream\n");
            ret = AVERROR_UNKNOWN;
            goto end;
        }
        //复制AVCodecContext的设置属性
        if (avcodec_copy_context(out_stream->codec, in_stream->codec) < 0) {
            printf("Faield to copy context from input to output \n");
            goto end;
        }


        out_stream->codec->codec_tag = 0;
        if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
            out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }

    //输出信息
    av_dump_format(ofmt_ctx, 0, out_filename, 1);

    if (!(ofmt->flags & AVFMT_NOFILE)) {
        ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
        if (ret < 0) {
            printf("Could not open output file'%s'", out_filename);
            goto end;
        }
    }
    //写文件头
    if (avformat_write_header(ofmt_ctx, NULL) < 0) {
        printf("Error occureed when opening output file\n");
        goto end;
    }

    while (1) {
        AVStream *in_stream, *out_stream;
        //       得到一个AVPacket
        ret = av_read_frame(ifmt_ctx, &pkt);
        if (ret < 0) {
            break;
        }
        in_stream = ifmt_ctx->streams[pkt.stream_index];
        out_stream = ofmt_ctx->streams[pkt.stream_index];

        // 转换PTS/DTS
        pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base,
                                   (AVRounding) (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
        pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base,
                                   (AVRounding) (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
        pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
        pkt.pos = -1;

        if (pkt.stream_index == 0) {
            AVPacket fpkt = pkt;
            int a = av_bitstream_filter_filter(vbsf, out_stream->codec, NULL, &fpkt.data,
                                               &fpkt.size,
                                               pkt.data, pkt.size, pkt.flags & AV_PKT_FLAG_KEY
            );
            pkt.data = fpkt.data;
            pkt.size = fpkt.size;
        }

        //写Avpacket
        if (av_write_frame(ofmt_ctx, &pkt) < 0) {
            printf("Eroor mixing packet\n");
            break;
        }

        printf("Write %8d frames to output file\n", frame_index);
        av_packet_unref(&pkt);
        frame_index++;
    }

    av_write_trailer(ofmt_ctx);

    printf("succcess");
    end:
    avformat_close_input(&ifmt_ctx);
    if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE)) {
        avio_close(ofmt_ctx->pb);
    };

    avformat_free_context(ofmt_ctx);
    //clos out put

    printf("end");
    return 0;

}

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用FFmpeg完成 mp4格式转avi格式 的相关文章

  • pictureBox 图片处理异常

    我最近想尝试一下锻造网 http www aforgenet com framework 因为我发现它非常简单 所以我决定使用 Video FFMPEG 命名空间进行一些简单的视频播放 这样我就可以将每个帧直接放在 pictureBox 上
  • 如何使用ijkplayer库

    我要使用 ijkplayergithub链接 https github com bbcallen ijkplayer 我下载了这个 然后通过 文件 gt 导入 gt 常规 gt 现有项目到工作区 将其导入到 eclipse 中 之后我有三个
  • 为视频添加水印的命令

    我尝试在一个视频上添加水印 但 FFmpeg 命令不会执行 错误代码为 3037 我运行相同的代码来修剪视频 视频已成功修剪 因此没有问题inputpath or outputpath我也有ic watermark png在资产文件夹中 我
  • 如何使用ffmpeg从avi生成gif? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试使用以下命令将视频的一部分提取到动画 gif 中 ffmpeg i video avi t 5 out gif 它会生成一个 g
  • 合并来自 ffmpeg 的两个视频

    我想使用 ffmpeg 将两个 mp4 视频组合成一个 mp4 视频 到目前为止我尝试过的是 ffmpeg i input1 mp4 i input2 mp4 output mp4 但是 每次我获取带有第一个输入的视频编解码器的视频而不是另
  • 使用 ffmpeg 将 h.264 avi 容器转换为 mp4

    我想使用 ffmpeg 将 h 264 avi 容器转换为 mp4 容器 我发现这个有效 ffmpeg i myfile avi vcodec copy myfile mp4 ffmpeg version N 51169 gcedf276
  • Google Cloud Platform:将上传的 MP4 文件转换为 HLS 文件

    我正在构建一个平台 允许用户将一些视频文件 20 40 秒 从手机上传到服务器 所有这些上传目前都运行良好 文件通过nodejs云功能存储在谷歌存储桶中 现在我想创建一个 gcp 转码器作业 它将上传的 mp4 视频文件转换为 hls 视频
  • 如何使用 ffmpeg 提取时间精确的视频片段?

    这并不是一个特别新的问题领域 但我已经尝试过那里建议的内容 但运气不佳 那么 我的故事 我有一大段 15 秒的直接来自camera mov 视频 我想从中提取特定的块 我可以通过开始时间和停止时间 以秒为单位 来识别该块 我首先尝试执行我称
  • VLC 和 ffmpeg 如何协同工作?

    我从源代码编译了VLC 它运行良好 当我执行 Vlc 时 vlc 运行 我还从源代码编译了 ffmpeg 它也运行良好 当我执行 ffmpeg i f toto flv mp3 vn acodec copy new toto mp3 时 会
  • 无法在 Windows 7 机器中使用 OpenCV 2.4.3、Python 2.7 打开“.mp4”视频文件

    我目前正在进行一个涉及读取 mp4 视频文件的项目 我遇到的问题是它在Windows 7机器上使用Python 2 7 32位 OpenCV 2 4 3 cv2 pyd 代码片段如下 try video cv2 VideoCapture v
  • MP4 到 DASH(bash 脚本)

    我有一个网站 用户可以在其中上传视频文件 我想使用 DASH 流式传输所有内容以获得自适应比特率流式传输 因此 我编写了一个 bash 脚本 由 cron 运行 将所有 mp4 文件转换为 DASH 但它无法正常工作 出了什么问题 例如 使
  • 使用网络摄像头捕获视频并使用 C# 保存为 avi [重复]

    这个问题在这里已经有答案了 可能的重复 网络摄像头捕获并转换为 avi https stackoverflow com questions 2807040 webcam capture and convert to avi 有没有办法使用
  • H264 字节流到图像文件

    第一次来这里所以要温柔 我已经在给定的 H 264 字节流上工作了几个星期 一般注意事项 字节流不是来自文件 它是从外部源实时提供给我的 字节流使用 Android 的媒体编解码器进行编码 当将流写入扩展名为 H264的文件时 VLC能够正
  • Qt WinRT 应用程序无法访问文件权限被拒绝

    我需要使用 Qt 和 FFMPEG 开发 WinRT 应用程序 我根据指令构建了 WinRT 的 ffmpeghere https github com Microsoft FFmpegInterop我可以将库与我的项目链接起来 现在我需要
  • FFmpeg - 来自 NodeJS 的 RTMP 流,流比实时更快

    我的目标是在 Node 中渲染画布 并将该画布流式传输到 RTMP 服务器 最终是 Twitch 但现在我正在在本地 RTMP 服务器上测试 流式传输到 RTMP 的标准方式似乎是ffmpeg 所以我使用它 从 NodeJS 中作为子进程生
  • FFMPEG:使用具有复杂滤波器的视频滤波器

    我正在使用fluent ffmpeg用于对视频文件执行批量操作的 Node js 库 视频过滤器裁剪 16 9 输入 添加填充并将字幕刻录到填充中 在下一步中 我想使用复杂的滤镜来覆盖图像作为水印 ff input video mp4 ff
  • 为什么处理时间随着修剪位置的增加而增加?

    我最近一直在使用ffmpeg修剪一些视频 我注意到随着修剪位置的增加 修剪视频所花费的时间也会增加 即使持续时间相同 5 seconds 下面给出了修剪视频的命令0 to 5秒 处理仅需1秒 ffmpeg y i input mp4 fil
  • 如何将 MP3 音频文件读入 numpy 数组/将 numpy 数组保存到 MP3?

    有没有办法从 MP3 音频文件中读取 写入 MP3 音频文件numpy具有类似 API 的数组scipy io wavfile read https docs scipy org doc scipy 0 14 0 reference gen
  • iOS-如何使用 AVAsset 或 AVURLAsset 获取 .mp4 文件的持续时间

    我知道视频类型问题的持续时间之前已得到解答 但我在获取视频持续时间方面遇到了真正的麻烦 mp4文件通过使用AVAsset and by AVURLAsset 我正在使用以下代码 NSString itemPathString NSSearc
  • Xuggler 未转换 .webm 文件?

    我只是尝试使用 Xuggler 将 mov 文件转换为 webm 这应该可以工作 因为 FFMPEG 支持 webm 文件 这是我的代码 IMediaReader reader ToolFactory makeReader home use

随机推荐

  • 解决debian下thinkpad x1没有声音的问题

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 问题描述 一 解决方法 二 解决步骤 1 使用non free源 2 更改参数 3 更新源信息 4 安装以下驱动包 5 重启 问题描述 安装完debian 11后
  • windows环境变量配置你知道吗?

    1 什么是windows环境变量 xff1f 我们直接看百度的专业解释 环境变量 xff08 environment variables xff09 一般是指在操作系统中用来指定操作系统运行环境的一些参数 xff0c 如 xff1a 临时文
  • C# 远程RDP共享桌面,控制桌面,远程桌面登录注销,用户切换,包括客户端,服务端软件及代码

    可以一次打开16个桌面 可以支持登录切换用户 包含客户端NoteWin exe WINDOWS服务NoteWinService exe xff0c 当前用户服务NoteWService exe xff0c 远程启动服务AppLoad exe
  • 树莓派3B+ 网页控制GPIO(WebIOPi)

    树莓派3B 43 网页控制GPIO xff08 WebIOPi xff09 对于没接触编程的小白来说 xff0c 让他们编程控制树莓派的GPIO口输出输入 xff0c 那简直就是折磨人 xff0c WebOPi就是一个开源 方便 实用的网页
  • 解决Win10 自动更新问题(可以认为永久关闭更新)

    解决Win10 自动更新问题 xff08 可以认为永久关闭更新 xff09 这是我意外想到的一个方法 xff0c 步骤十分简单 xff0c 什么都不用设置 xff0c 不过每隔35天就要操作一下 xff0c 因为win10最多临时暂停35天
  • * failed to start daemon *解决方法

    16 11 23 error could not install smartsocket listener cannot bind to 127 0 0 1 5037 通常每个套接字地址 协议 网络地址 端口 只允许使用一次 10048 1
  • 【工具】验证是否安装cuda和cuDNN

    验证是否安装cuda 验证cuda是否安装方法1 span class token keyword import span torch span class token keyword print span span class token
  • 常用的url链接

    maven库 xff1a https mvnrepository com 一些基本工具的安装和语法 xff0c 如mysql docker https www runoob com docker centos docker install
  • 达梦7数据库后台导入导出命令解释

    达梦7使用的dexp和dimp xff0c 用法和exp和imp类似 xff0c 在命令后直接加上help可以查看帮助 吐槽一下竟然没有 dexp dimp help或 xff1f 这种操作 xff0c 必须是help才可以识别 格式 de
  • 麒麟V10修改root密码

    不知为何 xff0c root密码登录不上去 xff0c 几番测试都说是密码错误 基本环境 xff1a 国产服务器和麒麟V10 人不在机房 步骤如下 xff1a 1 连接服务器 xff0c 打开带外界面 2 打开控制台界面 3 重启电脑 x
  • python 图片文字提取

    转载 xff1a python怎么读取png python 图像处理 天道酬勤 花开半夏 图像处理不是一件简单的工作 对你来说 xff0c 一看到某样东西 xff0c 马上就知道你在看什么很容易 但是 xff0c 电脑不是这样工作的 对你来
  • C++ MFC调用JS代码获取返回值

    C 43 43 有时候会需要调用JS代码 xff0c 这对于C 43 43 来说或者对于国内来说一直是比较蛋疼的问题 xff0c 主要是资料少 xff0c 微软提供了一个COM组件 xff0c 里面包含有JS引擎 xff0c 这个组件就是
  • Python类基本概念 类对象、类属性、实例化、实例对象、实例属性、类方法、类构造函数、类继承

    想看视频的直接移步 python类对象类属性类的实例化实例对象实例属性 哔哩哔哩 bilibili python类方法类构造函数实例方法静态方法 哔哩哔哩 bilibili python类的继承代码实现 哔哩哔哩 bilibili 类对象
  • 用API获取IP地址

    设计蜂巢IP地址查询接口 xff1a http www hujuntao com api ip ip php腾讯IP地址查询接口 xff1a http fw qq com ipaddress新浪IP地址查询接口 xff1a http int
  • 打印出所有的水仙花数 Java实现

    题目 xff1a 打印出所有的水仙花数 所谓水仙花数是指一个三位数 xff0c 其各位数字立方和等于该数本身 例如 xff1a 153是一个 水仙花数 xff0c 因为153 61 1的三次方 xff0b 5的三次方 xff0b 3的三次方
  • iOS CGContext实现绘制任意圆角

    少说废话直接上代码 CGSize size 61 view bounds size UIGraphicsBeginImageContextWithOptions size NO UIScreen mainScreen scale CGCon
  • Kali Linux安装(VM环境下2022版本)

    目录 1 Kali虚拟机创建 2 Kali系统安装 1 Kali虚拟机创建 1 下载安装VM xff08 VMware Workstation xff09 软件 官网下载地址 xff1a 下载 VMware Workstation Pro
  • 为树莓派更换国内镜像源

    使用管理员权限 xff08 经由sudo xff09 xff0c 编辑 etc apt sources list文件 参考命令行为 xff1a span class token function sudo span span class t
  • LINK : fatal error LNK1104: cannot open file “kernel32.lib

    场景 xff1a 使用 VC6 0English 软件时 xff0c 提示 xff1a LINK fatal error LNK1104 cannot open file 34 kernel32 lib 解决方案 配置 Link 项的 In
  • 利用FFmpeg完成 mp4格式转avi格式

    我们可以用ffmpeg来完成一些很有用的功能 这篇文章就来说说 xff0c 怎样用ffmpeg来完成视频格式的转换 首先在我们搭建好ffmpeg环境的基础上 xff0c 如下链接所示 https blog csdn net laibowon