aboutsummaryrefslogtreecommitdiffstats
path: root/vlc_input.c
diff options
context:
space:
mode:
authorMatthias Braendli <matthias.braendli@u-blox.com>2015-06-18 14:00:00 +0200
committerMatthias Braendli <matthias.braendli@u-blox.com>2015-06-18 14:00:00 +0200
commit1c31d2937cd67c0e5e2f9cbc9dc48f5ae7d893ea (patch)
treea6db52c86c018d5f587bd1de5858e32f27b51f15 /vlc_input.c
parent1e2a3730e9833f4bac850f89e552f023b7eec3f1 (diff)
downloadtoolame-dab-1c31d2937cd67c0e5e2f9cbc9dc48f5ae7d893ea.tar.gz
toolame-dab-1c31d2937cd67c0e5e2f9cbc9dc48f5ae7d893ea.tar.bz2
toolame-dab-1c31d2937cd67c0e5e2f9cbc9dc48f5ae7d893ea.zip
Add write ICY text into file
Diffstat (limited to 'vlc_input.c')
-rw-r--r--vlc_input.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/vlc_input.c b/vlc_input.c
index 8d96652..c3e1c4f 100644
--- a/vlc_input.c
+++ b/vlc_input.c
@@ -1,5 +1,7 @@
#include <stdlib.h>
+#include <errno.h>
#include <pthread.h>
+#include <semaphore.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
@@ -18,6 +20,23 @@ unsigned int vlc_channels;
struct vlc_buffer *head_buffer;
+// now playing information can get written to
+// a file. This writing happens in a separate thread
+#define NOWPLAYING_LEN 512
+char vlc_nowplaying[NOWPLAYING_LEN];
+int vlc_nowplaying_running;
+pthread_t vlc_nowplaying_thread;
+const char* vlc_nowplaying_filename;
+
+struct icywriter_task_data {
+ char text[NOWPLAYING_LEN];
+ int success;
+ sem_t sem;
+};
+
+struct icywriter_task_data icy_task_data;
+
+
pthread_mutex_t buffer_lock = PTHREAD_MUTEX_INITIALIZER;
struct vlc_buffer* vlc_buffer_new()
@@ -135,10 +154,15 @@ int vlc_in_prepare(
unsigned verbosity,
unsigned int rate,
const char* uri,
- unsigned channels)
+ unsigned channels,
+ const char* icy_write_file
+ )
{
fprintf(stderr, "Initialising VLC...\n");
+ vlc_nowplaying_running = 0;
+ vlc_nowplaying_filename = icy_write_file;
+
long long int handleStream_address;
long long int prepareRender_address;
@@ -286,11 +310,76 @@ ssize_t vlc_in_read(void *buf, size_t len)
st == libvlc_Playing) ) {
return -1;
}
+
+ char* nowplaying_sz = libvlc_media_get_meta(media, libvlc_meta_NowPlaying);
+ if (nowplaying_sz) {
+ snprintf(vlc_nowplaying, NOWPLAYING_LEN, "%s", nowplaying_sz);
+ free(nowplaying_sz);
+ }
}
abort();
}
+// This task is run in a separate thread
+void* vlc_in_write_icy_task(void* arg)
+{
+ struct icywriter_task_data* data = arg;
+
+ FILE* fd = fopen(vlc_nowplaying_filename, "wb");
+ if (fd) {
+ int ret = fputs(data->text, fd);
+ fclose(fd);
+
+ if (ret >= 0) {
+ data->success = 1;
+ }
+ }
+ else {
+ data->success = 0;
+ }
+
+ sem_post(&data->sem);
+}
+
+void vlc_in_write_icy(void)
+{
+ if (vlc_nowplaying_filename == NULL) {
+ return;
+ }
+ else if (vlc_nowplaying_running == 0) {
+ memcpy(icy_task_data.text, vlc_nowplaying, NOWPLAYING_LEN);
+ icy_task_data.success = 0;
+
+ int ret = sem_init(&icy_task_data.sem, 0, 0);
+ if (ret == 0) {
+ ret = pthread_create(&vlc_nowplaying_thread, NULL, vlc_in_write_icy_task, &icy_task_data);
+ }
+ else {
+ fprintf(stderr, "ICY Text writer: semaphore init failed: %s\n", strerror(errno));
+ }
+
+ if (ret == 0) {
+ vlc_nowplaying_running = 1;
+ }
+ else {
+ fprintf(stderr, "ICY Text writer: thread start failed: %s\n", strerror(ret));
+ }
+ }
+ else {
+ int ret = sem_trywait(&icy_task_data.sem);
+ if (ret == -1 && errno == EAGAIN) {
+ return;
+ }
+ else if (ret == 0) {
+ ret = pthread_join(vlc_nowplaying_thread, NULL);
+ vlc_nowplaying_running = 0;
+ }
+
+ return ret;
+ }
+}
+
/* VLC up to version 2.1.0 used a different callback function signature.
* VLC 2.2.0 uses size_t