Skip to content

Latest commit

 

History

History
235 lines (199 loc) · 5.98 KB

File metadata and controls

235 lines (199 loc) · 5.98 KB

Media Player Demo

Complete sample code

#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <media_api.h>
#include <sys/mount.h>
#include <linux/fs.h>

#define PLAYER_IDLE      0
#define PLAYER_PREPARED  1
#define PLAYER_STARTED   2
#define PLAYER_COMPLETED 3
#define PLAYER_STOPPED   4
#define PLAYER_DEFAULT_SIZE 512

static struct player_global_s {
    sem_t sem;
    int state;
} g_priv;

struct player_priv_s {
    void *handle;
    char *file;
};

static void music_event_callback(void* cookie, int event, int ret, const char *data) {
    char *str = "UNKNOW EVENT";

    switch (event) {
        case MEDIA_EVENT_STARTED:
            g_priv.state = PLAYER_STARTED;
            str = "MEDIA_EVENT_STARTED";
            sem_post(&g_priv.sem);
            break;
        case MEDIA_EVENT_STOPPED:
            str = "MEDIA_EVENT_STOPPED";
            break;
        case MEDIA_EVENT_COMPLETED:
            g_priv.state = PLAYER_COMPLETED;
            str = "MEDIA_EVENT_COMPLETED";
            break;
        case MEDIA_EVENT_PREPARED:
            g_priv.state = PLAYER_PREPARED;
            str = "MEDIA_EVENT_PREPARED";
            sem_post(&g_priv.sem);
            break;
        case MEDIA_EVENT_PAUSED:
            str = "MEDIA_EVENT_PAUSED";
            break;
        case MEDIA_EVENT_SEEKED:
            str = "MEDIA_EVENT_SEEKED";
            break;
    }

    syslog(LOG_INFO, "%s, music event %s, event %d, ret %d, info %s line %d\n",
           __func__, str, event, ret, data ? data : "NULL", __LINE__);
}

/* buffer mode */
static void *player_write_thread(void *arg) {
    struct player_priv_s *priv = (struct player_priv_s *)arg;
    char *buffer = NULL;
    int act, ret;
    int fd = -1;

    fd = open(priv->file, O_RDONLY);
    if (fd < 0) {
        syslog(LOG_ERR, "Failed to open file: %s\n", strerror(errno));
        return NULL;
    }

    buffer = (char *)malloc(PLAYER_DEFAULT_SIZE);
    if (!buffer) {
        close(fd);
        return NULL;
    }

    syslog(LOG_INFO, "%s, start, line %d\n", __func__, __LINE__);

    while (1) {
        act = read(fd, buffer, PLAYER_DEFAULT_SIZE);
        if (act <= 0)
            break;

        char *tmp = buffer;
        while (act > 0) {
            ret = media_player_write_data(priv->handle, tmp, act);
            if (ret == 0) {
                break;
            } else if (ret < 0 && errno == EAGAIN) {
                sleep(1);
                continue;
            } else if (ret < 0) {
                syslog(LOG_ERR, "%s, error ret %d errno %d, line %d\n", __func__, ret, errno, __LINE__);
                goto out;
            }

            tmp += ret;
            act -= ret;
        }
    }

out:
    free(buffer);
    close(fd);
    g_priv.state = PLAYER_COMPLETED;
    return NULL;
}

int main(int argc, char *argv[]) {
    unsigned int duration, position;
    float volume;
    void *player;
    int ret;
    int buffer_mode_enabled = 0; /* Default to not using buffer mode */
    pthread_t thread;
    struct player_priv_s priv;

    if (argc >= 3) {
        if (strcmp(argv[2], "1") == 0) {
            buffer_mode_enabled = 1;
        } else if (strcmp(argv[2], "2") == 0) {
            buffer_mode_enabled = 0;
        } else {
            syslog(LOG_ERR, "Invalid buffer mode selection. Use 1 to buffer or 2 to url.\n");
            exit(EXIT_FAILURE);
        }
    } else {
        syslog(LOG_ERR, "Usage: %s <music_file> [1|2] (1=enable buffer mode, 2=url mode)\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    sem_init(&g_priv.sem, 0, 0);
    g_priv.state = PLAYER_IDLE;

    player = media_player_open("Music");
    if (!player) {
        syslog(LOG_ERR, "Player: open failed.\n");
        return -1;
    }

    ret = media_player_set_event_callback(player, player, music_event_callback);
    if (ret < 0) {
        syslog(LOG_ERR, "Player: set callback failed.\n");
        goto out;
    }

    ret = media_player_set_volume(player, 0.6);
    if (ret < 0) {
        syslog(LOG_ERR, "Player: set_volume failed.\n");
        goto out;
    }

    ret = media_player_prepare(player,argv[1], NULL);
    if (ret < 0) {
        syslog(LOG_ERR, "Player: prepare failed.\n");
        goto out;
    }

    sem_wait(&g_priv.sem);

    if (g_priv.state != PLAYER_PREPARED) {
        syslog(LOG_INFO, "Player: prepare event return failed.\n");
        goto out;
    }

    /* Initialize buffer mode if selected */
    if (buffer_mode_enabled) {
        priv.handle = player;
        priv.file = strdup(argv[1]); /* Use the music file provided as an argument */
        if (!priv.file) {
            syslog(LOG_ERR, "Failed to duplicate file path.\n");
            goto out;
        }
        ret = pthread_create(&thread, NULL, player_write_thread, &priv);
        if (ret != 0) {
            syslog(LOG_ERR, "Player: create thread failed.\n");
            free(priv.file);
            goto out;
        }
        pthread_detach(thread);
    }

    ret = media_player_start(player);
    if (ret < 0) {
        syslog(LOG_ERR, "Player: start failed.\n");
        goto out;
    }

    sem_wait(&g_priv.sem);

    if (g_priv.state != PLAYER_STARTED) {
        syslog(LOG_ERR, "Player: start event return failed.\n");
        goto out;
    }

    syslog(LOG_INFO, "Player: playing %d.\n", media_player_is_playing(player));

    media_player_get_duration(player, &duration);
    syslog(LOG_INFO, "Player: get_duration ret %d %d.\n", ret, duration);

    media_player_get_volume(player, &volume);
    syslog(LOG_INFO, "Player: get_volume %f.\n", volume);

    while (g_priv.state == PLAYER_STARTED) {
        media_player_get_position(player, &position);
        sleep(30);
    }

    ret = media_player_stop(player);
    if (ret < 0) {
        syslog(LOG_ERR, "Player: stop failed.\n");
        goto out;
    }

out:
    if (priv.file) {
        free(priv.file);
    }

    media_player_close(player, 0);
    sem_destroy(&g_priv.sem);
    syslog(LOG_INFO, "Player: closed.\n");

    return 0;
}