ffmpeg[学习(四)](代码实现) 实现音频数据解码并且用SDL播放
0、作者杂谈
CSDN大多数都是落后的,要么是到处复制粘贴的,对于初学者我来说困惑了很久,大多数CSDN文章都是使用旧的API ,已经被否决了,于是我读一些官方文档,和一些开源项目音视频的输出过程,写出这篇文章希望能帮助到入门音视频的人。
感觉这个专栏没多少人看呃,哎~
一、流程导图
其实与视频解码播放流程差不了太多,前面部分和专栏(一)一样
ffmpeg学习(一)
后面的话是添加了回调函数用于声卡通过回调函数拉数据到声卡缓冲区
二、实现过程
这中间省略了很多步骤 其实和ffmpeg学习(三)类似
SDL参数
转码参数和一开始的参数
这里新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大多数都是落后的,要么是到处复制粘贴的,对于初学者我来说困惑了很久,大多数CSDN文章都是使用旧的API ,已经被否决了,于是我读一些官方文档,和一些开源项目音视频的输出过程,写…...
C++ 字符串哈希 || 字符串前缀哈希法
字符串Hash就是构造一个数字使之唯一代表一个字符串。但是为了将映射关系进行一一对应,也就是,一个字符串对应一个数字,那么一个数字也对应一个字符串。 用字符串Hash的目的是,我们如果要比较一个字符串,我们不用直接比…...
【java】项目部署liunx服务器的简单步骤
在Linux服务器上部署Java项目通常涉及到一系列步骤,下面是一个基本的部署流程,具体步骤可能会根据项目和服务器环境的不同而有所调整: 1. 准备工作: 1.1 安装Java环境: 在Linux服务器上安装Java运行环境,…...

深度学习笔记(五)——网络优化(1):学习率自调整、激活函数、损失函数、正则化
文中程序以Tensorflow-2.6.0为例 部分概念包含笔者个人理解,如有遗漏或错误,欢迎评论或私信指正。 截图和程序部分引用自北京大学机器学习公开课 通过学习已经掌握了主要的基础函数之后具备了搭建一个网络并使其正常运行的能力,那下一步我们还…...

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

试用统信服务器操作系统UOS 20
作者:田逸(formyz) 试用统信Linux操作系统UOS,想了解一下用已有的Linux经验能否轻松驾驭它。以便在某些场景下,可以多一种选择。本次试验在Proxmox VE 8(以下简称PVE 8)平台下进行,采…...

[情商-11]:人际交流的心理架构与需求层次模型
目录 前言: 一、心理架构 1.1 个体生理层 1.2 个体心理层 1.3 点对点人际交流层 1.4 社会网络层 1.5 社会价值层 二、人的需求层次模型 2.1 需求(欲望)层次模型 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. 链表相交 时间复杂度:O(N),空间复杂度:O(1) 第一想法:求出两个链表长度,走差距步,再遍历找有没有相交 /*** 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,平均…...

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

计算机缺失msvcr100.dll如何修复?分享五种实测靠谱的方法
在计算机系统的日常运行与维护过程中,我们可能会遇到一种特定的故障场景,即系统中关键性动态链接库文件msvcr100.dll的丢失。msvcr100.dll是Microsoft Visual C Redistributable Package的一部分,对于许多基于Windows的应用程序来说ÿ…...

面试宝典进阶之redis缓存面试题
R1、【初级】Redis常用的数据类型有哪些? (1)String(字符串) (2)Hash(哈希) (3)List(列表) (4)Se…...

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

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

Jmeter 性能-监控服务器
Jmeter监控Linux需要三个文件 JMeterPlugins-Extras.jar (包:JMeterPlugins-Extras-1.4.0.zip) JMeterPlugins-Standard.jar (包: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 是什么?Labelme 能干啥? Ubuntu20.04安装Labelme1.Anaconda的安装2.Labelme的安装3.Labelme的使用 概要 图像检测需要自己的数据集,为此需要对一些数据进行数据标注,这里提供了一种图像的常用标注工具——la…...

回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制)
回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力机制) 目录 回归预测 | Matlab实现SSA-CNN-LSTM-Attention麻雀优化卷积长短期记忆神经网络注意力机制多变量回归预测(SE注意力…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
怎么让Comfyui导出的图像不包含工作流信息,
为了数据安全,让Comfyui导出的图像不包含工作流信息,导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo(推荐) 在 save_images 方法中,删除或注释掉所有与 metadata …...