音视频开发——FFmpeg 实现MP4转FLV文件 C语言实现

文章目录

      • 转换步骤
      • 关键代码
      • 完整代码

转换步骤

  1. 初始化FFmpeg库
  2. 打开输入文件
  3. 找到输入文件的流信息
  4. 打开输出文件并设置输出格式
  5. 创建输出文件的流
  6. 初始化解码器和编码器
  7. 读取输入文件的帧并写入输出文件
  8. 释放资源

关键代码

1 初始化FFmpeg库

av_register_all();
  1. 打开输入文件

    if ((ret = avformat_open_input(&input_format_ctx, input_filename, NULL, NULL)) < 0) {fprintf(stderr, "Could not open input file '%s'\n", input_filename);return ret;
    }
    
  2. 找到输入文件的流信息

    if ((ret = avformat_find_stream_info(input_format_ctx, NULL)) < 0) {fprintf(stderr, "Failed to retrieve input stream information\n");return ret;
    }
    
  3. 打开输出文件并设置输出格式

    avformat_alloc_output_context2(&output_format_ctx, NULL, "flv", output_filename);
    if (!output_format_ctx) {fprintf(stderr, "Could not create output context\n");return AVERROR_UNKNOWN;
    }
    
  4. 创建输出文件的流

    for (int i = 0; i < input_format_ctx->nb_streams; i++) {AVStream *in_stream = input_format_ctx->streams[i];AVStream *out_stream = avformat_new_stream(output_format_ctx, NULL);if (!out_stream) {fprintf(stderr, "Failed to allocate output stream\n");return AVERROR_UNKNOWN;}// 复制输入流的编解码器参数到输出流if ((ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar)) < 0) {fprintf(stderr, "Failed to copy codec parameters\n");return ret;}out_stream->codecpar->codec_tag = 0;
    }
    
  5. 打开输出文件

    if (!(output_format_ctx->oformat->flags & AVFMT_NOFILE)) {if ((ret = avio_open(&output_format_ctx->pb, output_filename, AVIO_FLAG_WRITE)) < 0) {fprintf(stderr, "Could not open output file '%s'\n", output_filename);return ret;}
    }
    
  6. 写文件头

    if ((ret = avformat_write_header(output_format_ctx, NULL)) < 0) {fprintf(stderr, "Error occurred when opening output file\n");return ret;
    }
    
  7. 读取输入文件的帧并写入输出文件

while (1) {AVStream *in_stream, *out_stream;ret = av_read_frame(input_format_ctx, &packet);if (ret < 0)break;in_stream  = input_format_ctx->streams[packet.stream_index];out_stream = output_format_ctx->streams[packet.stream_index];log_packet(input_format_ctx, &packet, "in");packet.pts = av_rescale_q_rnd(packet.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);packet.dts = av_rescale_q_rnd(packet.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);packet.duration = av_rescale_q(packet.duration, in_stream->time_base, out_stream->time_base);packet.pos = -1;log_packet(output_format_ctx, &packet, "out");ret = av_interleaved_write_frame(output_format_ctx, &packet);if (ret < 0) {fprintf(stderr, "Error muxing packet\n");break;}av_packet_unref(&packet);
}
  1. 写文件尾

    av_write_trailer(output_format_ctx);
    
  2. 释放资源

    avformat_close_input(&input_format_ctx);if (output_format_ctx && !(output_format_ctx->oformat->flags & AVFMT_NOFILE))avio_closep(&output_format_ctx->pb);avformat_free_context(output_format_ctx);
    

通过以上步骤和代码,可以将MP4文件转换为FLV格式。

完整代码

