Media Player API#
The media player API is called within the scope of the oasis::ui namespace.
The media player can receive events such as progress status or errors occurring during playback through a user-defined observer object derived from MediaObserver.
Header File#
OasisPlayer.h
Functions#
The key-value map required for creating the Player is as follows:
createAudioDevice. If not specified, audio will not be output.channel<N>-rotation key value.The key-value map values for each video track are prefixed with channel<N>- before each key name. <N> starts from 1 and increases by 1.
channel<N>-render-recording-path.channel<N>-render-enable-recording is "1". The recording file extension supports only mp4. If it is not mp4, it will not record.createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
createPlayer.
createPlayer.
- true: Operating.
- false: Stopped state.
createPlayer.
- true: Playing.
- false: Playback paused state.
createPlayer.
- true: Playback paused state.
- false: Not in playback paused state. Playing.
createPlayer.
Refer to the Structures section below for the MediaTrackInfo definition.
createPlayer.
nullptr if it does not exist.
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
true, and the video is not shown if false.
- 0: Success
- -1: Failure
- true: The specified video track is in a visible state.
- false: The specified video track is in an invisible state.
createPlayer.
- 0: Success
- -1: Failure
createPlayer.
- 0: Success
- -1: Failure
Structures#
Example#
Below is an example of a media player that plays a single video track of a recording file.
Initializes Oasis.
#define OFFS_QUEUE_SIZE_KBYTES (40*1024)
#define OFFS_CACHE_SIZE_KBYTES (1024)
#define MEDIA_CACHE_SIZE_KBYTES (40*1024)
oasis::key_value_map_t parameters;
parameters["offs-qsize-max"] = std::to_string(OFFS_QUEUE_SIZE_KBYTES);
parameters["offs-overwrite-if-exist"] = "1";
parameters["offs-cache-size"] = std::to_string(OFFS_CACHE_SIZE_KBYTES);
parameters["media-cache-size"] = std::to_string(MEDIA_CACHE_SIZE_KBYTES);
if(oasis::initialize(parameters) < 0) {
DLOG(DLOG_ERROR, "Oasis init failed\n");
return -1;
}
Initializes the audio output (sink) device.
parameters.clear();
#if 0
#define SND_PATH "default"
#else
#define SND_PATH "hw:0,0"
#endif
parameters["types"]="sink";
parameters["path"]=SND_PATH;
parameters["always-on"]="0";
parameters["aec-disabled"]="1";
parameters["denoise-enabled"]="1";
parameters["snd-input-channels"]="2";
parameters["snd-input-sample-size"]="16";
parameters["snd-input-sampling-duration-msec"]="40";
parameters["snd-input-sampling-rate"]="48000";
createAudioDevice(parameters);
Initializes the display device.
parameters.clear();
parameters["memory-type"] = "ion"; //cma
parameters["screen-width"] = "480";
parameters["screen-height"] = "320";
display::setup(parameters);
Configures the GUI. In this example, touch is not used.
parameters.clear();
parameters["system-font-size"] = "10";
parameters["system-font-path"] = "/mnt/sd/consola.ttf";
parameters["display-rotation"] = "0";
parameters["enable-touch"] = "0";
err = ui::setup(parameters);
if (err < 0) {
DLOG(DLOG_ERROR, "Oasis ui::setup failed\n");
return -1;
}
Initializes the media player.
parameters.clear();
// Obtains the default screen object and applies its width and height to the media player.
ui::ScreenRef screen = ui::getDefaultScreen();
int32_t screen_width = ui::screenWidth(screen);
int32_t screen_height = ui::screenHeight(screen);
// Creates a user-defined object derived from MediaObserver.
std::shared_ptr<MyPlayingObserver> observer = std::make_shared<MyPlayingObserver>();
// If necessary, specify rotation and snd-path as well.
// snd-path must be the device path specified during audio device creation.
parameters["rotation"] = std::to_string(rotation);
parameters["snd-path"] = SND_PATH;
parameters["channel-count"] = "1";
parameters["primary-channel"] = "1";
// Even if track-id is '0' and the actual file's first track ID is '1', they are allocated sequentially.
parameters["channel1-track-id"] = "0";
parameters["channel1-visible"] = "1";
parameters["channel1-rotation"] = std::to_string(rotation);
// Configures the playback screen to full screen.
parameters["channel1-x"] = "0";
parameters["channel1-y"] = "0";
parameters["channel1-width"] = std::to_string(screen_width);
parameters["channel1-height"] = std::to_string(screen_height);
parameters["channel1-zorder"] = "0";
ui::PlayerRef player = ui::createPlayer(0, parameters);
// setup the player object
observer->player_ = player;
Configures the screen layout. A Fixed layout container is used inside the top-level Window object, and the playback screen is set to full screen.
ui::WindowRef player_panel = ui::createWindow("Player1");
ui::FixedRef fixed_layout = ui::createFixed();
ui::containerAdd(player_panel, fixed_layout);
ui::setFixedSize(player, screen_width, screen_height);
ui::fixedPut(fixed_layout, player, 0, 0);
ui::screenAdd(screen, player_panel);
ui::setVisible(player_panel, true);
Starts playback.
err = ui::playerStart(player, file_path, observer, nullptr);
// Obtains track information.
std::vector<MediaTrackInfo> tracks;
ui::playerGetVideoTracks(player, tracks);
An example of seeking the playback position forward by 10 seconds during playback:
if (ui::playerIsPlaying(player) || ui::playerIsPaused(player)) {
int64_t duration = ui::playerGetDuraitonUs(player);
int64_t timestamp = ui::playerGetCurrentTimestampUs(player);
timestamp += 10*1000000ll;
if(timestamp > duration-10*1000000ll) {
timestamp = duration-10*1000000ll;
}
if(timestamp < 0) {
timestamp = 0ll;
}
err = ui::playerSeek(player, timestamp);
}
An example of modifying the screen position and size during playback:
ui::playerSetRect(player, track_id, 100, 100, 320, 240)
Stops playback.
ui::playerStop(player);
Below is the complete code:
#include "OasisAPI.h"
#include "OasisLog.h"
#include "OasisMedia.h"
#include "OasisUI.h"
#include "OasisFS.h"
#include "OasisUtil.h"
#include "OasisDisplay.h"
#include "OasisInference.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <thread>
#include <mutex>
#include <memory>
#include <condition_variable>
using namespace oasis;
#define OFFS_QUEUE_SIZE_KBYTES (40*1024)
#define OFFS_CACHE_SIZE_KBYTES (1024)
#define OFFS_WRITE_ALIGNMENT_BYTES 8192
#define MEDIA_CACHE_SIZE_KBYTES (40*1024)
static bool continue_playing = true;
void cancel_handler(int signum)
{
continue_playing = false;
}
class MyPlayingObserver : public MediaObserver {
public:
virtual void onStarted(void *user_data, const char *file_path) {
fprintf(stdout, "Playing started, file path \"%s\"\n", file_path);
}
virtual void onStopped(void *user_data, media_report_reason_t reason, void *details) {
fprintf(stdout, "Playing stopped, reason: %d\n", reason);
continue_playing = false;
}
virtual void onFileChanged(void *user_data, const char *new_file_path) {}
virtual void onError(void *user_data, media_report_reason_t reason, void *details) {
fprintf(stdout, "Playing error, reason: %d (%s)\n", reason, mediaReportReasonString(reason));
continue_playing = false;
}
virtual void onInfo(void *user_data, MediaInfo *info) {
int h, m, s, u;
parseUsec(info->durationUs, h, m, s, u);
int h1, m1, s1, u1;
parseUsec(info->currentTimestampUs, h1, m1, s1, u1);
fprintf(stdout, "\rPlaying duration %02d:%02d:%02d.%06d, current %02d:%02d:%02d.%06d ", h, m, s, u, h1, m1, s1, u1);
fflush(stdout);
}
virtual void onPaused(void *user_data, MediaInfo *info) {
fprintf(stdout, "Paused duration %lld usec, current %lld usec\n", info->durationUs, info->currentTimestampUs);
}
virtual void onResumed(void *user_data, MediaInfo *info) {
fprintf(stdout, "Resumed duration %lld usec, current %lld usec\n", info->durationUs, info->currentTimestampUs);
}
ui::PlayerRef player_;
};
static bool isFile(const char *path)
{
struct stat path_stat;
stat(path, &path_stat);
return S_ISREG(path_stat.st_mode);
}
void printUsage(const char *pgname)
{
fprintf(stderr, "USAGE: %s [-r <rotation. 90, 270>] <mp4 or avi file-path>\n", pgname);
}
int main(int argc, char *argv[])
{
int32_t err;
int c;
int32_t rotation = 0;
std::vector<MediaTrackInfo> tracks;
bool is_playing = false;
int32_t track_id = -1;
opterr = 0;
while ((c = getopt(argc, argv, "r:h")) != -1) {
switch (c) {
case 'r':
if(optarg == nullptr) {
fprintf(stderr, "error: bad option argument '%c'\n", optopt);
return -1;
}
rotation = atoi(optarg);
if(rotation != 0 && rotation != 90 /*&& rotation != 180*/ && rotation != 270) {
fprintf(stderr, "bad rotation: %d\n", rotation);
return -1;
}
break;
case 'h':
default:
printUsage(argv[0]);
return -1;
}
}
if(argc-optind < 1) {
fprintf(stderr, "error: invalid or insufficient arguments (%d, %d)\n", argc, optind);
printUsage(argv[0]);
return -1;
}
if (access(argv[optind], F_OK) != 0) {
fprintf(stderr, "\"%s\" not found\n", argv[optind]);
return -1;
}
std::string file_path = argv[optind];
if(!isFile(dir_path.c_str())) {
fprintf(stderr, "\"%s\" not type of file\n", argv[optind]);
return -1;
}
signal(SIGINT, cancel_handler);
oasis::key_value_map_t parameters;
////////////////////////////////////////////////////////////////////////////////////////////
// init
parameters["offs-qsize-max"] = std::to_string(OFFS_QUEUE_SIZE_KBYTES);
parameters["offs-overwrite-if-exist"] = "1";
parameters["offs-cache-size"] = std::to_string(OFFS_CACHE_SIZE_KBYTES);
parameters["media-cache-size"] = std::to_string(MEDIA_CACHE_SIZE_KBYTES);
if(oasis::initialize(parameters) < 0) {
DLOG(DLOG_ERROR, "Oasis init failed\n");
return -1;
}
////////////////////////////////////////////////////////////////////////////////////////////
// audio
parameters.clear();
#if 0
#define SND_PATH "default"
#else
#define SND_PATH "hw:0,0"
#endif
parameters["types"]="sink";
parameters["path"]=SND_PATH;
parameters["always-on"]="0";
parameters["aec-disabled"]="1";
parameters["denoise-enabled"]="1";
parameters["snd-input-channels"]="2";
parameters["snd-input-sample-size"]="16";
parameters["snd-input-sampling-duration-msec"]="40";
parameters["snd-input-sampling-rate"]="48000";
createAudioDevice(parameters);
////////////////////////////////////////////////////////////////////////////////////////////
// display setup
parameters.clear();
parameters["memory-type"] = "ion"; //cma
parameters["screen-width"] = "480";
parameters["screen-height"] = "320";
display::setup(parameters);
//////////////////////////////////////////////////////////////////////////////////////////
// ui setup
parameters.clear();
parameters["system-font-size"] = "10";
parameters["system-font-path"] = "/mnt/sd/consola.ttf";
parameters["display-rotation"] = "0";
parameters["enable-touch"] = "0";
err = ui::setup(parameters);
if (err < 0) {
DLOG(DLOG_ERROR, "Oasis ui::setup failed\n");
return -1;
}
ui::ScreenRef screen = ui::getDefaultScreen();
int32_t screen_width = ui::screenWidth(screen);
int32_t screen_height = ui::screenHeight(screen);
//////////////////////////////////////////////////////////////////////////////////////////
parameters.clear();
parameters["rotation"] = std::to_string(rotation);
/////////////////////////////////////////////////////////////////////////
//player_panel
ui::WindowRef player_panel = ui::createWindow("Player1");
ui::FixedRef fixed_layout = ui::createFixed();
ui::containerAdd(player_panel, fixed_layout);
std::shared_ptr<MyPlayingObserver> observer = std::make_shared<MyPlayingObserver>();
parameters["snd-path"] = SND_PATH;
parameters["channel-count"] = "1";
parameters["primary-channel"] = "1";
parameters["channel1-track-id"] = "0";
parameters["channel1-visible"] = "1";
parameters["channel1-rotation"] = std::to_string(rotation);
parameters["channel1-x"] = "0";
parameters["channel1-y"] = "0";
parameters["channel1-width"] = std::to_string(screen_width);
parameters["channel1-height"] = std::to_string(screen_height);
parameters["channel1-zorder"] = "0";
ui::PlayerRef player = ui::createPlayer(0, parameters);
//setup the player object
observer->player_ = player;
ui::setFixedSize(player, screen_width, screen_height);
ui::fixedPut(fixed_layout, player, 0, 0);
ui::screenAdd(screen, player_panel);
ui::setVisible(player_panel, true);
err = ui::playerStart(player, file_path.c_str(), observer, nullptr);
if(err != 0) {
fprintf(stderr, "\"%s\" failed to play!\n", file_path.c_str());
} else {
is_playing = true;
ui::playerGetVideoTracks(player, tracks);
if(tracks.size() > 0) {
track_id = tracks[0].id;
}
fprintf(stdout, "video track count %d, 1st track id %d\n", tracks.size(), track_id);
}
do {
usleep(100000);
} while (continue_playing);
if(is_playing) {
ui::playerStop(player);
}
err = ui::cleanup();
oasis::finalize();
return 0;
}