FFmpeg开发笔记(十八)FFmpeg兼容各种音频格式的播放

本文涉及的产品
视觉智能开放平台,图像资源包5000点
视觉智能开放平台,分割抠图1万点
视觉智能开放平台,视频资源包5000点
简介: 《FFmpeg开发实战》一书中,第10章示例程序playaudio.c原本仅支持mp3和aac音频播放。为支持ogg、amr、wma等非固定帧率音频,需进行三处修改:1)当frame_size为0时,将输出采样数量设为512;2)遍历音频帧时,计算实际采样位数以确定播放数据大小;3)在SDL音频回调函数中,确保每次发送len字节数据。改进后的代码在chapter10/playaudio2.c,可编译运行播放ring.ogg测试,成功则显示日志并播放铃声。

​FFmpeg结合SDL可以播放音频文件,也能播放视频文件中的音频流,《FFmpeg开发实战:从零基础到短视频上线》一书第10章的示例程序playaudio.c支持播放mp3和aac两种格式的音频,却不支持播放其他格式的音频。

因为mp3和aac两个格式拥有标准的规范定义,比如mp3规定每帧音频固定包含1152个样本,而aac规定每帧音频固定包含1024个样本。在它们的解码器实例AVCodecContext中,即可从frame_size字段获取每帧音频的样本数量。
然而其他音频格式(如ogg、amr、wma等)的每帧样本数并不固定,从frame_size字段取到的样本数量为0,这不仅导致SDL初始化失败,还导致重采样过程异常。为了能够播放其他格式的音频,需要对playaudio.c做下列三处修改。
1、从解码器实例获取音频样本数时,如果发现frame_size为0,就要把样本数变量设为512(注意该数值必须为2的n次幂,如256、512、1024等),修改后的赋值代码如下所示:

int out_nb_samples = audio_decode_ctx->frame_size; // 输出的采样数量
if (out_nb_samples <= 0) {
    out_nb_samples = 512;
}

2、在遍历音频帧的时候,要重新计算实际的采样位数,以便确定多少音频数据送给扬声器。具体的计算过程是这样的:先调用swr_convert函数对音频重采样,该函数的返回值为输出的数据大小;这个输入大小乘以声道数量乘以音频样本的位深(位深表示每个音频样本占据几个字节),最终的乘积便是要送给扬声器的音频数据大小。详细的计算代码如下所示:

// 重采样。也就是把输入的音频数据根据指定的采样规格转换为新的音频数据输出
int swr_size = swr_convert(swr_ctx, // 音频采样器的实例
    &out_buff, MAX_AUDIO_FRAME_SIZE, // 输出的数据内容和数据大小
    (const uint8_t **) frame->data, frame->nb_samples); // 输入的数据内容和数据大小
audio_pos = (unsigned char *) out_buff; // 把音频数据同步到缓冲区位置
// 这里要计算实际的采样位数
audio_len = swr_size * out_channels * av_get_bytes_per_sample(out_sample_fmt);

3、SDL的音频回调函数当中,注意每次要凑足len个字节。鉴于重采样后的音频数据可能较大(主要是amr格式有这种情况),因此要按照len指定的长度切割数据,确保每次回调函数都刚好把长度为len的音频数据送往扬声器。修改后的回调代码如下所示:

// 回调函数,在获取音频数据后调用
void fill_audio(void *para, uint8_t *stream, int len) {
    SDL_memset(stream, 0, len); // 将缓冲区清零
    if (audio_len == 0) {
        return;
    }
    while (len > 0) { // 每次都要凑足len个字节才能退出循环
        int fill_len = (len > audio_len ? audio_len : len);
        // 将音频数据混合到缓冲区
        SDL_MixAudio(stream, audio_pos, fill_len, SDL_MIX_MAXVOLUME);
        audio_pos += fill_len;
        audio_len -= fill_len;
        len -= fill_len;
        stream += fill_len;
        if (audio_len == 0) { // 这里要延迟一会儿,避免一直占据IO资源
            SDL_Delay(1);
        }
    }
}

