1. 音频框架简单介绍

linux 的音频管理是比较繁杂,我们的音频框架上层应用是的 js 服务, 中间层 ffmpeg + pulseaudio,底层的 alsa。 整个链路比较长,如何快速的定位播放问题是个问题,我对常见的问题做了总结

2. 常见问题的定位

2.1 设备无声

a. 确认各播放相关的进程是否正常,在内存珍贵的开发板上发送内存不足,进程被 OOM 一点也不奇怪,查看 pulseaudio 等播放相关进程被 kill

b. ffplay 确认中间层 ffmpeg 的基本功能

c. paplay 播放 wav 文件确认 paulseaudio 是否播放正常

d. pactl list 确认设备是不是被静音

e. pactl list sinks 检查 sink 流有木有被切到蓝牙设备上

f. aplay 播放 wav 文件确认 alsa 是否播放正常

g. 查看设备节点 ls dev/snd/

h. 检查喇叭是否连接好

备注:
  1. pulseaudio 可以直接管理一些流之外,它可以自主的切换输出流,比如切到 蓝牙设备上,耳机,蓝牙耳机很快切换 sink
  2. 可以使用 pactl 查看和设置当前 pulseaudio 的状态和每个sink、sink-input、source、source-output 的状态。
pactl -h
pactl [options] stat
pactl [options] info
pactl [options] list [short] [TYPE]
pactl [options] exit
pactl [options] upload-sample FILENAME [NAME]
pactl [options] play-sample  NAME [SINK]
pactl [options] remove-sample  NAME
pactl [options] load-module  NAME [ARGS ...]
pactl [options] unload-module  NAME|#N
pactl [options] move-(sink-input|source-output) #N SINK|SOURCE
pactl [options] suspend-(sink|source) NAME|#N 1|0
pactl [options] set-card-profile  CARD PROFILE
pactl [options] set-default-(sink|source) NAME
pactl [options] set-(sink|source)-port NAME|#N PORT
pactl [options] set-(sink|source)-volume NAME|#N VOLUME [VOLUME ...]
pactl [options] set-(sink-input|source-output)-volume #N VOLUME [VOLUME ...]
pactl [options] set-(sink|source)-mute NAME|#N 1|0|toggle
pactl [options] set-(sink-input|source-output)-mute #N 1|0|toggle
pactl [options] set-sink-formats #N FORMATS
pactl [options] set-port-latency-offset CARD-NAME|CARD-#N PORT OFFSET
pactl [options] subscribeThe special names @DEFAULT_SINK@, @DEFAULT_SOURCE@ and @DEFAULT_MONITOR@
can be used to specify the default sink, source and monitor.

常用的 pactl list 实时打印 pulseaudio 流的信息,主要的信息有:sink-input id, sink id (0 是默认 alsa 声卡), 流的 format 的信息,各声道的音量,是否被 mute,音量的通道,进程 id 和进程名

下图为 sink-inputs 的结果

pactl list sink-inputsSink Input #0Driver: protocol-native.cOwner Module: 3Client: 2Sink: 0Sample Specification: s16le 1ch 16000HzChannel Map: monoFormat: pcm, format.sample_format = "\"s16le\"" format.rate = "16000" format.channels = "1"  format.channel_map = "\"mono\"" Corked: noMute: noVolume: mono: 46656 /  71% / -8.85 dBbalance 0.00Buffer Latency: 0 usecSink Latency: 50535 usecResample method: ffmpegProperties:media.name = "system"application.name = "simpleplay"native-protocol.peer = "UNIX socket client"native-protocol.version = "32"application.process.id = "1786"application.process.user = "root"application.process.host = "OpenWrt"application.process.binary = "iotjs"application.language = "C"application.process.machine_id = "c7f625e9718357b9bd7ff09b5d0790b1"module-stream-restore.id = "sink-input-by-media-name:system"

2.2 播放失败

