说明
需要知道PCM的参数:采样率、采样格式、一帧采样个数、声道数。
对于ffplay需要知道 采样率、采样格式、声道数三个就行了。提取PCM
ffmpeg -i input.mp3 -f s16le -acodec pcm_s16le -ar 48000 -ac 1 output.pcm
- 播放PCM
ffplay -f s16le -ar 48000 -ac 1 output.pcm
SDL播放PCM的原理
SDL播放音频数据时会提供一个buf和len,前者是需要填充PCM数据的区域,len则是需要填充的长度,所以打开设备(SDL_OpenAudio)和准备播放后(SDL_PauseAudio),就需要一直给buf喂数据了。不过这个喂数据的过程是被动的,也就是给SDL提供一个喂PCM数据函数。SDL想要数据了自己调就行了。
实现步骤
- 编写喂数据函数,核心是给buf填充len长度的数据。
- 初始化SDL
- 打开音频设备
- 开始播放
示例代码
FILE *pPCMFile = NULL;
void fill_audio(void *udata, Uint8 *stream, int len) {
SDL_memset(stream, 0, len);
fread(stream, 1, len, pPCMFile);
}
//SDL初始化
ret = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER);
if (ret) {
printf("SDL init error\n"); return -1;
}
SDL_AudioSpec wanted_spec;
//设置已知音频的参数 采样率、采样格式、帧采样数目等
wanted_spec.freq = 44100;
wanted_spec.format = AUDIO_S16SYS;
wanted_spec.channels = 1;
wanted_spec.silence = 0;
wanted_spec.samples = 1024;
wanted_spec.callback = fill_audio;
//打开SDL
if (SDL_OpenAudio(&wanted_spec, NULL) < 0) {
printf("open audio failed\n");
return -1;
}
pPCMFile = fopen(PCM_PATH,"rb");
//开始播放
SDL_PauseAudio(0);
SDL_Delay(60000);