JHHK

欢迎来到我的个人网站
行者常至 为者常成

【MJ】09_播放PCM

参考:【秒懂音视频开发】09_播放PCM

本文是上面文章的摘要,只用于自己快速浏览.

目录

ffplay

可以使用ffplay播放《音频录制02_编程》中录制好的PCM文件,测试一下是否录制成功。

播放PCM需要指定相关参数:
ar:采样率
ac:声道数
f:采样格式

s16le:PCM signed 16-bit little-endian

更多PCM的采样格式可以使用命令查看
Windows:ffmpeg -formats | findstr PCM
Mac:ffmpeg -formats | grep PCM

SDL

一. 简介

ffplay是基于FFmpeg、SDL两个库实现的。通过编程的方式播放音视频,也是需要用到这2个库

SDL(Simple DirectMedia Layer),是一个跨平台的C语言多媒体开发库。

支持Windows、Mac OS X、Linux、iOS、Android

提供对音频、键盘、鼠标、游戏操纵杆、图形硬件的底层访问

SDL播放音频有2种模式:
Push(推):【程序】主动推送数据给【音频设备】
Pull(拉):【音频设备】主动向【程序】拉取数据

二. 下载

Windows平台下载

Mac平台下载

三.HelloWorld

  1. 环境配置

.pro文件中设置库的访问路径

在Windows环境中,还需要处理一下dll文件

  1. 打印版本
#include <SDL2/SDL.h>
 
SDL_version v;
SDL_VERSION(&v);
// 2 0 14
qDebug() << v.major << v.minor << v.patch;

播放PCM

一. 初始化系统

SDL分成好多个子系统(subsystem):

Video:显示和窗口管理

Audio:音频设备管理

Joystick:游戏摇杆控制

Timers:定时器

目前只用到了音频功能,所以只需要通过SDL_init函数初始化Audio子系统即可。

二. 打开音频设备

需要传递的参数:

采样率,采样格式(位深度,大小端,…),声道数,音频缓冲区的样本数量

读取文件的音频数据和长度,回调函数

三. 打开文件

打开需要播放的pcm文件

四. 开始播放

数据流向

读取的数据:通过循环不断从文件中读取数据,将数据放入一个bufferData,并记录读取的数据长度bufferLen

填充的数据:将读取的数据在回调函数内填充到stream,并移动bufferData的指针

播放数据:将stream内填充的数据进行播放.当播放完的时候再次调用回调函数进行填充.

如果bufferData还没有被消耗完(通过bufferLen是否大于0来判断),循环就空转(线程忙等),如果消耗完就从文件中读取数据到bufferData.如果再读取不到数据,就退出循环结束线程.

存在的问题

最后一次读取到bufferData的数据在被全部填充到stream后的那一刻,循环会立即退出,释放资源,线程销毁.这时stream内填充的数据还没有来的及播放,就被迫终止了.

从上边的分析可以看出导致问题出现是在bufferData变为0时的那次填充.

如何解决这个问题?

延时退出,记录变为0时那次填充到stream的数据大小,在根据每分钟播放的数据大小能计算出一个时间,让线程延时这个时间退出就能保证最后的数据播放完成.

五. 回调函数

// 等待音频设备回调(会回调多次)
void pull_audio_data(void *userdata,
                     // 需要往stream中填充PCM数据
                     Uint8 *stream,
                     // 希望填充的大小(samples * format * channels / 8)
                     int len
                    ) {
    //播放器没有数据播放时就会调用这个回调函数,来拉取数据
    //数据被填充到stream
    //需要填充的数据大小,比如len为4096 就是这次最多可以填充4096个字节的数据 len的大小是根据设置的音频缓冲区的样本数量(1024) 声道数(2) 采样格式(16bit) 共同决定的 
    //但bufferData内的数据可能大于4096 也可能小于 4096 ,所以要取bufferLen和 len中较小的那个值,来防止越界
}

六. 释放资源

关闭文件

关闭音频设备

清理子系统


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.