FFMpeg rtmp 无压缩推送本地yuv文件 压缩推送本地yuv文件

可以借鉴的:C++使用FFmpeg实现YUV数据编码转视频文件_C 语言_脚本之家

yuv文件下载地址:YUV Sequences

无压缩的方式推送本地yuv文件 代码:

#include <stdio.h>
#include <unistd.h>
#include <iostream>
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
};
using namespace std;const char* input_file = "/mnt/hgfs/shareVM/BigBuckBunny_CIF_24fps.yuv";
const char* output_rtmp_url = "rtmp://10.10.18.94:1935/live/test";int main(int argc, char *argv[]) {AVFormatContext *pFormatCtx = nullptr;AVOutputFormat *fmt = nullptr;AVStream *video_st = nullptr;AVCodecContext *pCodecCtx = nullptr;AVCodec *pCodec = nullptr;uint8_t *picture_buf = nullptr;int size;//打开视频文件FILE *in_file = fopen(input_file, "rb");if (!in_file) {cout << "can not open file!" << endl;return -1;}//[1] --注册所有ffmpeg组件avcodec_register_all();av_register_all();//[2] --初始化AVFormatContext结构体,根据文件名获取到合适的封装格式avformat_alloc_output_context2(&pFormatCtx, NULL, "flv", output_rtmp_url);fmt = pFormatCtx->oformat;//[3] --打开文件if (avio_open(&pFormatCtx->pb, output_rtmp_url, AVIO_FLAG_READ_WRITE)) {cout << "output file open fail!";return -1;}//[3]//[4] --初始化视频码流video_st = avformat_new_stream(pFormatCtx, 0);if (video_st == NULL){printf("failed allocating output stram\n");return -1;}video_st->time_base.num = 1;video_st->time_base.den = 25;//[4]//[5] --编码器Context设置参数pCodecCtx = video_st->codec;pCodecCtx->codec_id = fmt->video_codec;pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;pCodecCtx->width = 352;pCodecCtx->height = 288;pCodecCtx->time_base = {1, 25};pCodecCtx->framerate = {25, 1};pCodecCtx->bit_rate = 400000;pCodecCtx->gop_size = 50;//[5]//[6] --寻找编码器并打开编码器pCodec = avcodec_find_encoder(AV_CODEC_ID_FLV1);if (!pCodec){cout << "no right encoder!" << endl;return -1;}if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){cout << "open encoder fail!" << endl;return -1;}//[6]//输出格式信息av_dump_format(pFormatCtx, 0, output_rtmp_url, 1);//初始化帧AVFrame *picture = av_frame_alloc();picture->width = pCodecCtx->width;picture->height = pCodecCtx->height;picture->format = pCodecCtx->pix_fmt;av_frame_get_buffer(picture, 32);size = avpicture_get_size(pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);picture_buf = (uint8_t*)av_malloc(size);avpicture_fill((AVPicture*)picture, picture_buf, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height);//[7] --写头文件avformat_write_header(pFormatCtx, NULL);//[7]//[8] --循环编码每一帧AVPacket pkt; //创建已编码帧int frame_count = 0;while (!feof(in_file)) {// 读取一帧 YUV 数据uint8_t yuv_buf[pCodecCtx->width * pCodecCtx->height * 3 / 2];size_t read_size = fread(yuv_buf, 1, pCodecCtx->width * pCodecCtx->height * 3 / 2, in_file);if (read_size <= 0) {break;}av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;// 将 YUV 数据编码为 H.264memcpy(picture->data[0], yuv_buf, pCodecCtx->width * pCodecCtx->height);memcpy(picture->data[1], yuv_buf + pCodecCtx->width * pCodecCtx->height, pCodecCtx->width * pCodecCtx->height / 4);memcpy(picture->data[2], yuv_buf + pCodecCtx->width * pCodecCtx->height * 5 / 4, pCodecCtx->width * pCodecCtx->height / 4);picture->pts = frame_count;int got_picture = 0;//编码int ret = avcodec_encode_video2(pCodecCtx, &pkt, picture, &got_picture);if (ret < 0){cout << "encoder fail!" << endl;return -1;}if (!got_picture){ret = 0;break;}cout << "encoder success! " <<picture->pts<< endl;// parpare packet for muxingpkt.stream_index = video_st->index;pkt.pts = frame_count * (pCodecCtx->time_base.den) / ((pCodecCtx->time_base.num) * 25);pkt.dts = pkt.pts;av_packet_rescale_ts(&pkt, pCodecCtx->time_base, video_st->time_base);pkt.pos = -1;ret = av_interleaved_write_frame(pFormatCtx, &pkt);if(ret < 0)break;av_free_packet(&pkt);frame_count++;usleep(30*1000);}//[8]//[9] --写文件尾av_write_trailer(pFormatCtx);//[9]//释放内存if (video_st){avcodec_close(video_st->codec);av_free(picture);av_free(picture_buf);}if (pFormatCtx){avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);}fclose(in_file);return 0;
}

