Skip to content

Commit

Permalink
Refactoring event channel subscription to send events correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
DoumanAsh committed Jul 17, 2023
1 parent c5ed317 commit 21d902a
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 56 deletions.
9 changes: 9 additions & 0 deletions include/plugins/audioplayers.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,13 @@ void audio_player_set_source_url(struct audio_player *self, char *url);

bool audio_player_is_id(struct audio_player *self, char *id);

const char* audio_player_subscribe_channel_name(const struct audio_player *self);

///Asks to subscribe to channel events
///
///`value` - Indicates whether to subscribe or unsubscribe
///
///Returns `true` if player uses `channel`, otherwise returns `false
bool audio_player_set_subscription_status(struct audio_player *self, const char *channel, bool value);

#endif // AUDIOPLAYERS_H_
122 changes: 66 additions & 56 deletions src/plugins/audioplayers/player.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#define _GNU_SOURCE

#include <stdio.h>
#include <stdbool.h>

#include "gst/gst.h"
#include "gst/gstelementfactory.h"
#include "gst/gstmessage.h"
#include "gst/gstsegment.h"
#include "platformchannel.h"
#include "pluginregistry.h"

#include <flutter-pi.h>
#include <plugins/audioplayers.h>
Expand All @@ -30,7 +32,9 @@ struct audio_player {

char *url;
char *player_id;
char event_channel_name[128];
char *event_channel_name;

_Atomic bool event_subscribed;
};

// Private Class functions
Expand Down Expand Up @@ -75,22 +79,6 @@ static void audio_player_source_setup(GstElement *playbin, GstElement *source, G
}
}

static int on_receive_event_ch(char *channel, struct platch_obj *object, FlutterPlatformMessageResponseHandle *responsehandle) {
//TODO: Do we need any more setup to send events to dart code?
(void)channel;
if (strcmp(object->method, "listen") == 0) {
LOG_DEBUG("%s: listen()\n", channel);
platch_respond_success_std(responsehandle, NULL);
} else if (strcmp(object->method, "cancel") == 0) {
LOG_DEBUG("%s: cancel()\n", channel);
platch_respond_success_std(responsehandle, NULL);
} else {
return platch_respond_not_implemented(responsehandle);
}

return 0;
}