上述修改后的代码已经附在了《FFmpeg开发实战:从零基础到短视频上线》一书第10章的源码chapter10/playaudio2.c,这个c代码是playaudio.c的改进版,除了支持原来mp3和aac格式的音频播放,还支持ogg、amr、wma等格式的音频播放,以及asf、webm等视频文件的音频播放。
接着执行下面的编译命令。

gcc playaudio2.c -o playaudio2 -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -I/usr/local/sdl2/include -L/usr/local/sdl2/lib -lsdl2 -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswscale -lswresample -lpostproc -lm

编译完成后执行以下命令启动测试程序,期望播放音频文件ring.ogg。

./playaudio2 ../ring.ogg

程序运行完毕,发现控制台输出以下的日志信息。

Success open input_file ../ring.ogg.
out_sample_rate=11025, out_nb_samples=512
out_buffer_size=1024
256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256 256
Success play audio file.
Quit SDL.

同时电脑扬声器传来了两个“叮咚”的铃声,表示上述代码正确实现了播放ogg音频的功能。

目录
相关文章
|
15天前
|
XML Java Android开发
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
GSYVideoPlayer是一款国产移动端视频播放器,支持弹幕、滤镜、广告等功能,采用IJKPlayer、Media3(EXOPlayer)、MediaPlayer及AliPlayer多种内核。截至2024年8月,其GitHub星标数达2万。集成时需使用新版Android Studio,并按特定步骤配置依赖与权限。提供了NormalGSYVideoPlayer、GSYADVideoPlayer及ListGSYVideoPlayer三种控件,支持HLS、RTMP等多种直播链接。
53 18
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
|
14天前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
EasyPusher是一款国产RTSP直播录制推流客户端工具,支持Windows、Linux、Android及iOS等系统。尽管其GitHub仓库(安卓版:https://github.com/EasyDarwin/EasyPusher-Android)已多年未更新,但通过一系列改造,如升级SDK版本、迁移到AndroidX、指定本地NDK版本及更新Gradle版本等,仍可在最新Android Studio上运行。以下是针对Android Studio Dolphin版本的具体改造步骤。
40 3
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
|
13天前
|
编解码 API 数据安全/隐私保护
FFmpeg开发笔记(五十四)使用EasyPusher实现移动端的RTSP直播
【9月更文挑战第21天】本文介绍了如何使用FFmpeg和EasyPusher实现移动端RTSP直播。首先概述了EasyPusher的功能及其API,接着详细描述了安装FFmpeg、获取EasyPusher库、初始化对象、打开输入流、配置推送参数及读取推送帧的具体步骤,并提醒开发者注意网络环境、编码参数和权限管理等问题,以确保直播质量与稳定性。
|
29天前
|
编解码 移动开发 安全
FFmpeg开发笔记(五十)聊聊几种流媒体传输技术的前世今生
自互联网普及以来,流媒体技术特别是视频直播技术不断进步,出现了多种传输协议。早期的MMS由微软主导,但随WMV格式衰落而减少使用。RTSP由网景和RealNetworks联合提出,支持多种格式,但在某些现代应用中不再受支持。RTMP由Adobe开发,曾广泛用于网络直播,但因HTML5不支持Flash而受影响。HLS由苹果开发,基于HTTP,适用于点播。SRT和RIST均为较新协议,强调安全与可靠性,尤其SRT在电视直播中应用增多。尽管RTMP仍占一定市场,但SRT等新协议正逐渐兴起。
67 8
FFmpeg开发笔记(五十)聊聊几种流媒体传输技术的前世今生
|
1月前
|
Web App开发 Java 视频直播
FFmpeg开发笔记(四十九)助您在毕业设计中脱颖而出的几个流行APP
对于软件、计算机等专业的毕业生,毕业设计需实现实用软件或APP。新颖的设计应结合最新技术,如5G时代的音视频技术。示例包括: 1. **短视频分享APP**: 集成FFmpeg实现视频剪辑功能,如添加字幕、转场特效等。 2. **电商购物APP**: 具备直播带货功能,使用RTMP/SRT协议支持流畅直播体验。 3. **同城生活APP**: 引入WebRTC技术实现可信的视频通话功能。这些应用不仅实用,还能展示开发者紧跟技术潮流的能力。
69 4
FFmpeg开发笔记(四十九)助您在毕业设计中脱颖而出的几个流行APP
|
2月前
|
JavaScript 前端开发 Java
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
IT寒冬使APP开发门槛提升,安卓程序员需转型。选项包括:深化Android开发,跟进Google新技术如Kotlin、Jetpack、Flutter及Compose;研究Android底层框架,掌握AOSP;转型Java后端开发,学习Spring Boot等框架;拓展大前端技能,掌握JavaScript、Node.js、Vue.js及特定框架如微信小程序、HarmonyOS;或转向C/C++底层开发,通过音视频项目如FFmpeg积累经验。每条路径都有相应的书籍和技术栈推荐,助你顺利过渡。
45 3
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
|
2月前
|
Web App开发 Android开发
FFmpeg开发笔记(四十六)利用SRT协议构建手机APP的直播Demo
实时数据传输在互联网中至关重要,不仅支持即时通讯如QQ、微信的文字与图片传输,还包括音视频通信。一对一通信常采用WebRTC技术,如《Android Studio开发实战》中的App集成示例;而一对多的在线直播则需部署独立的流媒体服务器,使用如SRT等协议。SRT因其优越的直播质量正逐渐成为主流。本文档概述了SRT协议的使用,包括通过OBS Studio和SRT Streamer进行SRT直播推流的方法,并展示了推流与拉流的成功实例。更多细节参见《FFmpeg开发实战》一书。
43 1
FFmpeg开发笔记(四十六)利用SRT协议构建手机APP的直播Demo
|
28天前
|
Android开发 计算机视觉 C++
FFmpeg开发笔记(五十一)适合学习研究的几个音视频开源框架
音视频编程对许多程序员来说是一片充满挑战的领域,但借助如OpenCV、LearnOpenGL、FFmpeg、OBS Studio及VLC media player等强大的开源工具,可以降低入门门槛。这些框架不仅覆盖了计算机视觉、图形渲染,还包括多媒体处理与直播技术,通过多种编程语言如Python、C++的应用,使得音视频开发更为便捷。例如,OpenCV支持跨平台的视觉应用开发,FFmpeg则擅长多媒体文件的处理与转换,而VLC media player则是验证音视频文件质量的有效工具。
47 0
FFmpeg开发笔记(五十一)适合学习研究的几个音视频开源框架
|
2月前
|
Web App开发 5G Linux
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
一年一度的毕业季来临,计算机专业的毕业设计尤为重要,不仅关乎学业评价还积累实战经验。选择紧跟5G技术趋势的音视频APP作为课题极具吸引力。这里推荐三类应用:一是融合WebRTC技术实现视频通话的即时通信APP;二是具备在线直播功能的短视频分享平台,涉及RTMP/SRT等直播技术;三是具有自定义动画特效及卡拉OK歌词字幕功能的视频剪辑工具。这些项目不仅技术含量高,也符合市场需求,是毕业设计的理想选择。
68 6
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
|
2月前
|
编解码 Java Android开发
FFmpeg开发笔记(四十五)使用SRT Streamer开启APP直播推流
​SRT Streamer是一个安卓手机端的开源SRT协议直播推流框架,可用于RTMP直播和SRT直播。SRT Streamer支持的视频编码包括H264、H265等等,支持的音频编码包括AAC、OPUS等等,可谓功能强大的APP直播框架。另一款APP直播框架RTMP Streamer支持RTMP直播和RTSP直播,不支持SRT协议的直播。而本文讲述的SRT Streamer支持RTMP直播和SRT直播,不支持RTSP协议的直播。有关RTMP Streamer的说明参见之前的文章《使用RTMP Streamer开启APP直播推流》,下面介绍如何使用SRT Streamer开启手机直播。
56 4
FFmpeg开发笔记(四十五)使用SRT Streamer开启APP直播推流

热门文章

最新文章

下一篇
无影云桌面