压缩一半的方式推送本地yuv文件 代码:

#include <stdio.h>
#include <unistd.h>
#include <iostream>
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
};
using namespace std;const char* input_file = "/mnt/hgfs/shareVM/BigBuckBunny_CIF_24fps.yuv";
const char* output_rtmp_url = "rtmp://10.10.18.94:1935/live/test";
const int fps = 25;int main(int argc, char *argv[]) {AVFormatContext *pFormatCtx = nullptr;AVCodecContext *pCodecCtx = nullptr;//打开视频文件FILE *in_file = fopen(input_file, "rb");if (!in_file) {cout << "can not open file!" << endl;return -1;}//[1] --注册所有ffmpeg组件avcodec_register_all();av_register_all();//[2] --初始化AVFormatContext结构体,根据文件名获取到合适的封装格式avformat_alloc_output_context2(&pFormatCtx, NULL, "flv", output_rtmp_url);AVOutputFormat *fmt = pFormatCtx->oformat;//[3] --打开文件if (avio_open(&pFormatCtx->pb, output_rtmp_url, AVIO_FLAG_READ_WRITE)) {cout << "output file open fail!";return -1;}//[3]//[4] --初始化视频码流AVStream *video_st = avformat_new_stream(pFormatCtx, 0);if (video_st == NULL){printf("failed allocating output stram\n");avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);return -1;}video_st->time_base.num = 1;video_st->time_base.den = fps;//[4]struct SwsContext* swsContext = sws_getContext(352, 288, AV_PIX_FMT_YUV420P,352 / 2, 288 / 2, AV_PIX_FMT_YUV420P,SWS_BICUBIC, NULL, NULL, NULL);if(swsContext == NULL) {printf("failed sws_getContext\n");avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);return -1;}//[5] --编码器Context设置参数pCodecCtx = video_st->codec;pCodecCtx->codec_id = fmt->video_codec;pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;pCodecCtx->width = 352 / 2;pCodecCtx->height = 288 / 2;pCodecCtx->time_base = {1, fps};pCodecCtx->framerate = {fps, 1};pCodecCtx->bit_rate = 400000;pCodecCtx->gop_size = 50;//[5]//[6] --寻找编码器并打开编码器AVCodec *pCodec = avcodec_find_encoder(AV_CODEC_ID_FLV1);if (!pCodec){cout << "no right encoder!" << endl;return -1;}if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){cout << "open encoder fail!" << endl;avformat_free_context(pFormatCtx);return -1;}//[6]//输出格式信息av_dump_format(pFormatCtx, 0, output_rtmp_url, 1);//初始化帧AVFrame *originalFrame = av_frame_alloc();originalFrame->width = 352;originalFrame->height = 288;originalFrame->format = pCodecCtx->pix_fmt;av_frame_get_buffer(originalFrame, 32);int originalFrame_size = avpicture_get_size(pCodecCtx->pix_fmt, 352, 288);uint8_t* originalFrame_buf = (uint8_t*)av_malloc(originalFrame_size);avpicture_fill((AVPicture*)originalFrame, originalFrame_buf, pCodecCtx->pix_fmt, 352, 288);AVFrame *compressFrame = av_frame_alloc();compressFrame->width = pCodecCtx->width;compressFrame->height = pCodecCtx->height;compressFrame->format = pCodecCtx->pix_fmt;av_frame_get_buffer(compressFrame, 32);int compressFrame_size = avpicture_get_size((AVPixelFormat)compressFrame->format, compressFrame->width, compressFrame->height);uint8_t* compressFrame_buf = (uint8_t*)av_malloc(compressFrame_size);avpicture_fill((AVPicture*)compressFrame, compressFrame_buf, (AVPixelFormat)compressFrame->format, compressFrame->width, compressFrame->height);//[7] --写头文件avformat_write_header(pFormatCtx, NULL);//[7]   //[8] --循环编码每一帧AVPacket pkt; //创建已编码帧int frame_count = 0;while (!feof(in_file)) {// 读取一帧 YUV 数据uint8_t yuv_buf[352 * 288 * 3 / 2];size_t read_size = fread(yuv_buf, 1, 352 * 288 * 3 / 2, in_file);if (read_size <= 0) {break;}av_init_packet(&pkt);pkt.data = NULL;pkt.size = 0;// 将 YUV 数据编码为 H.264memcpy(originalFrame->data[0], yuv_buf, 352 * 288);memcpy(originalFrame->data[1], yuv_buf + 352 * 288, 352 * 288 / 4);memcpy(originalFrame->data[2], yuv_buf + 352 * 288 * 5 / 4, 352 * 288 / 4);originalFrame->pts = compressFrame->pts = frame_count;int got_picture = 0;sws_scale(swsContext, (const uint8_t* const*)originalFrame->data, originalFrame->linesize, 0,288, compressFrame->data, compressFrame->linesize);//编码int ret = avcodec_encode_video2(pCodecCtx, &pkt, compressFrame, &got_picture);if (ret < 0){cout << "encoder fail!" << endl;return -1;}if (got_picture){cout << "encoder success! " <<compressFrame->pts<< endl;// parpare packet for muxingpkt.stream_index = video_st->index;pkt.pts = frame_count * (pCodecCtx->time_base.den) / ((pCodecCtx->time_base.num) * fps);pkt.dts = pkt.pts;av_packet_rescale_ts(&pkt, pCodecCtx->time_base, video_st->time_base);pkt.pos = -1;ret = av_interleaved_write_frame(pFormatCtx, &pkt);if(ret < 0)break;}av_free_packet(&pkt);frame_count++;usleep(30 * 1000);}//[8]//[9] --写文件尾av_write_trailer(pFormatCtx);//[9]//释放内存if (video_st){avcodec_close(video_st->codec);av_free(originalFrame);av_free(originalFrame_buf);av_free(compressFrame);av_free(compressFrame_buf);}if (pFormatCtx){avio_close(pFormatCtx->pb);avformat_free_context(pFormatCtx);}fclose(in_file);return 0;
}

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

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