一般情况下,可以通过日志打印初步确认是否是 js 上层的调用逻辑问题

其他的播放失败问题就主要在 ffmpeg 和 pulseaudio

2.2.1 ffmpeg 层错误

网络流媒体播放失败原因主要有网络问题,音频源服务端问题等,服务端的问题主要通过 tcpdump 抓包查看

a. 网络不好读不到包,ping 查看网络环境(最好 ping 音乐源的服务器)

b. 音乐源代理服务器出问题连接断掉,导致播放器提前读到 eof。
之前有个酷狗音乐源的,音乐的最后一段没播放完成,解决到方法是每次设备播放完成在做一次重连策略

c. gethostbyname() 域名解析失败阻塞,导致播放失败且会达到 8秒以上的阻塞

d. 有遇到一个设备无法播放酷狗服务器的任何 url,原因:音乐源做压力测试 ,那个网络出口,请求太多了,服务器认为异常攻击,把它的ip请求给封了

e. 如果是 adb 命令行 paplay 播放,播放一半后断掉,首先检查 adb 连接是否正常,可能是 paplay 进程在前台播放被终止了,将paplay放到后台测试。

f. seek 操作后无法正确获取音频数据,可能是有的音频服务端的没有conten-lenght 字段,ffmpeg http服务无法 seek。

2.2.2 pulseaudio 层

a. 声卡未准备成功,导致 pulseaudio 无法正常播放

b. 声卡被独占

2.3. 设备声音不合适

比如最小音量过大的问题,可以设置合适的音量曲线

2.4 底噪爆破音问题

2.4.1 问题定位

底噪和爆破音的问题定位,主要是通过录制各层生成的数据,然后在 PC 上通过 AdobeAudition 查看录制的文件确认来确认噪音数据到底是那层产生的

ffmpeg 到 pulseaudio 的链路:

在 ffplayer 代码中在 sdl_audio_callback 中有个 test 的宏打开可以录制 ffmpeg 给 pulseaudio 的 pcm 数据

pulseaudio 到 alsa 的链路:

下面是捕捉 pulseaudio 给 alsa 数据的脚本(现在直接存的 pcm 数据,要是数据量很大的话,也可以在存储的时候把 pcm 数据进行编码,不过要编译对应的编码程序)

PCM="$1"
if [ -z "$PCM" ]; thenecho "Usage: $0 OUTPUT.PCM" >&2exit 1
fi
rm -f "$PCM"
# Get sink monitor:
MONITOR=$(pactl list | egrep -A2 '^(\*\*\* )?Source #' | \grep 'Name: .*\.monitor$' | awk '{print $NF}' | tail -n1)
echo "set-source-mute ${MONITOR} false" | pacmd >/dev/null
# Record it raw
echo "Recording to $PCM ..."
echo "Close this window to stop"
parec -d "$MONITOR" --format=s16le --channels=2 >> "$PCM"

2.4.1 解决方法

a. 底层功放限制,做最高音量的限制

b. 应用层可以做播放的淡入淡出操作,具体可以是添加静音数据或音量阶梯式恢复

c. 设备启动爆音,可以在 pulseaudio 的音量数据库中设置好启动音量,避免突然大音量导致的爆破

备注:

设备启动时日志抓取

a. 通过串口读日志

b. 读 logread 的缓存日志,需要分析 pulseaudio 的日志就先开启 pulseaudio log 并重定向到logread 系统,pulseaudio 的debug会有大量日志信息,logread的缓存区太小,抓不到更多信息,可以启动脚本修改 logread 的缓存区大小,获取更多缓存日志

2.5 卡断的问题

a. 网络卡顿

b. 缓冲区太小

c. 供电不足

2.6 内存泄露爆增问题

2.6.1 内存问题

内存问题一般分为传统的内存泄露和大量内存被 still reachable

内存泄露

a. new 和delete ,malloc 和free 不匹配使用造成的泄露

