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

ffmpeg[学习(四)](代码实现) 实现音频数据解码并且用SDL播放

0、作者杂谈

CSDN大多数都是落后的,要么是到处复制粘贴的,对于初学者我来说困惑了很久,大多数CSDN文章都是使用旧的API ,已经被否决了,于是我读一些官方文档,和一些开源项目音视频的输出过程,写出这篇文章希望能帮助到入门音视频的人。
感觉这个专栏没多少人看呃,哎~

一、流程导图

其实与视频解码播放流程差不了太多,前面部分和专栏(一)一样
ffmpeg学习(一)
后面的话是添加了回调函数用于声卡通过回调函数拉数据到声卡缓冲区
在这里插入图片描述

二、实现过程

在这里插入图片描述
这中间省略了很多步骤 其实和ffmpeg学习(三)类似

SDL参数

在这里插入图片描述

转码参数和一开始的参数

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2d471a44ad4f45d99eac2af9ae05b400.pn
这里新API中将AVChannelLayout分离出来了,我们需要自己创建一个AVChannelLayout来获得声道布局为后面转码参数做铺垫

转码器

在这里插入图片描述

数据转换格式

在这里插入图片描述
这里SDL_Delay主要是防止声音播放过快。

回调函数

在这里插入图片描述

播放过程

在这里插入图片描述
😔 这里播放的是瓦罗兰特的die for you 可惜你们听不到 😄 希望这篇文章对读者有收获!

源代码

#include<iostream>
#include "vp_test.h"static uint8_t* audio_buf = new uint8_t[4096];static int audio_size;void read_audio_data(void* userdata, Uint8* stream,int len)
{if (audio_size == 0)return;int audio_buf_index = 0;int len1 = 0; while (len > 0){len1 = audio_size - audio_buf_index;if (len1 > len)len1 = len;memcpy(stream, audio_buf+audio_buf_index, len1);audio_buf_index += len1;stream += len1;len -= len1;}SDL_Delay(1);}int vp_audio(const char * filepath) {int ret = 0;AVFormatContext* is = NULL;AVCodecContext* ic = NULL;const AVCodec* codec = NULL;AVPacket* pkt = NULL;AVFrame* frame = NULL;int audio_index;//init ffmpegis = avformat_alloc_context();pkt = av_packet_alloc();frame = av_frame_alloc();//初始化网络库avformat_network_init();if (avformat_open_input(&is, filepath, NULL, NULL) != 0) {return -1;}if (avformat_find_stream_info(is, NULL) < 0) {return -1;}//查找音频解码器for (int i = 0; i < is->nb_streams; i++) {AVStream *stream = NULL;stream = is->streams[i];if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {codec = avcodec_find_decoder(stream->codecpar->codec_id);ic = avcodec_alloc_context3(codec);avcodec_parameters_to_context(ic,stream->codecpar);audio_index = i;}}//打开解码器if (avcodec_open2(ic, codec, NULL) != 0)return -1;//SDL 初始化音频模块SDL_Init(SDL_INIT_AUDIO | SDL_INIT_AUDIO);//初始化SDL中自己想设置的参数SDL_AudioSpec wanted_spec ;wanted_spec.freq = 44100;wanted_spec.format = AUDIO_S16SYS;wanted_spec.channels = 2;wanted_spec.samples = 1024;wanted_spec.callback = read_audio_data;wanted_spec.userdata = ic;//设置转码参数(转码成我们SDL播放的音频参数格式)AVChannelLayout out_ch;av_channel_layout_default(&out_ch, 2);int out_nb_samples = 1024;enum AVSampleFormat sample_fmt = AV_SAMPLE_FMT_S16;int out_sample_rate = 44100;// 解码前的格式参数AVChannelLayout in_ch ;av_channel_layout_default(&in_ch, 2);enum AVSampleFormat in_sample_fmt=ic->sample_fmt;int in_sample_rate=ic->sample_rate;//转码器SwrContext* swr_ctx = NULL;swr_alloc_set_opts2(&swr_ctx,&out_ch,sample_fmt,out_sample_rate,&in_ch,in_sample_fmt,in_sample_rate,0, NULL);swr_init(swr_ctx);//打开音频播放设备if (SDL_OpenAudio(&wanted_spec, NULL) < 0)return -1;//开始或暂停播放SDL_PauseAudio(0);//开始调用回调函数填充缓冲区while (true) {while (true) {if (av_read_frame(is, pkt))goto end;//读取完毕if (pkt->stream_index == audio_index)break;}//发送编码包avcodec_send_packet(ic, pkt);av_frame_unref(frame);if (avcodec_receive_frame(ic, frame) == 0) {//数据转换int upper_bound_samples = swr_get_out_samples(swr_ctx, frame->nb_samples);uint8_t* out[4] = { 0 };out[0] = (uint8_t*)av_malloc(upper_bound_samples * 2 * 2);int samples = swr_convert(swr_ctx,out,upper_bound_samples,(const uint8_t**)frame->data,frame->nb_samples);//将数据写入buffer区memcpy(audio_buf, out[0], samples * 4);audio_size = samples * 4;SDL_Delay(19);}}
end:if (is)avformat_free_context(is);if (ic)avcodec_free_context(&ic);if (pkt)av_packet_free(&pkt);if (frame)av_frame_free(&frame);if (swr_ctx)swr_free(&swr_ctx);SDL_CloseAudio();SDL_Quit();return 0;
}