相关文章

【代码随想录02】977.有序数组的平方 209.长度最小的子数组 59.螺旋矩阵II

977. 有序数组的平方 题目描述 给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 做题思路 由于原数组存在负数&#xff0c;所以平方后最大值可能出现在两端。因此可以采用双指针法&#xf…

身边有填报志愿需求别错过!张雪峰透露今年志愿填报技巧:报专业,别报行业!(文末附稳定高薪专业推荐)

高考填报志愿是每个考生和家长都要面对的重大抉择。在当前就业形势日趋严峻、部分行业发展前景不明朗的大背景下,考生在填报志愿时更需要全面了解各个专业的就业前景,理性权衡自身兴趣特长与社会需求&#xff0c;而不是盲目跟风报考所谓的"热门专业"。 今天跟大家分…

期权开户零门槛怎么操作?期权不满50w的开户方式

今天带你了解期权开户零门槛怎么操作&#xff1f;期权不满50w的开户方式。在股票期权市场上&#xff0c;期权交易是一种非常受欢迎的投资方式。它不仅可以增加投资组合的多样性&#xff0c;还可以为投资者提供一定的保护和利润机会&#xff0c;比如通过买入认股期权做空对冲大盘…

如何选择视频号矩阵系统:打造高效短视频内容生态的指南

在短视频内容创作和分发的热潮中&#xff0c;视频号矩阵系统作为一种高效的管理工具&#xff0c;受到了越来越多创作者和品牌的青睐。它通过集中管理多个视频号&#xff0c;优化内容发布流程&#xff0c;帮助用户提升工作效率和内容影响力。本文将探讨如何选择一个合适的视频号…

振弦采集仪的工程安全监测实践与案例分析

振弦采集仪的工程安全监测实践与案例分析 振弦采集仪是一种常用的工程安全监测仪器&#xff0c;通过测量被监测结构的振动频率与振型&#xff0c;可以实时监测结构的安全状况。本文将结合实践经验和案例分析&#xff0c;探讨振弦采集仪在工程安全监测中的应用。 一&#xff0c…

欢乐钓鱼大师游戏攻略:在什么地方掉称号鱼?云手机游戏辅助!

《欢乐钓鱼大师》是一款融合了休闲娱乐和策略挑战的钓鱼游戏。游戏中的各种鱼类不仅各具特色&#xff0c;而且钓鱼过程充满了挑战和乐趣。下面将为大家详细介绍如何在游戏中钓鱼&#xff0c;以及一些有效的钓鱼技巧&#xff0c;帮助你成为一个出色的钓鱼大师。 实用工具推荐 为…

io_contextttttttttttt

创建上下文——io_context_t 它是一个上下文结构&#xff0c;在内部它包含一个完成队列&#xff0c;在线程之间是可以共享的。 提交请求——iocb io回调数据结构&#xff0c;和io_submit配合使用。 处理结果 通过io_event处理结果&#xff0c; struct io_event {void *data…

搜狗输入法产品使用说明

