当前位置: 首页 > news >正文

09-流媒体-FLV解复用

整体方案:
采集端:摄像头采集(YUV)->编码(YUV转H264)->写封装(H264转FLV)->RTMP推流
客户端:RTMP拉流->解封装(FLV转H264)->解码(H264转YUV)->YUV显示(SDL2)

#include <stdio.h>#define __STDC_CONSTANT_MACROSextern "C"
{
#include "libavformat/avformat.h"
};//封装格式MKV/MP4/FLV中如果有AAC的情况,首先这些封装格式中包含AudioSpecificConfig,
//保存在音频流的AVCodecContext->extradata 里面,需要解析然后封装ADTS即可#define DEMUXER_AAC 1
#define DEMUXER_MP3 0#define  ADTS_HEADER_SIZE (7)//FLV封装音视频 AAC封装在第一个AAC TAG会封装一个AudioSpecificConfig结构 
//AudioSpecificConfig解析结果保存在该结构体中
typedef struct  
{int write_adts;  int objecttype;  int sample_rate_index;  int channel_conf;  }ADTSContext;  //解析AudioSpecificConfig
int aac_decode_extradata(ADTSContext *adts, unsigned char *pbuf, int bufsize)  
{  int aot, aotext, samfreindex;  int i, channelconfig;  unsigned char *p = pbuf;  if (!adts || !pbuf || bufsize<2)  {  return -1;  }  aot = (p[0]>>3)&0x1f;  if (aot == 31)  {  aotext = (p[0]<<3 | (p[1]>>5)) & 0x3f;  aot = 32 + aotext;  samfreindex = (p[1]>>1) & 0x0f;   if (samfreindex == 0x0f)  {  channelconfig = ((p[4]<<3) | (p[5]>>5)) & 0x0f;  }  else  {  channelconfig = ((p[1]<<3)|(p[2]>>5)) & 0x0f;  }  }  else  {  samfreindex = ((p[0]<<1)|p[1]>>7) & 0x0f;  if (samfreindex == 0x0f)  {  channelconfig = (p[4]>>3) & 0x0f;  }  else  {  channelconfig = (p[1]>>3) & 0x0f;  }  }  
#ifdef AOT_PROFILE_CTRL  if (aot < 2) aot = 2;  
#endif  adts->objecttype = aot-1;  adts->sample_rate_index = samfreindex;  adts->channel_conf = channelconfig;  adts->write_adts = 1;  return 0;  
}  //添加ADTS头
int aac_set_adts_head(ADTSContext *acfg, unsigned char *buf, int size)  
{         unsigned char byte;    if (size < ADTS_HEADER_SIZE)  {  return -1;  }       buf[0] = 0xff;  buf[1] = 0xf1;  byte = 0;  byte |= (acfg->objecttype & 0x03) << 6;  byte |= (acfg->sample_rate_index & 0x0f) << 2;  byte |= (acfg->channel_conf & 0x07) >> 2;  buf[2] = byte;  byte = 0;  byte |= (acfg->channel_conf & 0x07) << 6;  byte |= (ADTS_HEADER_SIZE + size) >> 11;  buf[3] = byte;  byte = 0;  byte |= (ADTS_HEADER_SIZE + size) >> 3;  buf[4] = byte;  byte = 0;  byte |= ((ADTS_HEADER_SIZE + size) & 0x7) << 5;  byte |= (0x7ff >> 6) & 0x1f;  buf[5] = byte;  byte = 0;  byte |= (0x7ff & 0x3f) << 2;  buf[6] = byte;     return 0;  
}  int main(int argc, char* argv[])
{AVFormatContext *ifmt_ctx = NULL;AVPacket pkt;int ret, i;int videoindex=-1,audioindex=-1;#if DEMUXER_AACconst char *in_filename    = "demo.flv";		//Input file URLconst char *out_filename_v = "demo.h264";	//Output file URLconst char *out_filename_a = "demo.aac";#endif#if DEMUXER_MP3const char *in_filename    = "demo.flv";		//Input file URLconst char *out_filename_v = "demo.h264";	//Output file URLconst char *out_filename_a = "demo.mp3";#endifav_register_all();//Inputif ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {printf( "Could not open input file.");return -1;}if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {printf( "Failed to retrieve input stream information");return -1;}videoindex=-1;for(i=0; i<ifmt_ctx->nb_streams; i++) {if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){videoindex=i;}else if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){audioindex=i;}}FILE *fp_audio=fopen(out_filename_a,"wb+");  FILE *fp_video=fopen(out_filename_v,"wb+");  //FLV/MP4/MKV等结构中,h264需要h264_mp4toannexb处理。添加SPS/PPS等信息。FLV封装时,可以把//多个NALU放在一个VIDEO TAG中,结构为4B NALU长度+NALU1+4B NALU长度+NALU2+...,需要做的处理把4B//长度换成00000001或者000001AVBitStreamFilterContext* h264bsfc =  av_bitstream_filter_init("h264_mp4toannexb"); #if DEMUXER_AACADTSContext stADTSContext;unsigned char pAdtsHead[7];
#endifwhile(av_read_frame(ifmt_ctx, &pkt)>=0){if(pkt.stream_index==videoindex){av_bitstream_filter_filter(h264bsfc, ifmt_ctx->streams[videoindex]->codec, NULL, &pkt.data, &pkt.size, pkt.data, pkt.size, 0);printf("Write Video Packet. size:%d\tpts:%lld\n",pkt.size,pkt.pts);fwrite(pkt.data,1,pkt.size,fp_video);}else if(pkt.stream_index==audioindex){//AAC在封装结构MKV/FLV/MP4结构中,需要手动添加ADTS#if DEMUXER_AACaac_decode_extradata(&stADTSContext, ifmt_ctx->streams[audioindex]->codec->extradata, ifmt_ctx->streams[audioindex]->codec->extradata_size);aac_set_adts_head(&stADTSContext, pAdtsHead, pkt.size);fwrite(pAdtsHead, 1, 7, fp_audio);#endif//一般结构如MP3直接写文件即可printf("Write Audio Packet. size:%d\tpts:%lld\n",pkt.size,pkt.pts);fwrite(pkt.data,1,pkt.size,fp_audio);}av_free_packet(&pkt);}av_bitstream_filter_close(h264bsfc);  fclose(fp_video);fclose(fp_audio);avformat_close_input(&ifmt_ctx);if (ret < 0 && ret != AVERROR_EOF) {printf( "Error occurred.\n");return -1;}return 0;
}

