C++ 音视频流媒体浅谈

C++流媒体开发

今天就浅浅聊一下C++流媒体开发 

流媒体开发中最常见的是FFmpeg(编解码器)  业务逻辑主要是播放器了(如腾旭视频 爱奇艺等等)

FFmpeg是一个开源的音视频处理工具集,可以用于处理、转换和流媒体传输音视频文件。它包含了一系列的库和命令行工具,提供了强大的音视频编解码、格式转换、过滤器应用等功能。

以下是一些主要特点和功能:

  1. 格式支持广泛:FFmpeg支持几乎所有常见的音视频格式,包括但不限于MP4、AVI、MKV、MOV等。它能够对这些格式进行解码、编码和转换操作。

  2. 音视频编解码能力:FFmpeg支持多种音频编解码器(如AAC、MP3、FLAC)和视频编解码器(如H.264、H.265),可以实现音频和视频文件的压缩和解压缩操作。

  3. 视频流处理:FFmpeg可以处理各种视频流,包括网络摄像头实时流、屏幕捕捉流等。它能够进行录制、截取、转发等操作。

  4. 音频流处理:FFmpeg可以对音频流进行录制、混合、剪辑等操作。你可以从麦克风或其他输入设备获取音频,并将其发送到输出设备或保存为文件。

  5. 图像处理:除了音视频处理外,FFmpeg还提供了图像处理功能。你可以使用FFmpeg来调整图像大小,应用滤镜效果,进行图像转换等操作。

  6. 过滤器应用:FFmpeg内置了丰富的音视频过滤器,允许你对音视频进行处理和修改。你可以添加水印、调整亮度、对比度、色彩等参数,还可以实现视频剪裁、旋转和分割等操作。

FFmpeg是一个功能强大而灵活的工具,广泛应用于多媒体处理领域。它提供了简单易用的命令行界面和API接口,支持跨平台运行(Windows、Linux、macOS等),被众多开发者和专业用户所使用。

今天就聊一下音视频文件编码器(ffmpg)的转换吧(音视频的录制原理)

环境主要是Qt(Qt天然的支持跨平台)

编码主要流程

划分模块 

1.1 PCM 采集(麦克风+系统声音)+音频编码模块

1.2 Yun采集(摄像头+屏幕)+音视频编码模块 

   

解码主要流程:

将媒体数据解码 上面的过程逆行就可以了 这样就是一个完整播放器的模块

图中概念介绍:

1.时间戳  :时间戳通常指的是表示特定时间的数字或字符串

2.PCM:PCM(Pulse Code Modulation)是一种常用的数字音频编码方式,它将模拟声音信号转换为数字形式进行存储和传输。在PCM编码中,声音信号会被离散化成一系列采样点,并用固定的比特数来表示每个采样点的幅值。

3.Frame:在流媒体中,Frame(帧)是指一组连续的视频或音频数据。对于视频流来说,每个帧包含了一张完整的图像;对于音频流来说,每个帧包含了一段时间内的声音信号。

4.Packet:在计算机网络中,Packet(数据包)是将数据划分成小块进行传输的基本单位。它是网络通信中的信息载体,通过网络传输从源节点到目标节点。

5.Stream:音视频流

6.视频缓存:视频缓存是指在播放视频时,预先将部分视频数据存储在本地设备或服务器上,以提供更流畅的观看体验。

视频缓存 图像缓存类推

7.拉流;拉流是指从视频源服务器主动获取视频数据进行播放或处理的过程。在视频传输中,通常将视频源服务器称为推流端,而接收视频数据的设备称为拉流端

8.推流:推流是指将视频数据从源设备发送到视频服务器或云平台,以便其他用户可以通过网络观看或处理该视频流的过程。

9.YUV是一种常见的图像格式,它代表了图像的亮度(Y)和色度(U、V)信息。在视频处理和编码中经常使用YUV格式。

10.同步控制 :意思就是线程的同步 非异步编程

下面就介绍几个关于这些概念的代码实例

C++获取时间戳代码实例:

