开源FFMpeg(五)——使用SDL进行音频播放下(使用篇)

前言

在之前的博客中,已经对于FFmpeg的介绍、编译、拉流、解码等做了详细的介绍。现在紧跟着上一篇博客,在之前的拉流编解码后,使用SDL进行播放。

具体对于SDL的介绍与编译请查看上一篇博客

一、SDLAPI介绍

1.初始化子系统

int SDL_Init(Uint32 flags);

flags值可以是以下几种或者一起:

SDL_INIT_TIMER: 定时器子系统

SDL_INIT_AUDIO: 音频子系统

SDL_INIT_VIDEO:视频子系统;自动初始化事件子系统

SDL_INIT_JOYSTICK:操纵杆子系统;自动初始化事件子系统

SDL_INIT_HAPTIC:触觉(力反馈)子系统

SDL_INIT_GAMECONTROLLER:控制器子系统;自动初始化操纵杆子系统

SDL_INIT_EVENTS: 事件子系统

SDL_INIT_EVERYTHING: 以上所有子系统

SDL_INIT_NOPARACHUTE:兼容性;该标志被忽略

return:成功时返回 0,失败时返回负错误代码;调用SDL_GetError () 获取更多信息。

备注:在子系统使用结束后,需要调用SDL_Quit () 以关闭

2.打开音频设备

int SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained);

参数:

desired:表示所需输出格式的SDL_AudioSpec结构。有关如何准备此结构的详细信息,请参阅SDL_OpenAudioDevice文档。

obtained: 用实际参数填充的SDL_AudioSpec结构,或 NULL。

return:如果成功则返回 0,将实际的硬件参数放入 指向的结构中obtained。

备注:更强大的方法是使用SDL_OpenAudioDevice (),指定使用设备

3.SDL_AudioSpec 结构体

包含音频输出格式的结构。它还包含在音频设备需要更多数据时调用的回调。

其中

  1. 音频数据格式参数值如下:

2.支持的通道数如下

SDL2.0以后可以支持的值为 1(单声道)、2(立体声)、4(四声道)和 6 (5.1)

3.回调函数模型如下

void SDL_AudioCallback(void* userdata, Uint8* stream, int len)

4.样本中的音频缓冲区大小

由于本例子中播放的是MP3,MP3一帧数据大小为1152采样,所以该值为1152

4.暂停音频设备

void SDL_PauseAudio(int pause_on);

参数:非零暂停,0取消暂停

备注:一般是传入1代表暂停

二、使用实例

1.粗浅设计

播放的基础是建立在正确拉流、并进行编解码的基础之上,所以下面的代码是对之前的例子的修改和补充。关于拉流、解码的API就不进行过多的介绍了。

整体的设计结构如下图:

整体对外接口

bool StartPlay(const char* pAudioFilePath);
bool StopPlay();
bool PausePlay();
bool ResumePlay();

分别对应开始播放、暂停播放、恢复播放、停止播放。

2.头文件

代码如下:

#pragma once

extern "C" {
#include "include/libavformat/avformat.h"
#include "include/libavcodec/avcodec.h"
#include "include/libavutil/avutil.h"
#include "include/libswresample/swresample.h"
}

#include "SDL.h"
#include <iostream>
#include <mutex>
#include <Windows.h> 
#include <vector>

namespace AudioReadFrame
{

#define MAX_AUDIO_FRAME_SIZE	192000 // 1 second of 48khz 16bit audio 2 channel
#define MAX_CACHE_BUFFER_SIZE	50*1024*1024 // 5M

	//自定义结构体存储信息
	struct FileAudioInst
	{
		long long duration;    ///< second
		long long curl_time;   ///< second
		int sample_rate;       ///< samples per second
		int channels;          ///< number of audio channels
		FileAudioInst()
		{
			duration = 0;
			curl_time = 0;
			sample_rate = 0;
			channels = 0;
		}
	};

	//拉流线程状态
	enum ThreadState
	{
		eRun = 1,
		eExit,
	};

	enum PlaySate
	{
		ePlay = 1,
		ePause,
		eStop
	};

	struct CircleBuffer
	{
		CircleBuffer() : dataBegin(0), dataEnd(0), buffLen_(0) {}

		uint32_t						buffLen_;
		uint32_t						dataBegin;
		uint32_t						dataEnd;
		std::vector<uint8_t>			decodeBuffer_;
	};

	class CAudioReadFrame
	{
	public:
		CAudioReadFrame();
		~CAudioReadFrame();

	public:
		
		bool StartPlay(const char* pAudioFilePath);

		bool StopPlay();

		bool PausePlay();
		 
		bool ResumePlay();

	private:
		//加载流文件
		bool LoadAudioFile(const char* pAudioFilePath);
		//开始读流
		bool StartReadFile();
		//停止读流
		bool StopReadFile();
		//释放资源
		bool FreeResources();
		//改变拉流线程的装填
		void ChangeThreadState(ThreadState eThreadState);
		//拉流线程
		void ReadFrameThread
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值