The (Circle) Music Player sample application demonstrates how you can create a music player application, get media information, and play media files using APIs related to media control.
For information on creating the sample application project in the IDE, see Creating Sample Applications.
The following figure illustrates the main screens of the Music Player.
Figure: (Circle) Music Player screens
The user can control the playback with the buttons on the main screen. To access further options, click the more button (3 vertical dots) on the right side of the screen.
Prerequisites
To ensure proper application execution, the following privileges must be set:
- http://tizen.org/privilege/mediastorage
- http://tizen.org/privilege/externalstorage
- http://tizen.org/privilege/content.write
Source Files
You can create and view the sample application project including the source files in the IDE.
File name | Description |
---|---|
inc/data.h | This file contains information and definition of the variables and functions used in the C files, especially in the data.c file. |
inc/musicplayer.h | This file contains information and definition of the variables and functions used in the C files, especially in the musicplayer.c file. |
inc/view.h | This file contains information and definition of the variables and functions used in the C files, especially in the view.c file. |
res/edje/main.edc | This file is for the UI and contains style, image, and position of the sample application. |
res/images | This directory contains the image files used in the C files. |
src/data.c | This file contains the functions for retrieving and creating data for the application. |
src/musicplayer.c | This file contains the functions related to the application life-cycle, callback functions, and view control. |
src/view.c | This file contains the functions for implementing the views and handling events. |
Implementation
Basic Layout
To create the basic application layout, use the view_create() function. The window and conformant components are essential parts of the application layout.
void view_create(void) { // Create a window s_info.win = view_create_win(PACKAGE); if (s_info.win == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a window."); return; } // Create a conformant s_info.conform = view_create_conformant_without_indicator(s_info.win); if (s_info.conform == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a conformant"); return; } // Show the window after the main view is set up evas_object_show(s_info.win); }
Create a layout for the conformant using the view_create_layout_for_conformant() function:
conform = view_get_conformant(); content = view_create_layout_for_conformant(conform, full_path, GRP_MAIN, _content_back_cb, NULL); if (content == NULL) { dlog_print(DLOG_ERROR, LOG_TAG, "failed to create a content."); return NULL; }
Main View
The main view shows the playback control buttons, and the details of the currently playing song.
Figure: Main view
To create the main view, use the view_create_layout_for_conformant() function in the app_create() function:
content = view_create_layout_for_conformant(conform, full_path, GRP_MAIN, _content_back_cb, NULL);
The following figure illustrates the created main view frame.
Figure: Main view frame
Fill out each part of the view:
- The fourth parameter of the view_set_button() function is used to define the button icon image. In this example, a background image under the button is used, so set the background image with the EDJ file and set the button to be transparent (with a focus theme).
- To indicate that a button is clicked, customize the _<button name>_btn_clicked_cb() callbacks.
- To add a more button to the music player, use the view_set_more_button() function. You can customize the number, names, sub texts, and icons of the options behind the more button. The last parameter is the path of the icon.
// Set default album art data_get_resource_path(IMG_PATH_NO_ALBUM, default_img_path, sizeof(default_img_path)); view_music_set_album_art(content, "sw.bg", "NULL", default_img_path); // Set the progress bar background image and color icon_path = data_get_image("sw.progressbar.bg"); view_set_image(content, "sw.progressbar.bg", icon_path); view_set_color(content, "sw.progressbar.bg", 0, 87, 107, 255); free(icon_path); // Set the Play button icon_path = data_get_image("sw.icon.play"); view_set_button(content, "sw.icon.play", "focus", icon_path, NULL, _btn_down_cb, _btn_up_cb, _play_btn_clicked_cb, content); view_set_color(content, "sw.icon.play", 250, 250, 250, 255); free(icon_path); // Set the Prev button icon_path = data_get_image("sw.icon.prev"); view_set_button(content, "sw.icon.prev", "focus", icon_path, NULL, _btn_down_cb, _btn_up_cb, _prev_btn_clicked_cb, content); view_set_color(content, "sw.icon.prev", 250, 250, 250, 255); free(icon_path); // Set the Next button icon_path = data_get_image("sw.icon.next"); view_set_button(content, "sw.icon.next", "focus", icon_path, NULL, _btn_down_cb, _btn_up_cb, _next_btn_clicked_cb, content); view_set_color(content, "sw.icon.next", 250, 250, 250, 255); free(icon_path); // Set the progress bar used to display the play time view_set_progressbar(content, "sw.progressbar", 53, 5); view_set_color_of_circle_object(content, "sw.progressbar", 0, 192, 235, 255 * 0.5); view_set_progressbar_val(content, "sw.progressbar", 0); // Set the more button view_set_more_button(content, "sw.more", NULL, NULL, NULL, NULL); data_get_resource_path(data_get_more_button_image(0), full_path, sizeof(full_path)); view_add_more_button_item(content, "sw.more", data_get_more_button_main_text(0), data_get_more_button_sub_text(0), full_path, _more_btn_item_clicked_cb, content);
When the user clicks the more button, a selector view opens showing the available options. If the user selects a more option item, the _more_btn_item_clicked_cb() callback is called.
Figure: Option icon in the selector view
static void _more_btn_item_clicked_cb(void *user_data, Evas_Object *obj, void *event_info) { Evas_Object *content = user_data; Eext_Object_Item *item = (Eext_Object_Item *) event_info; const char *sub_text; char full_path[PATH_MAX] = {0,}; device_info_e device; sub_text = eext_more_option_item_part_text_get(item, "selector,sub_text"); if (!strcmp(sub_text, data_get_more_button_sub_text(DEVICE_INFO_GEAR))) { device = DEVICE_INFO_PHONE; evas_object_data_set(content, "__DEVICE_INFO__", (void *) device); _set_no_content_layout(content, "BT disconnected"); } else { device = DEVICE_INFO_GEAR; evas_object_data_set(content, "__DEVICE_INFO__", (void *) device); evas_object_data_set(content, "__CURRENT_ALBUM_INDEX__", (void *) 0); _set_current_album(content, 0); } data_get_resource_path(data_get_more_button_image(device), full_path, sizeof(full_path)); view_music_change_more_item(item, data_get_more_button_main_text(device), data_get_more_button_sub_text(device), full_path); if (player_unprepare(s_info.player) != PLAYER_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "unprepare error"); return; } _change_play_button_image(content); }
The _more_btn_item_clicked_cb() callback changes the current album art and title based on the device type the user selected.
Figure: Result of the device type change