搜狗输入法产品使用说明 (qq.com) 看这里&#xff0c;这里记录下。基本都用这个&#xff0c;里面还是有很多小技巧不知道&#xff0c;可以参考下。

【刷题汇总--Fibonacci数列、单词搜索、杨辉三角】

C日常刷题积累 今日刷题汇总 - day0041、Fibonacci数列1.1、题目1.2、思路1.3、程序实现 2、单词搜索2.1、题目2.2、思路2.3、程序实现 3、杨辉三角3.1、题目3.2、思路3.3、程序实现 - 蛮力法3.4、程序实现 - vector3.5、程序实现 - dp 4、题目链接 今日刷题汇总 - day004 1、…

【CUDA】 矩阵乘向量 matVecMul

Matrix - Vector Multiplication 矩阵-向量乘法是线性代数中的基本操作。它用于将一个矩阵与一个向量相乘。乘法的结果是与输入向量大小相同的向量。 矩阵和向量的乘法如图1所示。 图1 基础kernel与共享内存kernel 执行矩阵-向量乘法的基础kernel是使用单个线程执行输出向量…

【SOLID原则前端中的应用】开闭原则(Open/Closed Principle)- vue3示例

开闭原则&#xff08;Open/Closed Principle&#xff09;在Vue 3中的应用 开闭原则&#xff08;Open/Closed Principle&#xff0c;OCP&#xff09;规定&#xff0c;软件实体&#xff08;类、模块、函数等&#xff09;应该对扩展开放&#xff0c;对修改关闭。 也就是说&#xf…

大型网站软件系统架构演进过程

在我们的生活中,通常会使用大型网站系统,比如购物网站淘宝,京东,阿里1688;大型搜索引擎网站百度,社交类的如腾讯旗下的微信,QQ及新浪旗下的微博等,他们通常都有一下特点: 高并发、大流量&#xff1a;这些系统必须能够处理成千上万甚至数百万的并发用户请求&#xff0c;以及持续…

Dubbo内部通信流程

我当时在学习的过程中搭建过demo&#xff0c;具体流程就是&#xff0c;我先定义了一个api接口模块&#xff0c;还定义一个服务提供者模块&#xff0c;然后服务提供方实现该接口&#xff0c;定义该方法具体的实现impl类&#xff0c;服务提供方启动时&#xff0c;将要暴露的服务和…

运维行业的全新视界:一体化监控解决方案

在当今的IT环境中&#xff0c;运维团队面临着前所未有的挑战。随着技术的快速发展&#xff0c;企业需要更加高效、智能的监控工具来确保IT基础设施的稳定运行。本文旨在为运维团队提供一个全面的、集成多种功能的监控解决方案参考。 一、总体架构与要求 首先&#xff0c;一个理…

Python中的模块和包定义以及如何在Python中导入和使用它们

在Python中&#xff0c;模块&#xff08;Module&#xff09;和包&#xff08;Package&#xff09;是组织代码、重用代码的基本单位&#xff0c;它们让Python的编程更加模块化&#xff0c;易于管理和维护。 模块&#xff08;Module&#xff09; 模块是一个包含Python定义和声明…

金融科技的移动时代:探索APP与SaaS系统的结合之道

金融科技&#xff08;FinTech&#xff09;的革新正在重塑金融服务行业的未来。移动应用&#xff08;APP&#xff09;与软件即服务&#xff08;SaaS&#xff09;系统的结合&#xff0c;为金融行业带来了前所未有的灵活性和可扩展性。 一、金融科技的发展趋势 金融科技通过技术…

在线快速制作二维码的技巧,支持生成多种内容二维码

现在用二维码来分享内容是很多场景下会使用的一种方式&#xff0c;常见的展示内容有图片、文件、文本、音频、视频等&#xff0c;都可以生成二维码之后。通过手机扫码来查看内容&#xff0c;有利于内容的快速传播&#xff0c;并且用户获取信息也更加的方便。 下面来教大家使用…

ubuntu rc.local开机自启动

https://blog.csdn.net/qq_48974566/article/details/137212295

Web应用防火墙用在哪些场景?

WAF是Web Application Firewall的缩写&#xff0c;翻译为“Web应用防火墙”是一种网络安全设备或服务&#xff0c;用于保护Web应用程序免受各种网络攻击和漏洞的影响。 WAF特别设计用于识别和阻止特定于Web应用程序的攻击&#xff0c;例如SQL注入、跨站脚本(XSS)、跨站请求伪造…

力扣习题--哈沙德数

一、前言 本系列主要讲解和分析力扣习题&#xff0c;所以的习题均来自于力扣官网题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台 二、哈沙德数 1. 哈沙德数 如果一个整数能够被其各个数位上的数字之和整除&#xff0c;则称之为 哈沙德数&#xff08;Harshad number&…