b. 申请的动态内存没有释放

c. remalloc 泄露

glibc 等内存管理引起内存爆增

a. linux 底层内存管理的策略

b. 程序设计无限制的申请大量内存作为缓冲区

2.6.2 问题定位

难点

a. 内存管理引起的内存爆增,通常是要某种场景内存使用达到某种峰值使得进程向系统申请内存,不好复现

b. 我们的播放器功能多主要有播放,倍速播放和不同音效播放,使用了不同的库,测试定位不方便

c. 我们的设备内存小,好多内存检测的工具和带符号表的文件不好推

解决方法

a. 带符号表的库 /usr/lib 放不下问题,可以推到 data 目录下,然后修改环境变量 LD_LIBRARY_PATH 添加 data 到加载路径

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data

b. 使用内存检查工具 valgrind 的 mencheck,基本可以检查出内存是否为泄露还是被进程管理,其中still reachable 说明是被内存管理,未还给系统的

==8302==    definitely lost: 96 bytes in 6 blocks
==8302==    indirectly lost: 0 bytes in 0 blocks
==8302==      possibly lost: 46,616 bytes in 1,317 blocks
==8302==    still reachable: 814,079 bytes in 2,321 blocks
==8302==         suppressed: 0 bytes in 0 blocks

c. valgrind运行会占用大量内存,如果跑不起来可以使用谷歌工具 gperftools,gpeftoos 轻量很适合开发板的内存检查

2.7. cpu 占用高的问题

定位进程 cpu 问题

1.查看进程中的哪个线程cpu的占⽤用率⾼,查看高 cpu 的线程id
top -Hp ${pid}2. 使用 strace 查看 CPU 占用高的线程当前的系统调用
//注:tid 是通过 1 查看对高 cpu 的线程 id
strace -p ${tid}3. 如果通过 2 的系统调用不能确认上层的使⽤的函数,使用 adbserver attach
到该进程查看 cpu 高的线程的堆栈调用
// 注: adbserver 主要有2 个优势:
// 1.可以 attach 到正在运行的进程上进行调试
// 2. 可以在 PC 机上外部分析栈等,解决设备内存小不好推带符号表的库的问题
备注

gdbserver 的使用

gdbserver的使用1.在设备端// 在设备端运⾏ gdbserver,并 attach 到调试进程(ip是设备ip)
gdbserver IP:PORT --attach ${pid}2. 在 pc 端运行 // 运行 gdb
gdb// 连接 gdbserver
target remote IP:PORT// 加载进程
file ${proc}// 加载带符号表的动态库
set sysroot ${solib}3. 进⾏ gdb 调试

实际操作中可能会出现进程突然attch的时候挂掉

