SkylarkOS 播放器使用指南

优质
小牛编辑
131浏览
2023-12-01

我们提供的播放器,统称为gplayer。内部分两个播放器,一个叫:audiotrack,一个叫:mediaplayer。

  • audiotrack,用来播放裸的pcm音频数据,使用前前先调用专门的接口设置采样率,声道数,比特位。比如:打电话播放

  • mediaplayer,用来播放本地音频或者在线音频,支持的格式依赖内部编译的ffmpeg,大家可以自己查看编译的ffmpeg选项,自己增加支持的音频格式

我们提供了使用的例子,参考:/middleware/gplayer/sample/

编译指南

在openwrt的编译配置下,选择上libaudiotrack和libmediaplayer

audiotrack接口使用说明

AudioTrack 只支持播放pcm数据

C++接口:

  • AudioTrack

    • AudioTrack(unsigned int sampleRateInHz, unsigned int channels, PcmFormat format, unsigned int bufferSizeInBytes)
    • AudioTrack(const char* device, unsigned int sampleRateInHz, unsigned int channels, PcmFormat format, unsigned int bufferSizeInBytes) 构造AudioTrack,需要指定pcm数据的采样率,通道数,数据格式和缓冲区大小.device是指定alsa的pcm设备
  • ~AudioTrack

    • ~AudioTrack() 析构AudioTrack
  • play

    • void play() 进入播放状态
  • write

    • long write(const void* buffer, unsigned int size) 填写pcm数据
  • stop

    • void stop() 停止播放并释放相关资源
  • pause

    • void pause() 暂停播放,可以通过play接口继续播放
  • flush

    • void flush() 丢弃缓冲区的数据
  • getMinBufferSize

    • unsigned int getMinBufferSize(unsigned int sampleRateInHz, unsigned int channels, PcmFormat format) 获取缓冲区最小的空间要求
  • setVolume

    • int setVolume(int volume) 设置当前音量,范围为 0-100
  • getVolume

    • int getVolume(void) 获取当前音量

C接口

  • void AudioTrackInit(const char device, unsigned int sampleRateInHz, unsigned int channels,

             PcmFormat format, unsigned int bufferSizeInBytes);
    

    初始化AudioTrack,获取相应的句柄.当不需要指定音频设备时device设置为NULL

  • void AudioTrackDeinit(void *aHandle); 释放AudioTrack相关的资源,需要传入相应的句柄.

其余C接口与C++类似,可以参考上面的描述

MediaPlayer


MediaPlayer作为统一接口层,封装了GPlayer和SimplePlayer,实现自动选择合适的player .GPlayer主要用于网络流媒体音频播放,SimplePlayer主要用于本地文件播放.

目录结构


  • docs

用户使用文档

  • include

开放头文件

  • sample

示例代码

  • src

源代码

状态图


MediaPlayer 使用状态机控制整个播放过程。用户可以调用公开接口触发状态变化,然后 MediaPlayer 会调用回调接口通知用户当前的状态。 因此用户在初始化阶段需要注册回调函数用于接收状态变化事件进而操作 MediaPlayer。 下图所示为MediaPlayer 的状态变化图。椭圆代表了 MediaPlayer 的状态,其中实线椭圆代表MediaPlayer 变化到当前状态时会触发回调通用用户。箭头代表用户可以调用这些方法触发状态变化。

  • Idle state 当创建 MediaPlayer 或 MediaPlayer 被 stop() 后,MediaPlayer 处于空闲状态。在该状态下,不建议使用 get 或者 set 相关的接口。而且强烈建议用户在初始化 MediaPlayer 后调用 setListener() 注册回调函数。

  • Prepared state 当prepare() 或者 prepareAsync() 被调用后,MediaPlayer 完成内部资源和线程的初始化后会进入 Prepared 状态。其中 Ffmpeg 和 SDL 相关的初始化比较耗时。如果初始化成功,MediaPlayer 会通过回调函数上报 MEDIA_PREPARED事件,否则会上报 MEDIA_ERROR 事件。需要注意的是调用 prepare() 之前必须调用 setDataSource() 设置需要播放的资源路径,否则 MediaPlayer 会通过回调函数上报 MEDIA_ERROR 事件。

  • Playing state 当用户收到 MEDIA_PREPARED 后,可以调用 start() 播放音频。在播放过程中用户也可以调用 seekTo() 查找某个位置进行播放,查找完成后 MediaPlayer 会发送 MEDIA_SEEK_COMPLETE 事件。

  • Buffer Underrun state 在弱网情况下,MediaPlayer 会发送 MEDIA_BUFFERING_UPDATE 事件用于表明没有 buffer 可以用来播放。

  • Paused state 当用户调用 pause() 函数后,MediaPlayer 会进入暂停状态,音频会相应的暂停。resume() 函数可用于恢复音频播放。需要注意的是,播放状态和暂停状态之间的实质切换可能并不是完全同步的,可能需要100ms左右的延时。

  • Playback Complete state 当音频播放完成后,MediaPlayer 会发送 MEDIA_PLAYBACK_COMPLETE 事件,此时用户也可通过 seekTo() 查找某个位置继续播放。

  • Stopped state 用户可通过 stop() 和 stopAsync() 停止音频播放,其中 stopAsync() 在完成停止后 MediaPlayer 会发送 MEDIA_STOPPED 事件。

  • End ~MediaPlayer() 被调用后,之前分配的资源会被全部释放。