#include <iostream>
#include <chrono>int main() {// 获取当前时间的时间戳(以秒为单位)auto now = std::chrono::system_clock::now();auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();// 输出时间戳std::cout << "Current timestamp: " << timestamp << " seconds" << std::endl;return 0;
}

C++PCM应用

#include <iostream>
#include <fstream>int main() {// 打开 PCM 文件std::ifstream pcmFile("audio.pcm", std::ios::binary);if (!pcmFile) {std::cerr << "Failed to open PCM file." << std::endl;return 1;}// 读取 PCM 数据并进行处理const int bufferSize = 1024; // 缓冲区大小char buffer[bufferSize]; // 缓冲区while (!pcmFile.eof()) {pcmFile.read(buffer, bufferSize);// 在这里可以对 buffer 中的 PCM 数据进行处理,比如解码、编码、特征提取等// 这里只是简单地输出每个采样点的值(假设采样格式为16位有符号整数)for (int i = 0; i < pcmFile.gcount(); i += 2) {short sample = (buffer[i + 1] << 8) | buffer[i];std::cout << "Sample: " << sample << std::endl;}}// 关闭 PCM 文件pcmFile.close();return 0;
}

C++拉流代码应用

#include <opencv2/opencv.hpp>int main() {// 视频流URLstd::string stream_url = "your_stream_url_here";// 创建视频捕获对象cv::VideoCapture cap(stream_url);// 检查视频捕获对象是否成功打开视频流if (!cap.isOpened()) {std::cout << "无法打开视频流" << std::endl;return -1;}cv::Mat frame;while (true) {// 读取帧cap >> frame;// 检查帧是否成功读取if (frame.empty()) {std::cout << "无法读取帧" << std::endl;break;}// 显示帧图像cv::imshow("Video Stream", frame);// 按下 'q' 键退出循环if (cv::waitKey(1) == 'q') {break;}}// 释放资源和关闭窗口cap.release();cv::destroyAllWindows();return 0;
}

C++推流代码应用

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>extern "C" {#include <libavformat/avformat.h>#include <libavutil/opt.h>
}int main(int argc, char* argv[]) {// 输入参数const char* input_file = "input.mp4";const char* output_url = "rtmp://your-streaming-server.com/live/stream_key";// 初始化FFmpegav_register_all();// 打开输入文件AVFormatContext* input_ctx = NULL;if (avformat_open_input(&input_ctx, input_file, NULL, NULL) != 0) {fprintf(stderr, "无法打开输入文件\n");return -1;}// 查找输入文件流信息if (avformat_find_stream_info(input_ctx, NULL) < 0) {fprintf(stderr, "无法获取流信息\n");avformat_close_input(&input_ctx);return -1;}// 创建输出上下文并设置输出格式AVFormatContext* output_ctx = NULL;if (avformat_alloc_output_context2(&output_ctx, NULL, "flv", output_url) == -1) {   fprintf(stderr, "无法创建输出上下文\n");avformat_close_input(&input_ctx);return -1;   }// 遍历输入文件中的所有流,并在输出上下文中添加相应的流for (unsigned int i = 0; i < input_ctx->nb_streams; ++i) {AVStream* in_stream = input_ctx->streams[i];AVCodec* codec = avcodec_find_decoder(in_stream->codecpar->codec_id);AVStream* out_stream = avformat_new_stream(output_ctx, codec);if (!out_stream) {fprintf(stderr, "无法创建输出流\n");avformat_close_input(&input_ctx);avformat_free_context(output_ctx);return -1;}// 复制流参数if (avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar) < 0) {fprintf(stderr, "无法复制流参数\n");avformat_close_input(&input_ctx);avformat_free_context(output_ctx);return -1;}}// 打开输出URLif (!(output_ctx->oformat->flags & AVFMT_NOFILE)) {   if (avio_open(&output_ctx->pb, output_url, AVIO_FLAG_WRITE) < 0) {    fprintf(stderr, "无法打开输出URL\n");avformat_close_input(&input_ctx);   avformat_free_context(output_ctx); return -1;   } }// 写入文件头部信息if (avformat_write_header(output_ctx, NULL) < 0) {fprintf(stderr, "无法写入文件头部信息\n");avio_close(output_ctx->pb); avformat_close_input(&input_ctx);   avformat_free_context(output_ctx); return -1;  }// 推送数据AVPacket packet;while (av_read_frame(input_ctx, &packet) >= 0) {AVStream* in_stream = input_ctx->streams[packet.stream_index];AVStream* out_stream = output_ctx->streams[packet.stream_index];// 调整帧的时间基av_packet_rescale_ts(&packet, in_stream->time_base, out_stream->time_base);packet.pos = -1;// 写入输出流if (av_interleaved_write_frame(output_ctx, &packet) < 0) {fprintf(stderr, "无法写入输出流\n");break;}av_packet_unref(&packet);}// 写入文件尾部信息av_write_trailer(output_ctx);// 关闭输入和输出上下文avio_close(output_ctx->pb);  avformat_close_input(&input_ctx);   avformat_free_context(output_ctx); return 0;
}