相关文章:

ffmpeg[学习(四)](代码实现) 实现音频数据解码并且用SDL播放

0、作者杂谈 CSDN大多数都是落后的&#xff0c;要么是到处复制粘贴的&#xff0c;对于初学者我来说困惑了很久&#xff0c;大多数CSDN文章都是使用旧的API &#xff0c;已经被否决了&#xff0c;于是我读一些官方文档&#xff0c;和一些开源项目音视频的输出过程&#xff0c;写…...

C++ 字符串哈希 || 字符串前缀哈希法

字符串Hash就是构造一个数字使之唯一代表一个字符串。但是为了将映射关系进行一一对应&#xff0c;也就是&#xff0c;一个字符串对应一个数字&#xff0c;那么一个数字也对应一个字符串。 用字符串Hash的目的是&#xff0c;我们如果要比较一个字符串&#xff0c;我们不用直接比…...

【java】项目部署liunx服务器的简单步骤

在Linux服务器上部署Java项目通常涉及到一系列步骤&#xff0c;下面是一个基本的部署流程&#xff0c;具体步骤可能会根据项目和服务器环境的不同而有所调整&#xff1a; 1. 准备工作&#xff1a; 1.1 安装Java环境&#xff1a; 在Linux服务器上安装Java运行环境&#xff0c;…...

深度学习笔记(五)——网络优化(1):学习率自调整、激活函数、损失函数、正则化

文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解&#xff0c;如有遗漏或错误&#xff0c;欢迎评论或私信指正。 截图和程序部分引用自北京大学机器学习公开课 通过学习已经掌握了主要的基础函数之后具备了搭建一个网络并使其正常运行的能力&#xff0c;那下一步我们还…...

鸿蒙开发现在就业前景怎样?

随着科技的不断进步&#xff0c;鸿蒙系统逐渐崭露头角&#xff0c;成为智能设备领域的一颗新星。作为华为自主研发的操作系统&#xff0c;鸿蒙系统拥有着广阔的市场前景和就业机会。那么&#xff0c;鸿蒙开发的就业前景究竟怎样呢&#xff1f; 一、市场需求持续增长 随着鸿蒙…...

试用统信服务器操作系统UOS 20

作者&#xff1a;田逸&#xff08;formyz&#xff09; 试用统信Linux操作系统UOS&#xff0c;想了解一下用已有的Linux经验能否轻松驾驭它。以便在某些场景下&#xff0c;可以多一种选择。本次试验在Proxmox VE 8&#xff08;以下简称PVE 8&#xff09;平台下进行&#xff0c;采…...

[情商-11]:人际交流的心理架构与需求层次模型

目录 前言&#xff1a; 一、心理架构 1.1 个体生理层 1.2 个体心理层 1.3 点对点人际交流层 1.4 社会网络层 1.5 社会价值层 二、人的需求层次模型 2.1 需求&#xff08;欲望&#xff09;层次模型 2.2 基因与人需求之间的关系 2.3 个体生理需求 2.4 个体的心理需求…...

【.NET Core】Lazy<T> 实现延迟加载详解

【.NET Core】Lazy 实现延迟加载详解 文章目录 【.NET Core】Lazy<T> 实现延迟加载详解一、概述二、Lazy<T>是什么三、Lazy基本用法3.1 构造时使用默认的初始化方式3.2 构造时使用指定的委托初始化 四、Lazy.Value使用五、Lazy扩展用法5.1 实现延迟属性5.2 Lazy实现…...

