This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch main
in repository eradio.
View the commit online.
commit 8a2707d148a7e65b8ad5f30fe602dee179ecf888
Author: politebot <[email protected]>
AuthorDate: Thu Oct 16 16:01:16 2025 -0500
Add error message when stream fails, show station name in status bar if no metadata
---
src/radio_player.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++--
src/radio_player.h | 2 +-
src/station_list.c | 2 +-
src/ui.c | 40 ++++++++++++++
src/ui.h | 1 +
5 files changed, 189 insertions(+), 5 deletions(-)
diff --git a/src/radio_player.c b/src/radio_player.c
index dd4110a..20c5849 100644
--- a/src/radio_player.c
+++ b/src/radio_player.c
@@ -1,15 +1,108 @@
#include "radio_player.h"
+#include "ui.h"
+
+static Ecore_Timer *stream_error_timer = NULL;
+static Ecore_Timer *audio_progress_timer = NULL;
+static double last_position = 0.0;
+static const char *current_station_name = NULL;
static void
_title_changed_cb(void *data, Evas_Object *obj, void *event_info)
{
AppData *ad = data;
const char *title = emotion_object_title_get(obj);
- if (title)
+
+ if (title && strlen(title) > 0)
{
printf("Station metadata: %s\n", title);
elm_object_text_set(ad->statusbar, title);
}
+ else if (current_station_name)
+ {
+ printf("No metadata, showing station name: %s\n", current_station_name);
+ elm_object_text_set(ad->statusbar, current_station_name);
+ }
+}
+
+static void
+_playback_error_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ AppData *ad = data;
+ printf("Playback error detected\n");
+ ui_show_error_dialog(ad, "Unable to stream this station");
+}
+
+static void
+_decode_error_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ AppData *ad = data;
+ printf("Decode error detected\n");
+ ui_show_error_dialog(ad, "Unable to stream this station");
+}
+
+static Eina_Bool
+_audio_progress_cb(void *data)
+{
+ AppData *ad = data;
+
+ if (!ad->playing || !ad->emotion)
+ {
+ audio_progress_timer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ double current_position = emotion_object_position_get(ad->emotion);
+
+ // If position has advanced from 0, we have audio playback!
+ if (current_position > 0.0 || current_position != last_position)
+ {
+ printf("Audio playback detected - canceling error timers\n");
+
+ // Cancel both timers since audio is playing
+ if (stream_error_timer)
+ {
+ ecore_timer_del(stream_error_timer);
+ stream_error_timer = NULL;
+ }
+
+ audio_progress_timer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ last_position = current_position;
+ return ECORE_CALLBACK_RENEW;
+}
+
+static Eina_Bool
+_stream_timeout_cb(void *data)
+{
+ AppData *ad = data;
+ printf("Stream timeout detected - no audio playback\n");
+
+ // Check if we're still "playing" but no actual audio progress is being made
+ if (ad->playing && ad->emotion)
+ {
+ double position = emotion_object_position_get(ad->emotion);
+
+ // If position is still 0 after timeout, likely no audio is being decoded
+ if (position == 0.0)
+ {
+ printf("No audio playback detected, showing error\n");
+ ui_show_error_dialog(ad, "Unable to stream this station");
+ radio_player_stop(ad);
+ }
+ }
+
+ stream_error_timer = NULL;
+
+ // Also cancel the audio progress timer
+ if (audio_progress_timer)
+ {
+ ecore_timer_del(audio_progress_timer);
+ audio_progress_timer = NULL;
+ }
+
+ return ECORE_CALLBACK_CANCEL;
}
void
@@ -17,6 +110,8 @@ radio_player_init(AppData *ad)
{
ad->emotion = emotion_object_add(ad->win);
evas_object_smart_callback_add(ad->emotion, "title_change", _title_changed_cb, ad);
+ evas_object_smart_callback_add(ad->emotion, "playback_error", _playback_error_cb, ad);
+ evas_object_smart_callback_add(ad->emotion, "decode_error", _decode_error_cb, ad);
}
void
@@ -26,16 +121,44 @@ radio_player_shutdown(void)
}
void
-radio_player_play(AppData *ad, const char *url)
+radio_player_play(AppData *ad, const char *url, const char *station_name)
{
- fprintf(stderr, "LOG: radio_player_play: ad=%p, url="" ad, url);
+ fprintf(stderr, "LOG: radio_player_play: ad=%p, url="" station=%s\n", ad, url, station_name ? station_name : "(unknown)");
if (url && url[0])
{
+ // Store the current station name
+ if (current_station_name)
+ eina_stringshare_del(current_station_name);
+ current_station_name = station_name ? eina_stringshare_add(station_name) : NULL;
+
+ // Cancel any existing timers
+ if (stream_error_timer)
+ {
+ ecore_timer_del(stream_error_timer);
+ stream_error_timer = NULL;
+ }
+ if (audio_progress_timer)
+ {
+ ecore_timer_del(audio_progress_timer);
+ audio_progress_timer = NULL;
+ }
+
emotion_object_file_set(ad->emotion, url);
emotion_object_play_set(ad->emotion, EINA_TRUE);
ad->playing = EINA_TRUE;
if (ad->play_pause_item)
elm_toolbar_item_icon_set(ad->play_pause_item, "media-playback-pause");
+
+ // Show station name initially
+ if (current_station_name)
+ elm_object_text_set(ad->statusbar, current_station_name);
+
+ // Reset position tracking
+ last_position = 0.0;
+
+ // Start timers to detect streaming failures
+ stream_error_timer = ecore_timer_add(10.0, _stream_timeout_cb, ad);
+ audio_progress_timer = ecore_timer_add(0.5, _audio_progress_cb, ad);
}
}
@@ -45,6 +168,26 @@ radio_player_stop(AppData *ad)
emotion_object_play_set(ad->emotion, EINA_FALSE);
emotion_object_position_set(ad->emotion, 0.0);
ad->playing = EINA_FALSE;
+
+ // Cancel all timers
+ if (stream_error_timer)
+ {
+ ecore_timer_del(stream_error_timer);
+ stream_error_timer = NULL;
+ }
+ if (audio_progress_timer)
+ {
+ ecore_timer_del(audio_progress_timer);
+ audio_progress_timer = NULL;
+ }
+
+ // Clean up station name
+ if (current_station_name)
+ {
+ eina_stringshare_del(current_station_name);
+ current_station_name = NULL;
+ }
+
if (ad->play_pause_item)
elm_toolbar_item_icon_set(ad->play_pause_item, "media-playback-start");
if (ad->statusbar)
diff --git a/src/radio_player.h b/src/radio_player.h
index 983160d..c0f4108 100644
--- a/src/radio_player.h
+++ b/src/radio_player.h
@@ -4,6 +4,6 @@
void radio_player_init(AppData *ad);
void radio_player_shutdown(void);
-void radio_player_play(AppData *ad, const char *url);
+void radio_player_play(AppData *ad, const char *url, const char *station_name);
void radio_player_stop(AppData *ad);
void radio_player_toggle_pause(AppData *ad);
diff --git a/src/station_list.c b/src/station_list.c
index 0a2cef2..e104f04 100644
--- a/src/station_list.c
+++ b/src/station_list.c
@@ -141,7 +141,7 @@ _list_item_selected_cb(void *data, Evas_Object *obj, void *event_info)
fprintf(stderr, "LOG: _list_item_selected_cb: station name='%s', url="" st->name, st->url);
_station_click_counter_request(ad, st);
- radio_player_play(ad, st->url);
+ radio_player_play(ad, st->url, st->name);
}
void
diff --git a/src/ui.c b/src/ui.c
index acf4389..e1c1c4f 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -20,6 +20,7 @@ void _search_entry_activated_cb(void *data, Evas_Object *obj, void *event_info);
void _list_item_selected_cb(void *data, Evas_Object *obj, void *event_info);
static void _favorites_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
static void _load_more_btn_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _error_dialog_ok_clicked_cb(void *data, Evas_Object *obj, void *event_info);
static void
@@ -348,6 +349,45 @@ _tb_search_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info
station_list_clear(ad);
}
+static void
+_error_dialog_ok_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Evas_Object *inwin = data;
+ evas_object_del(inwin);
+}
+
+void
+ui_show_error_dialog(AppData *ad, const char *message)
+{
+ if (!ad || !ad->win || !message) return;
+
+ Evas_Object *inwin = elm_win_inwin_add(ad->win);
+
+ Evas_Object *box = elm_box_add(ad->win);
+ elm_box_padding_set(box, 10, 10);
+ elm_box_horizontal_set(box, EINA_FALSE);
+ evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
+ elm_win_inwin_content_set(inwin, box);
+
+ Evas_Object *label = elm_label_add(ad->win);
+ elm_object_text_set(label, message);
+ evas_object_size_hint_weight_set(label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ evas_object_size_hint_align_set(label, EVAS_HINT_FILL, 0.5);
+ elm_box_pack_end(box, label);
+ evas_object_show(label);
+
+ Evas_Object *btn = elm_button_add(ad->win);
+ elm_object_text_set(btn, "OK");
+ evas_object_size_hint_align_set(btn, 0.5, 0.5);
+ elm_box_pack_end(box, btn);
+ evas_object_smart_callback_add(btn, "clicked", _error_dialog_ok_clicked_cb, inwin);
+ evas_object_show(btn);
+
+ evas_object_show(box);
+ evas_object_show(inwin);
+}
+
diff --git a/src/ui.h b/src/ui.h
index be7b70e..e1f1096 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -9,3 +9,4 @@ void ui_update_server_list(AppData *ad);
void ui_loading_start(AppData *ad);
void ui_loading_stop(AppData *ad);
+void ui_show_error_dialog(AppData *ad, const char *message);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.