相关文章:

09-流媒体-FLV解复用

整体方案&#xff1a; 采集端&#xff1a;摄像头采集&#xff08;YUV&#xff09;->编码&#xff08;YUV转H264&#xff09;->写封装&#xff08;&#xff28;264转FLV&#xff09;->RTMP推流 客户端&#xff1a;RTMP拉流->解封装&#xff08;FLV转H264&#xff09…...

信息的浏览

万维网(WWW)是目前Internet上最流行的一种服务&#xff0c;它是建立在Internet上的多媒体集合信息系统。它利用超媒体的信息获取技术&#xff0c;通过一种超文本的表达方式&#xff0c;将所有WWW上的信息连接在一起。我们使用浏览器浏览网上的信息。 ▶浏览器 浏览器是指可以…...

vue directive自定义指令实现弹窗可拖动

vue2 创建一个js文件 // draggable.js export default {// 定义 Vue 插件install(Vue) {Vue.directive(draggable, { // 全局指令名为 v-draggableinserted(el) {el.onmousedown function (ev) {// 获取鼠标按下时的偏移量&#xff08;鼠标位置 - 元素位置&#xff09;const…...

07-流媒体-RTMP推流

整体方案&#xff1a; 采集端&#xff1a;摄像头采集&#xff08;YUV&#xff09;->编码&#xff08;YUV转H264&#xff09;->写封装&#xff08;&#xff28;264转FLV&#xff09;->RTMP推流 客户端&#xff1a;RTMP拉流->解封装&#xff08;FLV转H264&#xff09…...

Neo4j安装(Docker中安装Neo4j)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

面试求职者

顾x文 SQLite3数据的使用实现了多线程UDP数据收发功能Qt多线程的同步和异步熟悉GDB的调试了解Mysql的性能优化熟悉常见算法&#xff1a;快速排序、希尔排序、归并排序基于Nginx C Mysql Python ICE开发熟练Boost库负责搭建后台服务端&#xff0c;使用Nginx展示前端界面&am…...

Java NIO 详解

一、NIO简介 NIO 是 Java SE 1.4 引入的一组新的 I/O 相关的 API&#xff0c;它提供了非阻塞式 I/O、选择器、通道、缓冲区等新的概念和机制。相比与传统的 I/O 多出的 N 不是单纯的 New&#xff0c;更多的是代表了 Non-blocking 非阻塞&#xff0c;NIO具有更高的并发性、可扩…...

css设置下划线

css中设置下划线的方法 在CSS中可以使用text-decoration属性或border-bottom属性来给字体设置下划线样式。 1、使用text-decoration:underline;设置下划线样式 CSS的text-decoration属性用于指定添加到文本的修饰&#xff0c;其underline属性值可以定义文本下的一条线。 语…...

【献给过去的自己】栈实现计算器(C语言)

