Audio Player
1. Introduction
The Audio Player component is a lightweight audio player designed and implemented for the FreeRTOS system.
Supports playlist management, allowing you to add, delete audio files, and clear the playlist.
Supports multiple playback modes, such as: single song playback, sequential playback, single song loop, playlist loop, random playback, etc.
Supports rich playback control functions, such as: start, stop, pause, resume, previous, next, jump, etc.
Supports volume adjustment function, with a volume range of 0-100.
Supports event callback mechanism, through which you can register event callback functions to obtain player status changes, such as: song start, song finish, song failure, pause, resume, playback progress update, etc.
Supports playing audio files in the local VFS file system, and also supports playing network audio streams.
Metadata parsers, decoders, input sources, and output sinks are added by the customer through registration as needed. Built-in plugins cover common formats (e.g. MP3, WAV, AAC, OPUS, M4A, M3U8, TS) and file source, network source, HLS source, onboard speaker sink, file sink; customers may also implement and register custom plugins.
For API reference of the Audio Player, please refer to:
For example projects of the Audio Player, please refer to:
Important
The Audio Player component and the Player Service component are two independent components that do not depend on each other. The Player Service component is mainly used for playing prompt sounds and does not support playing multiple types of music and playlist management.
The Audio Player is adapted for the VFS file system and does not perform file system mounting and unmounting operations internally. Before playing local music files, the customer needs to mount the file system first.
2. Macro Configuration
Basic function macro configuration:
Kconfig
CPU
Format
Value
CONFIG_AUDIO_PLAYER
AP
bool
y
Memory configuration (choose one):
Kconfig
CPU
Format
Value
CONFIG_AUDIO_PLAYER_USE_SRAM
AP
bool
y/n
CONFIG_AUDIO_PLAYER_USE_PSRAM
AP
bool
y/n
Note
Value meanings:
ymeans must be enabled,y/nmeans choose based on actual needs.Memory configuration must choose one: use
CONFIG_AUDIO_PLAYER_USE_SRAMorCONFIG_AUDIO_PLAYER_USE_PSRAM; PSRAM depends onCONFIG_PSRAM.
3. Built-in Plugins
The component provides the following built-in plugins. Customers obtain the ops table via the corresponding
bk_audio_player_get_*_ops()APIs in the plugin headers and register them withbk_audio_player_register_*.Metadata parsers (for
bk_audio_player_register_metadata_parser):
Format
Get ops API
AAC
bk_audio_player_get_aac_metadata_parser_ops()AMR
bk_audio_player_get_amr_metadata_parser_ops()FLAC
bk_audio_player_get_flac_metadata_parser_ops()M4A
bk_audio_player_get_m4a_metadata_parser_ops()MP3
bk_audio_player_get_mp3_metadata_parser_ops()OGG
bk_audio_player_get_ogg_metadata_parser_ops()Opus
bk_audio_player_get_opus_metadata_parser_ops()WAV
bk_audio_player_get_wav_metadata_parser_ops()Decoders (for
bk_audio_player_register_decoder):
Format
Get ops API
AAC
bk_audio_player_get_aac_decoder_ops()AMR
bk_audio_player_get_amr_decoder_ops()FLAC
bk_audio_player_get_flac_decoder_ops()M4A
bk_audio_player_get_m4a_decoder_ops()MP3
bk_audio_player_get_mp3_decoder_ops()OGG
bk_audio_player_get_ogg_decoder_ops()Opus
bk_audio_player_get_opus_decoder_ops()MPEG-TS
bk_audio_player_get_ts_decoder_ops()WAV
bk_audio_player_get_wav_decoder_ops()Input sources (for
bk_audio_player_register_source):
Type
Get ops API
Local file
bk_audio_player_get_file_source_ops()HLS stream
bk_audio_player_get_hls_source_ops()Network
bk_audio_player_get_net_source_ops()
Important
Local file: Depends on VFS; enable
CONFIG_VFS.HLS stream and Network: Depend on web client; enable
CONFIG_WEBCLIENT.
Output sinks (for
bk_audio_player_register_sink):
Type
Get ops API
File output
bk_audio_player_get_file_sink_ops()Onboard speaker
bk_audio_player_get_onboard_speaker_sink_ops()
Important
File output: Depends on VFS; enable
CONFIG_VFS.Onboard speaker: Depends on ADK raw stream and onboard speaker stream; enable
CONFIG_ADK_RAW_STREAMandCONFIG_ADK_ONBOARD_SPEAKER_STREAM.PA control must be implemented in the sink (e.g. onboard speaker sink or custom sink controlling PA enable/mute pins).
The default onboard speaker sink does not enable PA control; to support PA control, the customer must modify and adapt it (this sink is based on onboard_speaker_stream;
onboard_speaker_stream_cfg_tprovides PA-related configuration options).
4. Usage Examples
Using the typical application scenario of playing an audio file list from an SD card as an example to illustrate the usage flow of the Audio Player component.
Initialize Audio Player
- The process of initializing the Audio Player is as follows:
Define an event callback function to handle player status change events.
Create a player instance and pass configuration (including event callback).
Register metadata parsers, decoders, input sources, and output sinks as needed (using built-in or custom implementations).
Set the playback mode (optional).
Set the volume (optional).
The code example is as follows:
/* 1. Define event callback function */
void player_event_handler(audio_player_event_type_t event, void *extra_info, void *args)
{
switch (event)
{
case AUDIO_PLAYER_EVENT_SONG_START:
LOGI("Song start playing\n");
break;
case AUDIO_PLAYER_EVENT_SONG_FINISH:
LOGI("Song finish playing\n");
break;
case AUDIO_PLAYER_EVENT_SONG_FAILURE:
LOGE("Song play failure\n");
break;
case AUDIO_PLAYER_EVENT_SONG_PAUSE:
LOGI("Song paused\n");
break;
case AUDIO_PLAYER_EVENT_SONG_RESUME:
LOGI("Song resumed\n");
break;
case AUDIO_PLAYER_EVENT_SONG_TICK:
// Handle playback progress update
break;
case AUDIO_PLAYER_EVENT_SEEK_COMPLETE:
{
audio_player_seek_result_t *result = (audio_player_seek_result_t *)extra_info;
if (result && result->status == AUDIO_PLAYER_OK)
{
LOGI("Seek success, target=%d\n", result->second);
}
else
{
LOGE("Seek failed\n");
}
break;
}
default:
break;
}
}
/* 2. Create player instance and get handle */
bk_audio_player_handle_t player_handle = NULL;
bk_audio_player_cfg_t cfg = DEFAULT_AUDIO_PLAYER_CONFIG();
cfg.event_handler = player_event_handler;
cfg.args = NULL; /* User defined parameters, can be NULL */
int ret = bk_audio_player_new(&player_handle, &cfg);
if (ret != AUDIO_PLAYER_OK || player_handle == NULL)
{
LOGE("audio player new fail, ret=%d\n", ret);
return BK_FAIL;
}
/* 3. Register plugins as needed: metadata parsers, decoders, sources, sinks (example: local MP3/WAV to onboard speaker) */
ret = bk_audio_player_register_metadata_parser(player_handle, bk_audio_player_get_mp3_metadata_parser_ops());
if (ret != AUDIO_PLAYER_OK)
{
LOGE("register mp3 metadata parser fail\n");
return BK_FAIL;
}
ret = bk_audio_player_register_metadata_parser(player_handle, bk_audio_player_get_wav_metadata_parser_ops());
if (ret != AUDIO_PLAYER_OK)
{
LOGE("register wav metadata parser fail\n");
return BK_FAIL;
}
ret = bk_audio_player_register_decoder(player_handle, bk_audio_player_get_mp3_decoder_ops());
if (ret != AUDIO_PLAYER_OK)
{
LOGE("register mp3 decoder fail\n");
return BK_FAIL;
}
ret = bk_audio_player_register_decoder(player_handle, bk_audio_player_get_wav_decoder_ops());
if (ret != AUDIO_PLAYER_OK)
{
LOGE("register wav decoder fail\n");
return BK_FAIL;
}
ret = bk_audio_player_register_source(player_handle, bk_audio_player_get_file_source_ops());
if (ret != AUDIO_PLAYER_OK)
{
LOGE("register file source fail\n");
return BK_FAIL;
}
ret = bk_audio_player_register_sink(player_handle, bk_audio_player_get_onboard_speaker_sink_ops());
if (ret != AUDIO_PLAYER_OK)
{
LOGE("register onboard speaker sink fail\n");
return BK_FAIL;
}
/* 4. Set playback mode (optional) */
ret = bk_audio_player_set_play_mode(player_handle, AUDIO_PLAYER_MODE_SEQUENCE_LOOP);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("set play mode fail, ret=%d\n", ret);
return BK_FAIL;
}
/* 5. Set volume (optional) */
ret = bk_audio_player_set_volume(player_handle, 80);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("set volume fail, ret=%d\n", ret);
return BK_FAIL;
}
Note
The
extra_infoofAUDIO_PLAYER_EVENT_SEEK_COMPLETEpoints toaudio_player_seek_result_twhosesecondandstatusfields describe the seek result.For other events,
extra_infomight beNULL; always check before dereferencing.Plugin registration: the example above only registers MP3/WAV metadata parsers and decoders, file source, and onboard speaker sink; register additional plugins as needed for other formats, sources, or sinks.
Add Audio Files to Playlist
- The detailed process is as follows:
Call the add music interface to add audio files to the playlist.
You can call the add interface multiple times to add multiple audio files.
The code example is as follows:
/* Add audio files to playlist */
ret = bk_audio_player_add_music(player_handle, "song1", "/sd0/music/song1.mp3");
if (ret != AUDIO_PLAYER_OK)
{
LOGE("add music fail, ret=%d\n", ret);
return BK_FAIL;
}
ret = bk_audio_player_add_music(player_handle, "song2", "/sd0/music/song2.wav");
if (ret != AUDIO_PLAYER_OK)
{
LOGE("add music fail, ret=%d\n", ret);
return BK_FAIL;
}
ret = bk_audio_player_add_music(player_handle, "song3", "/sd0/music/song3.mp3");
if (ret != AUDIO_PLAYER_OK)
{
LOGE("add music fail, ret=%d\n", ret);
return BK_FAIL;
}
Note
Audio file paths support VFS file system paths, such as SD card paths, Flash file system paths, etc.
Audio file names are user-defined and are used to identify audio files in the playlist.
Start Playback
- The detailed process is as follows:
Call the start interface to start playing audio files in the playlist.
The player will play according to the currently set playback mode.
The code example is as follows:
/* Start playback */
ret = bk_audio_player_start(player_handle);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("player start fail, ret=%d\n", ret);
return BK_FAIL;
}
Playback Control
The player provides rich playback control functions:
The code example is as follows:
/* Pause playback */
ret = bk_audio_player_pause(player_handle);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("player pause fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Resume playback */
ret = bk_audio_player_resume(player_handle);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("player resume fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Play previous song */
ret = bk_audio_player_prev(player_handle);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("player prev fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Play next song */
ret = bk_audio_player_next(player_handle);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("player next fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Jump to specific song (e.g., jump to the 2nd song, index starts from 0) */
ret = bk_audio_player_jumpto(player_handle, 1);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("player jumpto fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Seek to the 60th second of current song (local files only) */
ret = bk_audio_player_seek(player_handle, 60);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("player seek fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Stop playback */
ret = bk_audio_player_stop(player_handle);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("player stop fail, ret=%d\n", ret);
return BK_FAIL;
}
Note
bk_audio_player_seekonly supports local audio files; network or HLS sources return errors.Seeking is asynchronous, and completion is reported via
AUDIO_PLAYER_EVENT_SEEK_COMPLETEwithaudio_player_seek_result_t.
Playlist Management
The player supports dynamic playlist management:
The code example is as follows:
/* Delete music by name */
ret = bk_audio_player_del_music_by_name(player_handle, "song1");
if (ret != AUDIO_PLAYER_OK)
{
LOGE("delete music by name fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Delete music by URI */
ret = bk_audio_player_del_music_by_uri(player_handle, "/sd0/music/song2.wav");
if (ret != AUDIO_PLAYER_OK)
{
LOGE("delete music by uri fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Clear playlist */
ret = bk_audio_player_clear_music_list(player_handle);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("clear music list fail, ret=%d\n", ret);
return BK_FAIL;
}
Note
Deleting the currently playing song will automatically switch to the next song.
Clearing the playlist will stop the current playback.
Retrieve Audio Metadata
Before playback, you can call
bk_audio_player_get_metadata_from_file()to read basic fields (title, artist, bitrate, duration, etc.) from a local audio file using the instance’s registered metadata parsers.
The code example is as follows:
audio_metadata_t metadata;
memset(&metadata, 0, sizeof(metadata));
if (bk_audio_player_get_metadata_from_file(player_handle, "/sd0/music/song1.mp3", &metadata) == 0)
{
LOGI("title=%s, artist=%s, duration=%.1fs\n",
metadata.title, metadata.artist, metadata.duration);
}
else
{
LOGE("parse metadata fail\n");
}
Note
This API only supports local file paths (VFS); network or HTTP URIs are not supported.
Return value 0 means success, while -1/-2/-3/-4 represent open failure, unsupported format, invalid parameter, and file read failure respectively.
Volume Adjustment
The player supports volume adjustment function:
The code example is as follows:
/* Set volume to 50 */
ret = bk_audio_player_set_volume(player_handle, 50);
if (ret != AUDIO_PLAYER_OK)
{
LOGE("set volume fail, ret=%d\n", ret);
return BK_FAIL;
}
/* Get current volume */
int volume = bk_audio_player_get_volume(player_handle);
LOGI("current volume: %d\n", volume);
Note
The volume range is 0-100, where 0 means mute and 100 means maximum volume.
Deinitialize Audio Player
- The process of deinitializing the Audio Player is as follows:
Stop playback (if playing).
Call the deinitialization interface to release player resources.
The code example is as follows:
/* 1. Stop playback (if playing) */
bk_audio_player_stop(player_handle);
/* 2. Destroy player instance */
bk_audio_player_delete(player_handle);
player_handle = NULL;