好了 到这里对音视频的介绍就告一段落了 快过年了 祝大家新的一年里风调雨顺 事业有成

在这里小编有一个课程想介绍给大家:https://xxetb.xetslk.com/s/2PjJ3T

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

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

相关文章

「HarmonyOS」EventHub事件通知详细使用方法

需求背景&#xff1a; 在开发过程中&#xff0c;肯定会出现触发特定事件&#xff0c;需要全局进行通知&#xff0c;与之相关的部分进行执行相应的修改方法。举个例子&#xff1a;修改了用户个人昵称&#xff0c;需要进行全局通知&#xff0c;在涉及昵称的部分收到通知后&#…

Hive核心优化

数据采样 分桶表概述: 分桶就是分文件, 在创建表的时候, 指定分桶字段, 并设置分多少个桶, 在添加数据的时候, hive会根据设置分桶字段, 将数据划分到N个桶(文件)中, 默认情况采用HASH分桶方案 , 分多少个桶, 取决于建表的时候, 设置分桶数量, 分了多少个桶最终翻译的MR也就会运…

机器翻译在各领域的应用

你知道机器翻译有哪些应用领域吗&#xff1f; ​​机器翻译在多个领域都有应用场景&#xff0c;最常见的是商业领域。​机器翻译在商业领域中的应用如下&#xff1a; ​ 产品说明书&#xff1a;通过机器翻译&#xff0c;用户可以快速获取产品说明书中的内容&#xff0c;提高…

广州标点医药信息-米内网数据及咨询服务企业全方位解析!

米内网&#xff08;MENET&#xff09;原名中国医药经济信息网&#xff0c;由广州标点医药信息股份有限公司主办&#xff0c;2010年10月28日更名为“米内网”&#xff0c;上线初始主打医药销售数据库&#xff0c;经过十余年的迭代发展&#xff0c;现已成为国内主要的医药健康信息…

计网——应用层

应用层 应用层协议原理 网络应用的体系结构 客户-服务器&#xff08;C/S&#xff09;体系结构 对等体&#xff08;P2P&#xff09;体系结构 C/S和P2P体系结构的混合体 客户-服务器&#xff08;C/S&#xff09;体系结构 服务器 服务器是一台一直运行的主机&#xff0c;需…

数据结构·复杂度讲解

1. 什么是数据结构 数据结构(Data Structure)是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合。 数据结构是用来在内存中管理数据的&#xff0c;类似的&#xff0c;我们熟悉的文件或数据库是在硬盘中管理数据的。内存中的数据是带点…

2024美赛数学建模所有题目思路分析

美赛思路已更新&#xff0c;关注后可以获取更多思路。并且领取资料 C题思路 首先&#xff0c;我们要理解势头是什么。简单来说&#xff0c;势头是一方在比赛中因一系列事件而获得的动力或优势。在网球中&#xff0c;这可能意味着连续赢得几个球&#xff0c;或是在比赛的某个关…

【2024美赛】B题(中英文):搜寻潜水器Problem B: Searching for Submersibles

【2024美赛】B题&#xff08;中英文&#xff09;&#xff1a;搜寻潜水器Problem B: Searching for Submersibles 写在最前面2024美赛翻译 —— 跳转链接 中文赛题问题B&#xff1a;搜寻潜水器你的任务是&#xff1a; 词汇表 英文赛题Problem B: Searching for SubmersiblesYour…

