영상 재생 API¶
미디어 플레이어 API는 oasis::ui 네임스페이스 범주에서 호출됩니다.
미디어 플레이어는 MediaObserver로 유도된 사용자 정의 observer 객체를 통하여 진행 상황이나 재생중 발생하는 오류 등의 이벤트를 받을 수 있습니다.
헤더 파일¶
OasisPlayer.h
함수¶
PlayerRef
createPlayer
(
int32_t
display_id
,
key_value_map_t &
parameters
)
OasisPlayer.h
Player 객체를 생성합니다.
매개변수
display_id
영상이 보여질 Dispaly ID를 지정합니다. "0" 값을 지정합니다.
parameters
Player 생성에 필요한 key-value map을 지정합니다.
리턴값
성공하면 Player 객체를 리턴하고, 실패하면 nullptr를 리턴합니다.
Player 생성에 필요한 key-value map은 아래와 같습니다.
키
기본값
필수
설명
snd-path
○
createAudioDevice에서 설정한 오디오 장치 경로입니다. 지정하지 않으면 소리가 출력되지 않습니다.
rotation
0
영상 회전 각도를 지정합니다. 0, 90, 270, 180 값중 하나를 지정합니다. 일괄적으로 회전을 지정할 경우 사용되며, channel<N>-rotation 키값으로 개별 영상 트랙의 회전 각도를 지정할 수 있습니다.
channel-count
○
재생 파일의 영상 트랙 개수입니다.
primary-channel
○
주 채널 번호를 지정합니다. 시작번호는 1입니다.
각 영상 트랙에 대한 key-value map 값은 각 키값 앞에 prefix로 channel<N>- 이 붙습니다. <N>은 1부터 시작하여 1씩 증가합니다.
키
기본값
필수
설명
channel<N>-track-id
○
재생 파일 영상의 트랙 순번입니다. AVI 파일의 경우, 0번 부터 시작되며, MP4 파일의 경우, 1번 부터 시작됩니다. 어느 경우든 순차적으로 영상 트랙이 지정됩니다.
channel<N>-visible
1
"1" 값이면 재생시 영상이 보이고, "0" 값이면 영상을 숨깁니다.
channel<N>-rotation
0
영상 회전 각도를 지정합니다. 0, 90, 270, 180 중 한 값을 지정합니다.
channel<N>-x
○
영상 화면의 좌측상단 x 좌표입니다. 디스플레이 영역에서 벗어나면 짤려서 보입니다.
channel<N>-y
○
영상 화면의 좌측상단 y 좌표입니다. 디스플레이 영역에서 벗어나면 짤려서 보입니다.
channel<N>-width
○
영상 화면의 너비입니다. 디스플레이 영역에서 벗어나면 짤려서 보입니다.
channel<N>-height
○
영상 화면의 높이입니다. 디스플레이 영역에서 벗어나면 짤려서 보입니다.
channel<N>-zorder
0
영상이 보이는 순서입니다. 높을 값일 수록 위에서 보입니다.
channel<N>-enable-adas
0
재생 시 ADAS를 적용할지 지정합니다. "1" 이면 ADAS를 적용합니다.
channel<N>-adas-inference-model-names
ADAS에 적용될 추론 모델이름 목록을 지정합니다. 목록은 콤마(,)로 분리된 문자열입니다. 추론 모델이 추론 엔진에 없을 경우, ADAS는 적용되지 않습니다.
channel<N>-render-enable-recording
0
재생 중 화면에 보여지는 영상을 녹화할지 지정합니다. "1" 이면 channel<N>-render-recording-path에 지정된 경로에 녹화 영상을 저장합니다.
channel<N>-render-recording-path
channel<N>-render-enable-recording가 "1"일 경우, 녹화 영상이 저장될 경로입니다. 녹화 파일 확장자는 mp4만 지원합니다. mp4가 아닐 경우, 녹화하지 않습니다.
int32_t
destroyPlayer
(
const PlayerRef &
player
)
OasisPlayer.h
Player를 해제합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerStart
(
const PlayerRef &
player
,
const char *
filepath
,
const std::shared_ptr<MediaObserver> &
observer
,
void *
user_data
)
OasisPlayer.h
재생을 시작합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
filepath
AVI 파일이나 MP4 파일 경로입니다.
observer
재생시 발생한 이벤트를 받을 MediaObserver에서 유도된 사용자 정의 observer 객체입니다.
user_data
observer의 user_data 매개변수로 전달된 사용자 정의 데이터입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerStop
(
const PlayerRef &
player
)
OasisPlayer.h
재생을 중지합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerResume
(
const PlayerRef &
player
)
OasisPlayer.h
재생을 재시작합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerPause
(
const PlayerRef &
player
)
OasisPlayer.h
재생을 일시 멈춥니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerSeek
(
const PlayerRef &
player
,
int64_t
timestampUs
)
OasisPlayer.h
재생 시 특정 위치로 이동합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
timestampUs
특정 위치의 timestamp 입니다. 마이크로초 단위입니다.
리턴값
- 0: 성공
- -1: 실패
int64_t
playerGetDuraitonUs
(
const PlayerRef &
player
)
OasisPlayer.h
총 재생 시간를 리턴합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
총 재생 시간 입니다. 마이크로초 단위입니다.
int64_t
playerGetCurrentTimestampUs
(
const PlayerRef &
player
)
OasisPlayer.h
현재 재생 timestmap를 리턴합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
현재 재생 timestamp 입니다. 마이크로초 단위입니다.
bool
playerIsRunning
(
const PlayerRef &
player
)
OasisPlayer.h
미디어플레이어가 동작 상태인지 확인합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
- true: 동작 중입니다.
- false: 중지 상태입니다.
bool
playerIsPlaying
(
const PlayerRef &
player
)
OasisPlayer.h
미디어플레이가 재생 중인지 확인합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
- true: 재생 중입니다.
- false: 재생 멈춤 상태입니다.
bool
playerIsPaused
(
const PlayerRef &
player
)
OasisPlayer.h
미디어플레이어가 현재 멈춤 상태인지 확인합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
리턴값
- true: 재생 멈춤 상태니다.
- false: 재생 멈춤 상태가 아닙니다. 재생 중입니다.
int32_t
playerGetVideoTracks
(
const PlayerRef &
player
,
std::vector<MediaTrackInfo> &
video_tracks
)
OasisPlayer.h
영상 트랙 목록을 리턴합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
video_tracks
OUT
트랙 정보 목록입니다.
리턴값
트랙 개수를 리턴합니다. 영상 트랙이 없으면 0을 리턴합니다. 오류가 발생하면 -1을 리턴합니다.
MediaTrackInfo 정의는 아래 구조체 부분을 참고합니다.
MediaSourceRef
playerGetVideoTrackSource
(
const PlayerRef &
player
,
int32_t
track_id
)
OasisPlayer.h
영상 트랙의 MediaSource를 리턴합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다. AVI는 0번부터, MP4는 1번부터 순차적으로 증가합니다.
리턴값
영상 트랙이 있을 경우, MediaSource 객체를 리턴하고, 없을 경우 nullptr을 리턴합니다.
int32_t
playerAlign
(
const PlayerRef &
player
,
int32_t
track_id
,
PositionType
horz_position
,
PositionType
vert_position
)
OasisPlayer.h
영상 트랙이 보여질 위치를 변경합니다. 크기는 그대로 유지됩니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
horz_position
수평 위치를 지정합니다. left, center, right 중 하나 값을 지정합니다.
vert_position
수직 위치를 지정합니다. top, vcenter, bottom 중 하나 값을 지정합니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerSetPos
(
const PlayerRef &
player
,
int32_t
track_id
,
int32_t
x
,
int32_t
y
)
OasisPlayer.h
영상 트랙의 위치를 변경합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
x
영상 트랙의 x좌표입니다.
y
영상 트랙의 y좌표입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerSetSize
(
const PlayerRef &
player
,
int32_t
track_id
,
int32_t
width
,
int32_t
height
)
OasisPlayer.h
영상 트랙의 크기를 지정합니다. Display 크기를 벗어날 경우, 짤려서 보여집니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
width
영상 트랙의 가로 크기입니다.
height
영상 트랙의 세로 크기입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerSetRect
(
const PlayerRef &
player
,
int32_t
track_id
,
int32_t
left
,
int32_t
top
,
int32_t
width
,
int32_t
height
)
OasisPlayer.h
영상 트랙의 위치와 크기를 지정합니다. Display 크기를 벗어날 경우, 짤려서 보여집니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
left
영상 트랙의 x좌표입니다.
top
영상 트랙의 y좌표입니다.
width
영상 트랙의 가로 크기입니다.
height
영상 트랙의 세로 크기입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerSetZOrder
(
const PlayerRef &
player
,
int32_t
track_id
,
int32_t
zorder
)
OasisPlayer.h
영상 트랙이 보여질 순서를 지정합니다. 값이 큰 영상이 앞에 보여집니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
zorder
영상 트랙의 순서입니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerSetVisible
(
const PlayerRef &
player
,
int32_t
track_id
,
bool
show
)
OasisPlayer.h
영상이 보여질 지를 지정합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
show
true이면 영상이 보여지고, false이면 영상을 보여지지 않습니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerIsVisible
(
const PlayerRef &
player
,
int32_t
track_id
)
OasisPlayer.h
영상 트랙이 현재 보여지는지 확인합니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
리턴값
- true: 지정한 영상 트랙이 보이는 상태입니다.
- false: 지정한 영상 트랙이 보이지 않는 상태입니다.
int32_t
playerSetRotation
(
const PlayerRef &
player
,
int32_t
track_id
,
int32_t
rotation
)
OasisPlayer.h
영상 트랙을 회전하여 보여줍니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
rotation
영상 트랙의 회전 각도입니다. 0, 90, 180, 270 중 하나 값을 지정합니다.
리턴값
- 0: 성공
- -1: 실패
int32_t
playerSetZoom
(
const PlayerRef &
player
,
int32_t
track_id
,
int32_t
x
,
int32_t
y
,
int32_t
width
,
int32_t
height
)
OasisPlayer.h
영상 트랙을 확대 또는 축소하여 보여줍니다.
매개변수
player
createPlayer로 생성한 Player 객체입니다.
track_id
영상 트랙 ID입니다.
x
확대할 영역의 x좌표입니다.
y
확대할 영역의 y좌표입니다.
width
확대할 영역의 가로 크기입니다.
height
확대할 영역의 세로 크기입니다.
리턴값
- 0: 성공
- -1: 실패
구조체¶
struct
MediaTrackInfo
Oasis.h
타입
이름
설명
int32_t
id
영상 트랙 ID입니다.
int32_t
width
영상 트랙의 가로 크기입니다.
int32_t
height
영상 트랙의 세로 크기입니다.
예제¶
아래는 녹화 파일의 영상 트랙 하나를 재생하는 미디어 플레이어 예입니다.
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;
}
오디오 출력(sink) 장치를 초기화 합니다.
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["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);
디스프레이 장치를 초기화 합니다.
parameters.clear();
parameters["memory-type"] = "ion"; //cma
parameters["screen-width"] = "480";
parameters["screen-height"] = "320";
display::setup(parameters);
GUI를 설정합니다. 여기 예에서는 터치를 사용하지 않습니다.
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;
}
미디어 플레이어를 초기화 합니다.
parameters.clear();
// 기본 스크린 객체를 얻고 너비와 높이를 미디어플레이어에 적용합니다.
ui::ScreenRef screen = ui::getDefaultScreen();
int32_t screen_width = ui::screenWidth(screen);
int32_t screen_height = ui::screenHeight(screen);
// MediaObserver 에서 유도된 사용자 정의 객체를 생성합니다.
std::shared_ptr<MyPlayingObserver> observer = std::make_shared<MyPlayingObserver>();
// 필요할 경우 rotation과 snd-path 도 지정합니다.
// snd-path는 오디오 장치 생성시 지정한 장치 경로이어야 합니다.
parameters["rotation"] = std::to_string(rotation);
parameters["snd-path"] = SND_PATH;
parameters["channel-count"] = "1";
parameters["primary-channel"] = "1";
// track-id가 '0'고 실제 파일의 첫 트랙 ID가 '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;
화면을 구성합니다. 최상위 Window 객체에 Fixed 레이아웃 컨테이너를 이용하고, 재생화면은 전체화면으로 설정합니다.
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);
재생을 시작합니다.
err = ui::playerStart(player, file_path, observer, nullptr);
// 트랙 정보를 얻습니다.
std::vector<MediaTrackInfo> tracks;
ui::playerGetVideoTracks(player, tracks);
재생 중 10초 앞으로 재생 위치를 변경하는 예입니다.
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);
}
재생 중 화면 위치와 크기를 변경하는 예입니다.
ui::playerSetRect(player, track_id, 100, 100, 320, 240)
재생을 중지합니다.
ui::playerStop(player);
아래는 전체 코드입니다.
#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["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();
//ASSERT(screen != nullptr);
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");
//ASSERT(player_panel != nullptr);
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;
}