linux 音频播放的系统层问题相关推荐

  1. linux 音频播放器源码,Linux的音频播放器的设计源代码.doc

    Linux的音频播放器的设计源代码 嵌入式操作系统 课程设计 源代码 设计题目: 基于Linux的音频播放器的设计 院 系: ********* 班 级: ******** 组 别: 第1组 学 号: ...

  2. linux 音频播放器源码,基于Linux的音频播放器的设计 源代码.doc

    嵌入式操作系统 课程设计 源代码 设计题目: 基于Linux的音频播放器的设计 院 系: ********* 班 级: ******** 组 别: 第1组 学 号: ****** 姓 名: 起止日期: ...

  3. 嵌入式linux音频播放器设计,基于嵌入式Linux下Madplay音频播放器设计论文.docx

    基于嵌入式Linux下Madplay音频播放器设计论文 滁州职业技术学院计算机应用技术专业毕业论文PAGE I 滁州职业技术学院信息工程系--2015届计算机应用专业毕业论文 姓 名: 周杰 班 级: ...

  4. linux 音频播放器源码,Android音乐播放器源码

    相当完整的Android音乐播放器,直接上效果图及源代码,自己欣赏,具体不再解释了,可以说是一个很给力的Android音乐播放器. 示例代码: /* * Copyright (C) 2009 Tele ...

  5. linux声卡测试命令,linux添加声卡驱动使用命令行音频播放器的方法

    首先linux系统需要有声卡 哪怕是虚拟声卡,我用的是virtualbox,intel 80x AC97 声卡. 安装声卡驱动,在linux内核的找到声卡对应的驱动 可以集成到内核,或者安装为模块,为 ...

  6. linux数字音频播放器,Moode Audio Player数字音频播放系统的体验

    Element14 Raspberry Pi 3B Raspberry Pi 3B ARM开发板封装 Volumio OS数字音频播放系统-主页控制主界面 上周末,我们为几台ARM微型计算机推出了Ra ...

  7. qmmp安装包linux版,Qmmp音频播放器1.2.1发布下载(附Ubuntu 18.04下安装方法)

    Qmmp是一款基于Qt的音乐播放器,当前最新版本已到1.2.1版本(qt4为0.11.1),它具有winamp或xmms接口,新的Qmmp版本支持FFmpeg 4.0,并添加了改变默认用户界面的功能. ...

  8. 【Arduino + Linux】基于 Helix 解码库实现 MP3 音频播放

    目录 一.MP3 文件结构 1.1.ID3V2.3 1.1.1.标签头 1.1.2.扩展标签头 1.1.3.标签帧 1.2.音频数据 1.3.ID3V1 1.4.MP3文件结构图 二.MP3 解码库 ...

  9. 瑞芯微RK3399芯片开发板香橙派4的HDMI音频播放功能测试(Linux系统)

    瑞芯微RK3399芯片开发板香橙派OrangePi 4(16G)用拥有4G内存16G存储,集成双频WiFi.蓝牙5.0.HDMI输出.千兆网口.USB接口等丰富的功能接口,支持双摄像头输入和两路视频输 ...

最新文章

  1. Anaconda:包安装以XGBoost为例
  2. keras从入门到放弃(七)多层感知器训练
  3. Condition总结-CountDownLatch源码分析
  4. cheerio的小案例
  5. 如何化身BAT面试收割机?不吃透都对不起自己
  6. Python 学习---------Day4
  7. 意图识别 聊天机器人_如何解决聊天机器人中的意图冲突
  8. 一文解决十大排序算法(动画图解)
  9. 从数学的视角看社交网络
  10. 计算机无法检测电池损耗怎么办,笔记本电脑电池损耗怎么修复 笔记本电脑电池损耗修复方法...
  11. 【安卓手机驱动无法安装则无法连接电脑,终极100%解决方法】ADB interfacm与 Andriod安装出现黄色感叹号
  12. 电脑网速,详细教您电脑网速慢怎么办
  13. java使用密文链接数据库_Java基础——数据库连接信息使用密文
  14. R语言27-Prosper 贷款数据分析3
  15. 陶哲轩实分析 命题7.2.9 绝对收敛判别法
  16. GRAF: Generative Radiance Fields for 3D-Aware Image Synthesis
  17. BUGKU--web详解
  18. D - Denouncing Mafia DFS
  19. 桌球歷史:削球、快攻、弧圈球
  20. 智能服务机器人产品及解决方案

热门文章

  1. linux常用基础命令整理
  2. python机械编程入门先学什么_编程入门先学什么
  3. Java获取当前时间前24小时时间
  4. 右键图形属性 图形选项_如何调整视频游戏选项以获得更好的图形和性能
  5. 人工智能数学基础--导数3:隐函数求导、对数求导法、参数方程求导法
  6. GPS北斗卫星授时服务器(NTP时钟)设计及方案应用
  7. 用户指南:自动切换打印机的位置感知打印功能——乡巴佬下载
  8. HCNP学习笔记之IP地址、子网掩码、网关的关系
  9. malloc函数未定义
  10. List循环中指定删除元素(不止一个)