player_ui.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. #include <rtgui/rtgui.h>
  2. #include <rtgui/image.h>
  3. #include <rtgui/rtgui_system.h>
  4. #include <rtgui/widgets/view.h>
  5. #include <rtgui/widgets/workbench.h>
  6. #include <string.h>
  7. #include <dfs_posix.h>
  8. #include "player_ui.h"
  9. #include "player_bg.h"
  10. #include "play_list.h"
  11. #include "listview.h"
  12. #include "filelist.h"
  13. #include "play.hdh"
  14. #include "stop.hdh"
  15. static rtgui_image_t *background = RT_NULL;
  16. static struct rtgui_view* function_view;
  17. static struct rtgui_view* home_view;
  18. static struct rtgui_workbench* workbench;
  19. static rtgui_timer_t* info_timer;
  20. static rt_thread_t player_ui_tid = RT_NULL;
  21. static enum PLAYER_MODE player_mode = PLAYER_STOP;
  22. static enum PLAYER_STEP next_step = PLAYER_STEP_STOP;
  23. static struct tag_info tinfo;
  24. void player_set_position(rt_uint32_t position)
  25. {
  26. tinfo.position = position / (tinfo.bit_rate / 8);
  27. }
  28. void info_timer_timeout(rtgui_timer_t* timer, void* parameter)
  29. {
  30. struct rtgui_dc* dc;
  31. rtgui_color_t saved;
  32. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(home_view));
  33. if (dc == RT_NULL) return ;
  34. saved = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view));
  35. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = RTGUI_RGB(206, 231, 255);
  36. rtgui_dc_draw_hline(dc, 14, 14 + (tinfo.position * 212) / tinfo.duration, 75);
  37. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = saved;
  38. rtgui_dc_end_drawing(dc);
  39. }
  40. rt_uint32_t read_line(int fd, char* line, rt_uint32_t line_size)
  41. {
  42. char *pos, *next;
  43. rt_uint32_t length;
  44. length = read(fd, line, line_size);
  45. if (length > 0)
  46. {
  47. pos = strstr(line, "\r\n");
  48. if (pos == RT_NULL)
  49. {
  50. pos = strstr(line, "\n");
  51. next = pos ++;
  52. }
  53. else next = pos + 2;
  54. if (pos != RT_NULL)
  55. {
  56. *pos = '\0';
  57. /* move back */
  58. lseek(fd, -(length - (next - line)), SEEK_CUR);
  59. length = pos - line;
  60. }
  61. else length = 0;
  62. }
  63. rt_kprintf("line %s\n", line);
  64. return length;
  65. }
  66. static void player_update_tag_info(struct rtgui_dc* dc)
  67. {
  68. rtgui_rect_t rect;
  69. char line[32];
  70. rtgui_color_t saved;
  71. saved = rtgui_dc_get_color(dc);
  72. rtgui_dc_set_color(dc, black);
  73. rect.x1 = 0; rect.y1 = 0;
  74. rect.x2 = 240; rect.y2 = 65;
  75. /* draw background */
  76. background = rtgui_image_create_from_file("hdc",
  77. "/resource/bg.hdc", RT_FALSE);
  78. if (background != RT_NULL)
  79. {
  80. rtgui_image_blit(background, dc, &rect);
  81. rtgui_image_destroy(background);
  82. background = RT_NULL;
  83. }
  84. else
  85. {
  86. rtgui_dc_fill_rect(dc, &rect);
  87. }
  88. /* draw playing information */
  89. rect.x1 = 28; rect.y1 = 12;
  90. rect.x2 = 220; rect.y2 = rect.y1 + 16;
  91. if (player_mode == PLAYER_STOP)
  92. {
  93. rt_snprintf(line, sizeof(line),
  94. "网络收音机");
  95. rtgui_dc_draw_text(dc, line, &rect);
  96. }
  97. else
  98. rtgui_dc_draw_text(dc, tinfo.title, &rect);
  99. rect.x1 = 28; rect.y1 = 39;
  100. rect.x2 = 220; rect.y2 = 59;
  101. if (player_mode == PLAYER_STOP)
  102. {
  103. rt_snprintf(line, sizeof(line),
  104. "radio.rt-thread.org");
  105. rtgui_dc_draw_text(dc, line, &rect);
  106. }
  107. else
  108. rtgui_dc_draw_text(dc, tinfo.artist, &rect);
  109. if ((tinfo.duration != 0) && player_mode != PLAYER_STOP)
  110. {
  111. rect.x1 = rect.x2 - 64;
  112. rt_snprintf(line, sizeof(line), "%02d:%02d:%02d",
  113. tinfo.duration / 3600, tinfo.duration / 60, tinfo.duration % 60);
  114. rtgui_dc_draw_text(dc, line, &rect);
  115. }
  116. rtgui_dc_set_color(dc, saved);
  117. }
  118. void play_mp3_file(const char* fn)
  119. {
  120. struct rtgui_dc* dc;
  121. rtgui_color_t saved;
  122. /* get music tag information */
  123. mp3_get_info(fn, &tinfo);
  124. if (tinfo.title[0] == '\0')
  125. rt_snprintf(tinfo.title, sizeof(tinfo.title), "<未知名音乐>");
  126. /* set player mode */
  127. player_mode = PLAYER_PLAY_FILE;
  128. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(home_view));
  129. if (dc != RT_NULL)
  130. {
  131. rtgui_rect_t play_rect;
  132. rtgui_image_t *button;
  133. /* update tag information */
  134. player_update_tag_info(dc);
  135. /* reset progress bar */
  136. saved = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view));
  137. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = RTGUI_RGB(82, 199, 16);
  138. rtgui_dc_draw_hline(dc, 14, 226, 75);
  139. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = saved;
  140. /* update play button */
  141. button = rtgui_image_create_from_mem("hdc",
  142. play_hdh, sizeof(play_hdh), RT_FALSE);
  143. play_rect.x1 = 32; play_rect.y1 = 92;
  144. play_rect.x2 = 61; play_rect.y2 = 114;
  145. rtgui_image_blit(button, dc, &play_rect);
  146. rtgui_image_destroy(button);
  147. rtgui_dc_end_drawing(dc);
  148. }
  149. rtgui_view_show(home_view, RT_FALSE);
  150. rt_kprintf("play file: %s\n", fn);
  151. player_play_file(fn);
  152. }
  153. void function_filelist(void* parameter)
  154. {
  155. rtgui_rect_t rect;
  156. filelist_view_t *view;
  157. rtgui_widget_get_rect(RTGUI_WIDGET(workbench), &rect);
  158. view = filelist_view_create(workbench, "/", "*.*", &rect);
  159. if (view != RT_NULL)
  160. {
  161. if (rtgui_view_show(RTGUI_VIEW(view), RT_TRUE) == RTGUI_MODAL_OK)
  162. {
  163. char fn[64];
  164. /* get open file */
  165. rt_snprintf(fn, 64, "%s/%s", view->current_directory,
  166. view->items[view->current_item].name);
  167. if (strstr(view->items[view->current_item].name , ".mp3") != RT_NULL ||
  168. strstr(view->items[view->current_item].name , ".MP3") != RT_NULL)
  169. {
  170. /* clear old play list */
  171. play_list_clear();
  172. play_list_append(fn);
  173. player_mode = PLAYER_PLAY_FILE;
  174. next_step = PLAYER_STEP_STOP;
  175. play_mp3_file(play_list_start());
  176. }
  177. else if (strstr(view->items[view->current_item].name , ".m3u") != RT_NULL ||
  178. strstr(view->items[view->current_item].name , ".M3U") != RT_NULL)
  179. {
  180. /* read all of music filename to a list */
  181. int fd;
  182. char line[64];
  183. fd = open(fn, O_RDONLY, 0);
  184. if (fd >= 0)
  185. {
  186. rt_uint32_t length;
  187. length = read_line(fd, line, sizeof(line));
  188. /* clear old play list */
  189. play_list_clear();
  190. do
  191. {
  192. length = read_line(fd, line, sizeof(line));
  193. if (length > 0)
  194. {
  195. if (line[0] != '/')
  196. {
  197. rt_snprintf(fn, sizeof(fn),
  198. "%s/%s", view->current_directory, line);
  199. play_list_append(fn);
  200. }
  201. else play_list_append(line);
  202. }
  203. } while (length > 0);
  204. close(fd);
  205. if (play_list_items() > 0)
  206. {
  207. player_mode = PLAYER_PLAY_FILE;
  208. next_step = PLAYER_STEP_NEXT;
  209. play_mp3_file(play_list_start());
  210. }
  211. }
  212. }
  213. else if (strstr(view->items[view->current_item].name , ".wav") != RT_NULL ||
  214. strstr(view->items[view->current_item].name , ".WAV") != RT_NULL)
  215. {
  216. }
  217. }
  218. /* destroy view */
  219. filelist_view_destroy(view);
  220. }
  221. return;
  222. }
  223. void function_device(void* parameter)
  224. {
  225. rtgui_view_t *view;
  226. extern rtgui_view_t* device_view_create(rtgui_workbench_t* workbench);
  227. view = device_view_create(workbench);
  228. if (view != RT_NULL)
  229. {
  230. rtgui_view_show(view, RT_FALSE);
  231. }
  232. return;
  233. }
  234. void function_player(void* parameter)
  235. {
  236. rtgui_view_show(home_view, RT_FALSE);
  237. return;
  238. }
  239. void function_action(void* parameter)
  240. {
  241. rt_kprintf("item action!\n");
  242. return;
  243. }
  244. struct list_item function_list[] =
  245. {
  246. {"选择电台", RT_NULL, function_action, RT_NULL},
  247. {"更新电台", RT_NULL, function_action, RT_NULL},
  248. {"播放文件", RT_NULL, function_filelist, RT_NULL},
  249. {"设备信息", RT_NULL, function_device, RT_NULL},
  250. {"选项设置", RT_NULL, function_action, RT_NULL},
  251. {"返回播放器", RT_NULL, function_player, RT_NULL},
  252. };
  253. static rt_bool_t home_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
  254. {
  255. if (event->type == RTGUI_EVENT_PAINT)
  256. {
  257. struct rtgui_dc* dc;
  258. struct rtgui_rect rect;
  259. rtgui_color_t saved;
  260. dc = rtgui_dc_begin_drawing(widget);
  261. if (dc == RT_NULL) return RT_FALSE;
  262. rtgui_widget_get_rect(widget, &rect);
  263. saved = RTGUI_WIDGET_FOREGROUND(widget);
  264. /* draw background */
  265. background = rtgui_image_create_from_file("hdc",
  266. "/resource/bg.hdc", RT_FALSE);
  267. if (background != RT_NULL)
  268. {
  269. rtgui_image_t *play;
  270. rtgui_rect_t play_rect;
  271. rtgui_image_blit(background, dc, &rect);
  272. rtgui_image_destroy(background);
  273. background = RT_NULL;
  274. if (player_mode == PLAYER_STOP)
  275. play = rtgui_image_create_from_mem("hdc",
  276. stop_hdh, sizeof(stop_hdh), RT_FALSE);
  277. else
  278. play = rtgui_image_create_from_mem("hdc",
  279. play_hdh, sizeof(play_hdh), RT_FALSE);
  280. play_rect.x1 = 32; play_rect.y1 = 92;
  281. play_rect.x2 = 61; play_rect.y2 = 114;
  282. rtgui_image_blit(play, dc, &play_rect);
  283. rtgui_image_destroy(play);
  284. }
  285. else
  286. {
  287. rtgui_dc_fill_rect(dc, &rect);
  288. }
  289. /* draw playing information */
  290. rtgui_dc_set_color(dc, black);
  291. {
  292. char line[32];
  293. rect.x1 = 28; rect.y1 = 12;
  294. rect.x2 = 220; rect.y2 = rect.y1 + 16;
  295. if (player_mode == PLAYER_STOP)
  296. {
  297. rt_snprintf(line, sizeof(line),
  298. "网络收音机");
  299. rtgui_dc_draw_text(dc, line, &rect);
  300. }
  301. else
  302. rtgui_dc_draw_text(dc, tinfo.title, &rect);
  303. rect.x1 = 28; rect.y1 = 39;
  304. rect.x2 = 220; rect.y2 = 59;
  305. if (player_mode == PLAYER_STOP)
  306. {
  307. rt_snprintf(line, sizeof(line),
  308. "radio.rt-thread.org");
  309. rtgui_dc_draw_text(dc, line, &rect);
  310. }
  311. else
  312. rtgui_dc_draw_text(dc, tinfo.artist, &rect);
  313. if (tinfo.duration != 0)
  314. {
  315. rect.x1 = rect.x2 - 64;
  316. rt_snprintf(line, sizeof(line), "%02d:%02d:%02d",
  317. tinfo.duration / 3600, tinfo.duration / 60, tinfo.duration % 60);
  318. rtgui_dc_draw_text(dc, line, &rect);
  319. }
  320. }
  321. RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16);
  322. rtgui_dc_draw_hline(dc, 14, 226, 75);
  323. RTGUI_WIDGET_FOREGROUND(widget) = saved;
  324. if (player_mode == PLAYER_PLAY_FILE)
  325. {
  326. char line[32];
  327. rt_uint32_t index;
  328. struct play_item* item;
  329. rect.x1 = 20; rect.y1 = 150;
  330. rect.x2 = 220; rect.y2 = 168;
  331. for (index = 0; index < play_list_items() && index < 8; index ++)
  332. {
  333. item = play_list_item(index);
  334. rtgui_dc_draw_text(dc, item->title, &rect);
  335. rect.x1 = rect.x2 - 64;
  336. rt_snprintf(line, sizeof(line), "%02d:%02d:%02d",
  337. item->duration / 3600,
  338. item->duration / 60,
  339. item->duration % 60);
  340. rtgui_dc_draw_text(dc, line, &rect);
  341. /* move to next item */
  342. rect.x1 = 20;
  343. rect.y1 += 18; rect.y2 += 18;
  344. }
  345. }
  346. rtgui_dc_end_drawing(dc);
  347. return RT_FALSE;
  348. }
  349. else if (event->type == RTGUI_EVENT_KBD)
  350. {
  351. struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
  352. if (ekbd->type == RTGUI_KEYDOWN)
  353. {
  354. switch (ekbd->key)
  355. {
  356. case RTGUIK_RIGHT:
  357. if (player_mode == PLAYER_PLAY_FILE && play_list_items() > 0)
  358. {
  359. player_stop();
  360. next_step = PLAYER_STEP_NEXT;
  361. }
  362. break;
  363. case RTGUIK_LEFT:
  364. if (player_mode == PLAYER_PLAY_FILE && play_list_items() > 0)
  365. {
  366. player_stop();
  367. next_step = PLAYER_STEP_PREV;
  368. }
  369. break;
  370. case RTGUIK_RETURN:
  371. if (player_is_playing() == RT_TRUE)
  372. {
  373. player_stop();
  374. next_step = PLAYER_STEP_STOP;
  375. }
  376. else
  377. {
  378. if ((player_mode == PLAYER_STOP) && (play_list_items() > 0))
  379. {
  380. next_step = PLAYER_STEP_NEXT;
  381. play_mp3_file(play_list_current_item());
  382. }
  383. }
  384. break;
  385. case RTGUIK_DOWN:
  386. rtgui_view_show(function_view, RT_FALSE);
  387. break;
  388. }
  389. }
  390. return RT_FALSE;
  391. }
  392. else if (event->type == RTGUI_EVENT_COMMAND)
  393. {
  394. struct rtgui_event_command* ecmd = (struct rtgui_event_command*)event;
  395. switch (ecmd->command_id)
  396. {
  397. case PLAYER_REQUEST_PLAY_SINGLE_FILE:
  398. case PLAYER_REQUEST_PLAY_LIST:
  399. rtgui_timer_start(info_timer);
  400. break;
  401. case PLAYER_REQUEST_STOP:
  402. {
  403. rtgui_timer_stop(info_timer);
  404. switch (next_step)
  405. {
  406. case PLAYER_STEP_STOP:
  407. {
  408. struct rtgui_dc* dc;
  409. rtgui_color_t saved;
  410. rtgui_image_t *button;
  411. rtgui_rect_t play_rect;
  412. player_mode = PLAYER_STOP;
  413. dc = rtgui_dc_begin_drawing(widget);
  414. if (dc == RT_NULL) return RT_FALSE;
  415. player_update_tag_info(dc);
  416. saved = RTGUI_WIDGET_FOREGROUND(widget);
  417. RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16);
  418. rtgui_dc_draw_hline(dc, 14, 226, 75);
  419. /* update play button */
  420. button = rtgui_image_create_from_mem("hdc",
  421. stop_hdh, sizeof(stop_hdh), RT_FALSE);
  422. play_rect.x1 = 32; play_rect.y1 = 92;
  423. play_rect.x2 = 61; play_rect.y2 = 114;
  424. rtgui_image_blit(button, dc, &play_rect);
  425. rtgui_image_destroy(button);
  426. RTGUI_WIDGET_FOREGROUND(widget) = saved;
  427. rtgui_dc_end_drawing(dc);
  428. }
  429. break;
  430. case PLAYER_STEP_NEXT:
  431. if (play_list_is_end() == RT_TRUE)
  432. {
  433. struct rtgui_dc* dc;
  434. rtgui_color_t saved;
  435. rtgui_image_t *button;
  436. rtgui_rect_t play_rect;
  437. /* set stat */
  438. next_step = PLAYER_STEP_STOP;
  439. player_mode = PLAYER_STOP;
  440. /* update UI */
  441. dc = rtgui_dc_begin_drawing(widget);
  442. if (dc == RT_NULL) return RT_FALSE;
  443. player_update_tag_info(dc);
  444. saved = RTGUI_WIDGET_FOREGROUND(widget);
  445. RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16);
  446. rtgui_dc_draw_hline(dc, 14, 226, 75);
  447. /* update play button */
  448. button = rtgui_image_create_from_mem("hdc",
  449. stop_hdh, sizeof(stop_hdh), RT_FALSE);
  450. play_rect.x1 = 32; play_rect.y1 = 92;
  451. play_rect.x2 = 61; play_rect.y2 = 114;
  452. rtgui_image_blit(button, dc, &play_rect);
  453. rtgui_image_destroy(button);
  454. RTGUI_WIDGET_FOREGROUND(widget) = saved;
  455. rtgui_dc_end_drawing(dc);
  456. }
  457. else
  458. {
  459. play_mp3_file(play_list_next());
  460. next_step = PLAYER_STEP_NEXT;
  461. }
  462. break;
  463. case PLAYER_STEP_PREV:
  464. play_mp3_file(play_list_prev());
  465. next_step = PLAYER_STEP_NEXT;
  466. break;
  467. };
  468. }
  469. break;
  470. default:
  471. break;
  472. }
  473. return RT_FALSE;
  474. }
  475. return rtgui_view_event_handler(widget, event);
  476. }
  477. rt_bool_t player_workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event)
  478. {
  479. if (event->type == RTGUI_EVENT_KBD)
  480. {
  481. struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
  482. if ((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME)
  483. {
  484. /* active home view */
  485. if (workbench->current_view != home_view)
  486. {
  487. rtgui_view_show(home_view, RT_FALSE);
  488. return RT_FALSE;
  489. }
  490. }
  491. }
  492. return rtgui_workbench_event_handler(widget, event);
  493. }
  494. static void player_entry(void* parameter)
  495. {
  496. rt_mq_t mq;
  497. rtgui_rect_t rect;
  498. mq = rt_mq_create("ply_ui", 256, 4, RT_IPC_FLAG_FIFO);
  499. rtgui_thread_register(rt_thread_self(), mq);
  500. /* create information timer */
  501. info_timer = rtgui_timer_create(RT_TICK_PER_SECOND,
  502. RT_TIMER_FLAG_PERIODIC,
  503. info_timer_timeout, RT_NULL);
  504. workbench = rtgui_workbench_create("main", "workbench");
  505. if (workbench == RT_NULL) return;
  506. rtgui_widget_set_event_handler(RTGUI_WIDGET(workbench), player_workbench_event_handler);
  507. /* add home view */
  508. home_view = rtgui_view_create("Home");
  509. rtgui_widget_set_event_handler(RTGUI_WIDGET(home_view), home_view_event_handler);
  510. rtgui_workbench_add_view(workbench, home_view);
  511. /* this view can be focused */
  512. RTGUI_WIDGET(home_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
  513. /* set widget focus */
  514. rtgui_widget_focus(RTGUI_WIDGET(home_view));
  515. rtgui_view_show(home_view, RT_FALSE);
  516. /* add function view */
  517. rtgui_widget_get_rect(RTGUI_WIDGET(workbench), &rect);
  518. function_view = (struct rtgui_view*)list_view_create(function_list,
  519. sizeof(function_list)/sizeof(struct list_item),
  520. &rect);
  521. rtgui_workbench_add_view(workbench, function_view);
  522. rtgui_workbench_event_loop(workbench);
  523. rtgui_thread_deregister(rt_thread_self());
  524. rt_mq_delete(mq);
  525. }
  526. void player_notify_play(void)
  527. {
  528. struct rtgui_event_command ecmd;
  529. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  530. ecmd.type = RTGUI_CMD_USER_INT;
  531. ecmd.command_id = PLAYER_REQUEST_PLAY_SINGLE_FILE;
  532. rtgui_thread_send(player_ui_tid, &ecmd.parent, sizeof(ecmd));
  533. }
  534. void player_notify_stop()
  535. {
  536. struct rtgui_event_command ecmd;
  537. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  538. ecmd.type = RTGUI_CMD_USER_INT;
  539. ecmd.command_id = PLAYER_REQUEST_STOP;
  540. rtgui_thread_send(player_ui_tid, &ecmd.parent, sizeof(ecmd));
  541. }
  542. void player_ui_init()
  543. {
  544. player_ui_tid = rt_thread_create("ply_ui", player_entry, RT_NULL,
  545. 4096, 25, 5);
  546. if (player_ui_tid != RT_NULL)
  547. rt_thread_startup(player_ui_tid);
  548. }