#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavutil/imgutils.h>
#include <libavutil/timestamp.h>
#include <libswscale/swscale.h>void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, const char *tag)
{AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;printf("%s: pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",tag,av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),pkt->stream_index);
}int main(int argc, char *argv[])
{if (argc < 3) {printf("Usage: %s <input file> <output file>\n", argv[0]);return -1;}const char *input_filename = argv[1];const char *output_filename = argv[2];AVFormatContext *input_format_ctx = NULL, *output_format_ctx = NULL;AVPacket packet;int ret;av_register_all();// 打开输入文件if ((ret = avformat_open_input(&input_format_ctx, input_filename, NULL, NULL)) < 0) {fprintf(stderr, "Could not open input file '%s'\n", input_filename);return ret;}// 找到输入文件的流信息if ((ret = avformat_find_stream_info(input_format_ctx, NULL)) < 0) {fprintf(stderr, "Failed to retrieve input stream information\n");return ret;}// 打开输出文件并设置输出格式avformat_alloc_output_context2(&output_format_ctx, NULL, "flv", output_filename);if (!output_format_ctx) {fprintf(stderr, "Could not create output context\n");return AVERROR_UNKNOWN;}// 创建输出文件的流for (int i = 0; i < input_format_ctx->nb_streams; i++) {AVStream *in_stream = input_format_ctx->streams[i];AVStream *out_stream = avformat_new_stream(output_format_ctx, NULL);if (!out_stream) {fprintf(stderr, "Failed to allocate output stream\n");return AVERROR_UNKNOWN;}// 复制输入流的编解码器参数到输出流if ((ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar)) < 0) {fprintf(stderr, "Failed to copy codec parameters\n");return ret;}out_stream->codecpar->codec_tag = 0;}// 打开输出文件if (!(output_format_ctx->oformat->flags & AVFMT_NOFILE)) {if ((ret = avio_open(&output_format_ctx->pb, output_filename, AVIO_FLAG_WRITE)) < 0) {fprintf(stderr, "Could not open output file '%s'\n", output_filename);return ret;}}// 写文件头if ((ret = avformat_write_header(output_format_ctx, NULL)) < 0) {fprintf(stderr, "Error occurred when opening output file\n");return ret;}// 读取输入文件的帧并写入输出文件while (1) {AVStream *in_stream, *out_stream;// 获取一个packetret = av_read_frame(input_format_ctx, &packet);if (ret < 0)break;in_stream  = input_format_ctx->streams[packet.stream_index];out_stream = output_format_ctx->streams[packet.stream_index];// 记录packet的时间戳log_packet(input_format_ctx, &packet, "in");// 转换PTS/DTSpacket.pts = av_rescale_q_rnd(packet.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);packet.dts = av_rescale_q_rnd(packet.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);packet.duration = av_rescale_q(packet.duration, in_stream->time_base, out_stream->time_base);packet.pos = -1;// 记录packet的时间戳log_packet(output_format_ctx, &packet, "out");// 写packet到输出文件ret = av_interleaved_write_frame(output_format_ctx, &packet);if (ret < 0) {fprintf(stderr, "Error muxing packet\n");break;}av_packet_unref(&packet);}// 写文件尾av_write_trailer(output_format_ctx);// 释放资源avformat_close_input(&input_format_ctx);if (output_format_ctx && !(output_format_ctx->oformat->flags & AVFMT_NOFILE))avio_closep(&output_format_ctx->pb);avformat_free_context(output_format_ctx);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/870402.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt学生管理系统(付源码)

Qt学生管理系统 一、前言1.1 项目介绍1.2 项目目标 2、需求说明2.1 功能性说明2.2 非功能性说明 三、UX设计3.1 登录界面3.2 学生数据展示3.3 信息插入和更新 三、架构说明3.1 客户端结构如下3.2 数据流程图3.2.1 数据管理3.2.2 管理员登录 四、 设计说明3.1 数据库设计3.2 结构…

EdgeOne安全能力开箱测评挑战赛

活动地址&#xff1a;EdgeOne安全能力开箱测评挑战赛-腾讯云开发者社区-腾讯云 随着网络攻击日益频繁&#xff0c;企业网站面临着数据泄露、DDoS攻击、CC攻击等多种安全威胁。如何有效保护企业网站安全&#xff0c;成为企业IT部门的重要任务。腾讯云EdgeOne作为一款集成了CDN和…

智能家居开发新进展:乐鑫 ESP-ZeroCode 与亚马逊 ACK for Matter 实现集成

日前&#xff0c;乐鑫 ESP-ZeroCode 与亚马逊 Alexa Connect Kit (ACK) for Matter 实现了集成。这对智能家居设备制造商来说是一项重大进展。开发人员无需编写固件或开发移动应用程序&#xff0c;即可轻松设计符合 Matter 标准的产品。不仅如此&#xff0c;开发者还可以在短短…

算法模块导学

算法分析版本迭代流程图设计算法实践 练就扎实的基本功&#xff0c;可量化&#xff0c;可评估的&#xff0c;不是停留在大脑中的感觉。 1、算法&测开之缘 我们学习算法的目标是为了测试服务的&#xff0c;所以我们要了解测开最终要具备什么样的能力。 测开需要具备的能力…

从0开始的STM32HAL库学习4

对射式红外传感器计数复现 配置工程 我们直接复制oled的工程&#xff0c;但是要重命名。 将PB14设置为中断引脚 自定义命名为sensorcount 设置为上升沿触发 打开中断 配置NVCI 都为默认就可以了 修改代码 修改stm32f1xx_it.c 文件 找到中断函数并修改 void EXTI15_10_I…

Qt:14.容器类控件(QGroupBox、QTabWidget-创建选项卡式界面的控件)

目录 一、QGroupBox&#xff1a; 1.1QGroupBox介绍&#xff1a; 1.2 属性介绍&#xff1a; 二、QTabWidget-创建选项卡式界面的控件&#xff1a; 2.1 QTabWidget介绍&#xff1a; 2.2 属性介绍&#xff1a; 一、QGroupBox&#xff1a; 1.1QGroupBox介绍&#xff1a; QGro…

操作系统安全保护

操作系统安全概述 操作系统&#xff08;Operating System, OS&#xff09;是计算机系统的核心软件&#xff0c;管理硬件资源&#xff0c;提供基本服务&#xff0c;支持应用程序运行。操作系统安全是确保OS及其管理的资源免受未经授权访问、使用、修改和破坏的重要过程。操作系…

Python精神病算法和自我认知异类数学模型

&#x1f3af;要点 &#x1f3af;空间不确定性和动态相互作用自我认知异类模型 | &#x1f3af;精神病神经元算法推理 | &#x1f3af;集体信念催化个人行动力数学模型 | &#x1f3af;物种基因进化关系网络算法 | &#x1f3af;电路噪声低功耗容错解码算法 &#x1f4dc;和-…

【Java】零散知识--感觉每条都有知识在进入脑子唤起回忆

1&#xff0c;什么是双亲委派 AppClassLoader在加载类时&#xff0c;会向上委派&#xff0c;取查找缓存。 AppClassLoader >>ExtClassLoader >>BootStrapClassLoader 情况一 向上委派时查找到了&#xff0c;直接返回。 情况二 当委派到顶层之后&#xff0c;缓…

CSS特效:pointer-events: none;的一种特殊应用

一、需求描述 今天看到一个设计需求&#xff1a;需要在弹框中显示如下界面&#xff0c;其中有两个效果&#xff1a; 1.顶部点击项目&#xff0c;下面的内容能相应滚动定位&#xff0c;同时滚动的时候顶部项目也能相应激活显示 2.顶部右侧有一个模糊渐变效果&#xff0c;并且要…

从0到1搭建数据中台(1)

初识 数据仓库&#xff0c;数据湖&#xff0c;大数据平台&#xff0c;数据中台的发展历程梳理&#xff1b;数据中台的搭建方法论&#xff1b;数据中台搭建的初步落地&#xff0c;参考大神郭忆的课程&#xff0c;看完就会对全貌有个理解。 Easydata大数据生产力平台架构图。 有…

html页面实现socket.io

使用CDN&#xff1a;https://socket.io/zh-CN/docs/v4/client-installation/ socket.on 监听服务端的事件 socket.emit 是客户端的事件 <!DOCTYPE html> <html> <head><title>长时间任务</title><script src"https://cdnjs.cloudflare…

linux 文件末尾追加内容

1、echo echo "Hello, World!" >> example.txt 2、printf printf "Hello, World!\n" >> example.txt 3、cat 多行添加 cat >> example.txt <<EOF Line 1 Line 2 Line 3 EOF 4、sed sed -i ‘$a\要添加的文本’ example.txt 其中…

vue实例和容器的一夫一制——04

//准备容器 <div classapp> <h1>{{mag}}</h1> </div> //准备容器 <div classapp> <h1>{{mag}}</h1> </div> //准备容器 <div classapp2> <h1>{{name}}</h1> </div> <script> // 验…

【通信协议-RTCM】GPS卫星星历 ---- 对应RTCM十六进制 编码ID(3FB)

注释&#xff1a; RTCM响应消息1014-1017为网络辅助站数据消息的内容&#xff0c;应该不是很重要&#xff08;工作中也未接触到此些语句&#xff09;&#xff0c;故忽略 1. 1019型消息的内容&#xff0c;GPS卫星星历数据 2. 1008型消息的内容——天线描述符和序列号 DATA FI…

久期分析与久期模型

目录 一、久期分析的理论原理 二、数据准备 三、Stata 程序代码及解释 四、代码运行结果 一、久期分析的理论原理 久期&#xff08;Duration&#xff09;是衡量债券价格对利率变动敏感性的重要指标。它不仅仅是一个简单的时间概念&#xff0c;更是反映了债券现金流回收的平均…

Elasticsearch:Node.js ECS 日志记录 - Pino

在我的上一篇文章 “Beats&#xff1a;使用 Filebeat 从 Python 应用程序中提取日志” 里&#xff0c;我详述了如何使用 Python 来生成日志&#xff0c;并使用 Filebeat 来收集日志到 Elasticsearch 中。在今天的文章中&#xff0c;我来详细描述如何使用 Node.js 来生成 ECS 相…

SAP ABAP开发从入门到精通 年薪约30~40万

SAP ABAP开发从入门到精通培训课程 SAP ABAP&#xff08;Advanced Business Application Programming&#xff09;开发是SAP系统中重要的一环&#xff0c;它是一种用于SAP软件开发的编程语言。如果你正寻求从入门到精通SAP ABAP开发的方法&#xff0c;以下推荐的培训课程可能会…

龙迅#LT6711GXE适用于HDMI2.1转DP1.4/TPYE-C应用方案,分辨率高达8K30HZ,4K144HZ!

1. 描述 LT6711GXE 是带有 PD 控制器的 HD-DVI2.1 到 DP1.4a 转换器。 对于 HD-DVI2.1 输入&#xff0c;LT6711GXE可以配置为 3/4 通道。自适应均衡使其适用于长电缆应用&#xff0c;最大带宽高达 40Gbps。它支持最高分辨率的8K30Hz、4K144Hz或8K60Hz压缩数据&#xff08;直通&…