struct audio_player *audio_player_new(char *player_id, char *channel) {
GPollFD fd;
sd_event_source *busfd_event_source;
Expand All @@ -101,11 +89,13 @@ struct audio_player *audio_player_new(char *player_id, char *channel) {
}

self->url = NULL;
self->source = NULL;
self->is_initialized = false;
self->is_playing = false;
self->is_looping = false;
self->is_seek_completed = false;
self->playback_rate = 1.0;
self->event_subscribed = false;

gst_init(NULL, NULL);
self->playbin = gst_element_factory_make("playbin", NULL);
Expand Down Expand Up @@ -154,23 +144,10 @@ struct audio_player *audio_player_new(char *player_id, char *channel) {

// audioplayers player event channel clang:
// <local>/events/<player_id>
int ok = snprintf(
self->event_channel_name,
sizeof(self->event_channel_name),
"%s/events/%s",
channel,
player_id
);
DEBUG_ASSERT_MSG(ok < sizeof(self->event_channel_name), "event channel name overflow");

// set a receiver on the videoEvents event channel
ok = plugin_registry_set_receiver(
self->event_channel_name,
kStandardMethodCall,
on_receive_event_ch
);
asprintf(&self->event_channel_name, "%s/events/%s", channel, player_id);
DEBUG_ASSERT_MSG(self->event_channel_name != NULL, "event channel name OEM");

if (ok != 0) {
if (self->event_channel_name == NULL) {
goto deinit_player_id;
}

Expand Down Expand Up @@ -293,6 +270,10 @@ void audio_player_set_playback(struct audio_player *self, int64_t seekTo, double
}

void audio_player_on_media_error(struct audio_player *self, GError *error, gchar *debug) {
if (!self->event_subscribed) {
return;
}

char error_code[16] = {0};
snprintf(error_code, sizeof(error_code), "%d", error->code);
// clang-format off
Expand Down Expand Up @@ -335,6 +316,10 @@ void audio_player_on_media_state_change(struct audio_player *self, GstObject *sr
}

void audio_player_on_prepared(struct audio_player *self, bool value) {
if (!self->event_subscribed) {
return;
}

// clang-format off
platch_send_success_event_std(
self->event_channel_name,
Expand All @@ -347,6 +332,10 @@ void audio_player_on_prepared(struct audio_player *self, bool value) {
}

void audio_player_on_position_update(struct audio_player *self) {
if (!self->event_subscribed) {
return;
}

// clang-format off
platch_send_success_event_std(
self->event_channel_name,
Expand All @@ -359,6 +348,9 @@ void audio_player_on_position_update(struct audio_player *self) {
}

void audio_player_on_duration_update(struct audio_player *self) {
if (!self->event_subscribed) {
return;
}
// clang-format off
platch_send_success_event_std(
self->event_channel_name,
Expand All @@ -371,28 +363,32 @@ void audio_player_on_duration_update(struct audio_player *self) {
}
void audio_player_on_seek_completed(struct audio_player *self) {
audio_player_on_position_update(self);
// clang-format off
platch_send_success_event_std(
self->event_channel_name,
&STDMAP2(
STDSTRING("event"), STDSTRING("audio.onSeekComplete"),
STDSTRING("value"), STDBOOL(true)
)
);
// clang-format on

if (self->event_subscribed) {
// clang-format off
platch_send_success_event_std(
self->event_channel_name,
&STDMAP2(
STDSTRING("event"), STDSTRING("audio.onSeekComplete"),
STDSTRING("value"), STDBOOL(true)
)
);
// clang-format on
}
self->is_seek_completed = true;
}
void audio_player_on_playback_ended(struct audio_player *self) {
// clang-format off
platch_send_success_event_std(
self->event_channel_name,
&STDMAP2(
STDSTRING("event"), STDSTRING("audio.onComplete"),
STDSTRING("value"), STDBOOL(true)
)
);

// clang-format on
if (self->event_subscribed) {
// clang-format off
platch_send_success_event_std(
self->event_channel_name,
&STDMAP2(
STDSTRING("event"), STDSTRING("audio.onComplete"),
STDSTRING("value"), STDBOOL(true)
)
);
// clang-format on
}

if (audio_player_get_looping(self)) {
audio_player_play(self);
Expand Down Expand Up @@ -482,14 +478,15 @@ void audio_player_destroy(struct audio_player *self) {
self->url = NULL;
}


if (self->player_id != NULL) {
free(self->player_id);
self->player_id = NULL;
}

plugin_registry_remove_receiver(self->event_channel_name);
self->event_channel_name[0] = 0;
if (self->event_channel_name != NULL) {
free(self->event_channel_name);
self->event_channel_name = NULL;;
}

free(self);
}
Expand Down Expand Up @@ -572,3 +569,16 @@ void audio_player_set_source_url(struct audio_player *self, char *url) {
bool audio_player_is_id(struct audio_player *self, char *player_id) {
return strcmp(self->player_id, player_id) == 0;
}

const char* audio_player_subscribe_channel_name(const struct audio_player *self) {
return self->event_channel_name;
}

bool audio_player_set_subscription_status(struct audio_player *self, const char *channel, bool value) {
if (strcmp(self->event_channel_name, channel) == 0) {
self->event_subscribed = value;
return true;
} else {
return false;
}
}
53 changes: 53 additions & 0 deletions src/plugins/audioplayers/plugin.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,38 @@ static int on_global_method_call(char *channel, struct platch_obj *object, Flutt
return platch_respond_success_std(responsehandle, &STDBOOL(true));
}

static int on_receive_event_ch(char *channel, struct platch_obj *object, FlutterPlatformMessageResponseHandle *responsehandle) {
struct audio_player *player;

if (strcmp(object->method, "listen") == 0) {
LOG_DEBUG("%s: listen()\n", channel);

for_each_pointer_in_cpset(&plugin.players, player) {
if (audio_player_set_subscription_status(player, channel, true)) {
return platch_respond_success_std(responsehandle, NULL);
}
}

LOG_ERROR("%s: player not found\n", channel);
return platch_respond_not_implemented(responsehandle);
} else if (strcmp(object->method, "cancel") == 0) {
LOG_DEBUG("%s: cancel()\n", channel);

for_each_pointer_in_cpset(&plugin.players, player) {
if (audio_player_set_subscription_status(player, channel, false)) {
return platch_respond_success_std(responsehandle, NULL);
}
}

LOG_ERROR("%s: player not found\n", channel);
return platch_respond_not_implemented(responsehandle);
} else {
return platch_respond_not_implemented(responsehandle);
}

return 0;
}

enum plugin_init_result audioplayers_plugin_init(struct flutterpi *flutterpi, void **userdata_out) {
(void) userdata_out;
int ok;
Expand Down Expand Up @@ -249,12 +281,33 @@ static struct audio_player *audioplayers_linux_plugin_get_player(char *player_id
}
}

LOG_DEBUG("Create player(id=%s)\n", player_id);
player = audio_player_new(player_id, AUDIOPLAYERS_LOCAL_CHANNEL);

if (player == NULL) {
LOG_ERROR("player(id=%s) cannot be created", player_id);
return NULL;
}

const char* event_channel = audio_player_subscribe_channel_name(player);
// set a receiver on the videoEvents event channel
int ok = plugin_registry_set_receiver(
event_channel,
kStandardMethodCall,
on_receive_event_ch
);
if (ok != 0) {
LOG_ERROR("Cannot set player receiver for event channel: %s\n", event_channel);
audio_player_destroy(player);
return NULL;
}

cpset_put_locked(&plugin.players, player);
return player;
}

static void audioplayers_linux_plugin_dispose_player(struct audio_player *player) {
plugin_registry_remove_receiver(audio_player_subscribe_channel_name(player));
audio_player_destroy(player);
cpset_remove_locked(&plugin.players, player);
}
Expand Down

0 comments on commit 21d902a

Please sign in to comment.