坑记(HttpInputMessage)

一、背景知识 public interface HttpInputMessage extends HttpMessage Represents an HTTP input message, consisting of headers and a readable body.Typically implemented by an HTTP request on the server-side, or a response on the client-side.Since: 3.0 Author:…...

day04打卡

day04打卡 面试题 02.07. 链表相交 时间复杂度&#xff1a;O(N)&#xff0c;空间复杂度&#xff1a;O(1) 第一想法&#xff1a;求出两个链表长度&#xff0c;走差距步&#xff0c;再遍历找有没有相交 /*** Definition for singly-linked list.* struct ListNode {* int…...

语义分割miou指标计算详解

文章目录 1. 语义分割的评价指标2. 混淆矩阵计算2.1 np.bincount的使用2.2 混淆矩阵计算 3. 语义分割指标计算3.1 IOU计算方式1(推荐)方式2 3.2 Precision 计算3.3 总体的Accuracy计算3.4 Recall 计算3.5 MIOU计算 参考 MIoU全称为Mean Intersection over Union&#xff0c;平均…...

Unity3d 实现直播功能(无需sdk接入)

Unity3d 实现直播功能 需要插件 :VideoCapture 插件地址(免费的就行) 原理:客户端通过 VideoCapture 插件实现推流nodejs视频流转服务进行转发,播放器实现rtmp拉流 废话不多说,直接上 CaptureSource我选择的是屏幕录制,也可以是其他源 CaptureType选择LIVE–直播形式 LiveSt…...

计算机缺失msvcr100.dll如何修复?分享五种实测靠谱的方法

在计算机系统的日常运行与维护过程中&#xff0c;我们可能会遇到一种特定的故障场景&#xff0c;即系统中关键性动态链接库文件msvcr100.dll的丢失。msvcr100.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;对于许多基于Windows的应用程序来说&#xff…...

面试宝典进阶之redis缓存面试题

R1、【初级】Redis常用的数据类型有哪些&#xff1f; &#xff08;1&#xff09;String&#xff08;字符串&#xff09; &#xff08;2&#xff09;Hash&#xff08;哈希&#xff09; &#xff08;3&#xff09;List&#xff08;列表&#xff09; &#xff08;4&#xff09;Se…...

调试(c语言)

前言&#xff1a; 我们在写程序的时候可能多多少少都会出现一些bug&#xff0c;使我们的程序不能正常运行&#xff0c;所以为了更快更好的找到并修复bug&#xff0c;使这些问题迎刃而解&#xff0c;学习好如何调试代码是每个学习编程的人所必备的技能。 1. 什么是bug&#xf…...

opencv-4.8.0编译及使用

1 编译 opencv的编译总体来说比较简单&#xff0c;但必须记住一点&#xff1a;opencv的版本必须和opencv_contrib的版本保持一致。例如opencv使用4.8.0&#xff0c;opencv_contrib也必须使用4.8.0。 进入opencv和opencv_contrib的github页面后&#xff0c;默认看到的是git分支&…...

Jmeter 性能-监控服务器

Jmeter监控Linux需要三个文件 JMeterPlugins-Extras.jar (包&#xff1a;JMeterPlugins-Extras-1.4.0.zip) JMeterPlugins-Standard.jar (包&#xff1a;JMeterPlugins-Standard-1.4.0.zip) ServerAgent-2.2.3.zip 1、Jemter 安装插件 在插件管理中心的搜索Servers Perform…...

Excel学习

文章目录 学习链接Excel1. Excel的两种形式2. 常见excel操作工具3.POI1. POI的概述2. POI的应用场景3. 使用1.使用POI创建excel2.创建单元格写入内容3.单元格样式处理4.插入图片5.读取excel并解析图解POI 4. 基于模板输出POI报表5. 自定义POI导出工具类ExcelAttributeExcelExpo…...

【技能---labelme软件的安装及其使用--ubuntu】

文章目录 概要Labelme 是什么&#xff1f;Labelme 能干啥&#xff1f; Ubuntu20.04安装Labelme1.Anaconda的安装2.Labelme的安装3.Labelme的使用 概要 图像检测需要自己的数据集&#xff0c;为此需要对一些数据进行数据标注&#xff0c;这里提供了一种图像的常用标注工具——la…...

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力机制&#xff09; 目录 回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测&#xff08;SE注意力…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...