AI:122-基于深度学习的电影场景生成与特效应用

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

详解 Prim 算法的实现

一、算法思路 Prim 算法是用来求最小生成树的&#xff0c;它的思想也有点类似于贪心——逐个将离当前集合最近的点加入到集合中&#xff0c;直至发现图不连通或所有点都被加到集合中&#xff0c;算法即宣告终止。它的具体做法是&#xff1a; step 1&#xff1a;初始时&#xf…

el-tree setChecked实现父子不联动

2024.1.29今天我学习了如何使用el-tree的setChecked用法&#xff0c;在使用el-tree的时候我们需要进行回显情况&#xff1a;如&#xff1a; [{id:1,name:张三, children:[{id:1-1,name:张三四},{id:1-2,name:张三五}]}, {id:2,name:李四}] 如果我们存id&#xff1a; [1,2]&a…

ArcGIS空间分析方法计算城市气体扩散

基于ArcGIS提供的空间分析方法,计算城市气体扩散涉及的密闭空间和开敞空间。 文章目录 一、实验描述二、实验过程1. 加载数据2.符号化3. 建立缓冲区4. 提取密闭空间(建筑)5.提取开敞区域6. 计算开敞空间面积三、注意事项一、实验描述 在对城市空间进行分析时,可将城市空间…

基于VMware和Unbuntu18.04编译 嘉立创·泰山派 Linux SDK

主机硬件要求 内存最少32G 硬盘腾出200-500G&#xff0c;虽然编译最终占了73G&#xff0c;但富余一些以后可以搞别的方便 操作系统win7/10/11 VMware 安装 1.去vmware官网下载&#xff1a;https://customerconnect.vmware.com/cn/downloads/info/slug/desktop_end_user_comp…

小红书种草商品笔记违规,有哪些原因?

发布小红书笔记之后迟迟没有流量&#xff0c;内容过关但是浏览量突然变低是什么原因?如果出现上述情况&#xff0c;就可能是商品笔记被限制了。那么该如何重新获得流量呢?今天我们就来分享下小红书种草商品笔记违规&#xff0c;有哪些原因&#xff1f; 一、怎样判断被限流了 …

网络原理-TCP/IP(4)

TCP原理 滑动窗口 之前我们讲过了确认应答策略,对发送的每一个数据段,都要给一个ACK确认应答,收到ACK后再发送下一个数据段. 确认应答,超时重传,连接管理这样的特性都是为了保证可靠运输,但就是付出了传输效率(单位时间能传输数据的多少)的代价,因为确认应答机制导致了时间大…

Qt实现类似ToDesk顶层窗口 不规则按钮

先看效果&#xff1a; 在进行多进程开发时&#xff0c;可能会遇到需要进行全局弹窗的需求。 因为平时会使用ToDesk进行远程桌面控制&#xff0c;在电脑被控时&#xff0c;ToDesk会在右下角进行一个顶层窗口的提示&#xff0c;效果如下&#xff1a; 其实要实现顶层窗口&#xf…

计算机设计大赛 深度学习 python opencv 火焰检测识别

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

LeetCode 第23天

669. 修剪二叉搜索树 卡哥讲的两个遍历的方法不太听得懂&#xff0c;去题解找了一个和昨天的题类似的删除二叉树节点的方法&#xff0c;感觉好不错。但是还是挺难写出来的&#xff0c;需要判断的情况有点多&#xff0c;再加上递归&#xff0c;我有点泪目了。 class Solution {…

STL - list

1、list的介绍及使用 1.1、list的介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向 其前一个元…

计算机网络(第六版)复习提纲21

SS4.6 互联网的路由选择协议 1 关于路由选择协议的基本概念 A 理想的路由算法&#xff08;路由选择协议的核心&#xff09;157 1 算法是正确和完整的 2 计算上简单 3 能适应通信量和网络拓扑的变化&#xff08;自适应性&#xff09; 4 稳定性 5 公平性 6 应当最佳&#xff08;特…