背景 记得在刚学C语言时&#xff0c;写了一篇栈实现计算器-CSDN博客文章。偶然间看到了文章的阅读量以及评论&#xff0c;居然有1.7w的展现和多条博友的点评&#xff0c;反馈。 现在回过头来看&#xff0c;的确有许多不严谨的地方&#xff0c;毕竟当时分享文章时&#xff0c;还…...

如何利用ChatGPT撰写学术论文?

在阅读全文前请注意&#xff0c;本文是利用ChatGPT“辅助完成”而不是“帮写”学术论文&#xff0c;请一定要注意学术规范&#xff01; 本文我将介绍如何使用清晰准确的“指令”让ChatGPT帮助我们在论文写作上提高效率&#xff0c;希望通过本文的指导&#xff0c;读者能够充分…...

【PG】PostgreSQL高可用方案repmgr管理之配置文件

1 配置文件 1.1 配置文件格式 repmgr.conf是一个纯文本文件&#xff0c;每行包含一个参数/值组合。 空格是无关紧要的&#xff08;除了在带引号的参数值内&#xff09;&#xff0c;并且空行将被忽略。#将该行的其余部分指定为注释。不是简单标识符或数字的参数值应该用单引号…...

labelme自动标注工具

可以实现多图中相同目标的追踪&#xff0c;自动标注目标位置&#xff0c;速度极快&#xff0c;有需要评论...

【C++学习手札】模拟实现vector

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;くちなしの言葉—みゆな 0:37━━━━━━️&#x1f49f;──────── 5:28 &#x1f504; ◀️ ⏸ ▶️ ☰…...

Python将图片按照表格形式排列

图片按照表格的形式排列&#xff0c;可以使用图像处理库Pillow来实现 事例代码 from PIL import Image, ImageDraw# 创建一个画布&#xff0c;用来存放排列后的图片 canvas Image.new(RGB, (800, 600), white)# 读取图片 im1 Image.open(image1.jpg) im2 Image.open(image…...

Linux 简要命令记录

1、设置时区&#xff1a; #设为上海&#xff1a; timedatectl set-timezone Asia/Shanghai #搜索特定时区 timedatectl list-timezone2、修改时间&#xff1a; #设定系统时间 date -s "2023-11-16 22:30:00" #同步写入BIOS hwclock -w3、fdisk分区 rootheihei:~# …...

深度学习与深度强化学习

1. 深度学习中卷积层的作用是什么&#xff1f;全连接层的作用是什么&#xff1f;二者有什么联系和区别&#xff1f; 在深度学习中&#xff0c;卷积层&#xff08;Convolutional Layer&#xff09;和全连接层&#xff08;Fully Connected Layer&#xff09;是神经网络中常见的两…...

C++函数重载中形参是引用类型和常量引用类型的调用方法

void fun(int &a) {cout<<"调用func(int &a)<<endl; }void fun(const int &a) {cout<<"调用func(const int &a)<<endl; }int main() {// 1.调用引用类型的函数int a10;func(a);// 2.调用常量引用类型的函数&#xff0c;因为…...

Quest 3期间Sui上游戏处理了数百万笔交易

Sui固有的可扩展性和低且可预测的gas费使其成为Web3游戏的理想平台。在Quest 3中&#xff0c;参与的游戏项目处理了数百万笔交易&#xff0c;这毫无疑问地展示了Sui卓越的能力。 Quest 3的主题是游戏&#xff0c;让开发者有机会向潜在玩家介绍他们激动人心的创作。鼓励这些玩家…...

Python中如何定义类、基类、函数和变量?

在Python中&#xff0c;定义类、基类、函数和变量是非常常见的操作。以下是简单的示例&#xff1a; 定义类&#xff1a; class Animal:def __init__(self, name):self.name namedef make_sound(self):passclass Dog(Animal):def make_sound(self):return "Woof!"上…...

打开文件 和 文件系统的文件产生关联

补充1&#xff1a;硬件级别磁盘和内存之间数据交互的基本单位 OS的内存管理 内存的本质是对数据临时存/取&#xff0c;把内存看成很大的缓冲区 物理内存和磁盘交互的单位是4KB&#xff0c;磁盘中未被打开的文件数据块也是4KB&#xff0c;所以磁盘中页帧也是4KB&#xff0c;内存…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

Java 与 MySQL 性能优化:MySQL 慢 SQL 诊断与分析方法详解

文章目录 一、开启慢查询日志&#xff0c;定位耗时SQL1.1 查看慢查询日志是否开启1.2 临时开启慢查询日志1.3 永久开启慢查询日志1.4 分析慢查询日志 二、使用EXPLAIN分析SQL执行计划2.1 EXPLAIN的基本使用2.2 EXPLAIN分析案例2.3 根据EXPLAIN结果优化SQL 三、使用SHOW PROFILE…...