多媒体事件


基于MediaPlayer实现的播放器需要根据以下事件切换工作流程。

  • MEDIA_PREPARED

准备完成状态

  • MEDIA_PLAYBACK_COMPLETE

播放完成状态

  • MEDIA_BUFFERING_UPDATE

没有buffer可以用来播放

  • MEDIA_SEEK_COMPLETE

位置查找完成,设备处于播放状态

  • MEDIA_STOPPED

停止状态

  • MEDIA_ERROR

错误状态

C++ Public Method


  • MediaPlayer

    • MediaPlayer()
    • MediaPlayer(const char *device) 构造 MediaPlayer,其中 device 参数用于指定alsa使用的pcm设备。
  • ~MediaPlayer

    • ~MediaPlayer() 析构 MediaPlayer。
  • prepare

    • status_t prepare()
    • status_t prepareAsync() 初始化 GPlayer或者SimplePlayer 资源,完成后上报 MEDIA_PREPARED 事件。
  • setDataSource

    • status_t setDataSource(const char *url)
    • status_t setDataSourceRead(MediaPlayerReadBuffer callback, void *arg)
    • status_t setDataSourceWrite(unsigned int bufferSizeInBytes) 通过setDataSource设置需要播放的音频路径。 当需要使用回调流式播放时可以选用setDataSourceRead,需要传入回调函数和所需的参数。 当需要使用直写流式播放时可以选用setDataSourceWrite,需要传入缓冲区的大小。
  • start

    • status_t start() 启动音频播放。
  • pause

    • status_t pause() 暂停音频播放。
  • resume

    • status_t resume() 恢复音频播放。
  • stop

    • status_t stop()
    • status_t stopAsync() 停止音频播放并释放资源和关闭子线程。需要注意的是只有 stopAsync() 函数在完成后会上报 MEDIA_STOPPED 事件。
  • seekTo

    • status_t seekTo(int msec)
    • status_t seekToBytes(long bytes) 指定播放位置。MediaPlayer 完成位置位置查找后会上报MEDIA_SEEK_COMPLETE 事件。
  • write

    • status_t write(const void* buffer, unsigned int size) 调用setDataSourceWrite后使用write写入需要播放的压缩数据,具体用法参考media_demo。 需要注意的是prepare之前需要write一定量的数据才能正常执行。
  • writeDone
    • status_t writeDone() 通知MediaPlayer已经写完所有数据
  • class MediaPlayerListener
class MediaPlayerListener
{
    public:
    virtual void notify(int msg, int ext1, int ext2, int fromThread) = 0;
};

回调函数基类 MediaPlayerListener。

  • setListener

    • status_t setListener(MediaPlayerListener *listener) 注册回调函数 MediaPlayerListener.。
  • getListener

    • MediaPlayerListener * getListener() 获取回调函数 MediaPlayerListener 指针。
  • setLooping

    • status_t setLooping(int loop) 设置循环播放模式,<=0代表非循环模式,>0代表循环播放模式。
  • isLooping

    • bool isLooping() 判断当前是否处在循环播放模式。
  • isPlaying

    • bool isPlaying() 判断当前是否在播放。
  • getCurrentPosition

    • long getCurrentBytesPosition()
    • long getCurrentPosition() 获取当前位置,getCurrentBytesPosition单位byte,getCurrentPosition单位ms。
  • getDuration

    • long getDuration(void) 获取当前播放音频的时长,单位为 ms。
  • setVolume

    • status_t setVolume(int volume) 设置当前音量,范围为 0-100。
  • getVolume

    • int getVolume(void) 获取当前音量。
  • enableDnsParse

    • status_t enableDnsParse(bool enabled) 选择是是否开启dns解析,开启后播放网络流能加快速度。
  • setCacheMode

    • setCacheMode(double cacheDuration, bool enabled) 设置GPlayer音频队列所需的cache大小,cacheDuration单位s,默认为1.0。
  • notify
    • void notify(int msg, int ext1, int ext, int fromThread) 将会调用MediaPlayerListener的notify接口。

C Public Method

  • void MediaPlayerInit(const char device) 初始化MediaPlayer,获取相应的句柄.当不需要指定音频设备时device设置为NULL

  • void MediaPlayerDeinit(void *mHandle) 释放MediaPlayer相关的资源,需要传入对应的句柄

  • status_t MediaPlayerSetNotify(void *mHandle, MediaPlayerNotify notify) 设置notify回调函数,MediaPlayer会调用该回调通知应用播放器状态发生改变

其余C接口与C++类似,可以参考上面的描述