]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-7656 parse metadata from files and put video banner up if artist or title is set
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 19 Jun 2015 23:00:43 +0000 (18:00 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 19 Jun 2015 23:00:47 +0000 (18:00 -0500)
src/include/switch_utils.h
src/mod/applications/mod_av/avformat.c
src/mod/formats/mod_local_stream/mod_local_stream.c
src/switch_core_video.c

index 6142d0c0fab6d6a7a2eff1685665a6e5c88bb8ad..73b6de12415633a1a85bff1cf10b385b84a7ee8c 100644 (file)
@@ -1115,6 +1115,35 @@ static inline switch_bool_t switch_is_file_path(const char *file)
 }
 
 
+static inline const char *switch_parse_audio_col(switch_audio_col_t col)
+{
+       const char *field = NULL;
+
+       switch (col) {
+       case SWITCH_AUDIO_COL_STR_TITLE:
+               field = "title";
+               break;
+       case SWITCH_AUDIO_COL_STR_COMMENT:
+               field = "comment";
+               break;
+       case SWITCH_AUDIO_COL_STR_ARTIST:
+               field = "artist";
+               break;
+       case SWITCH_AUDIO_COL_STR_DATE:
+               field = "date";
+               break;
+       case SWITCH_AUDIO_COL_STR_SOFTWARE:
+               field = "software";
+               break;
+       case SWITCH_AUDIO_COL_STR_COPYRIGHT:
+               field = "copyright";
+               break;
+       default:
+               break;
+       }
+
+       return field;
+}
 
 SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask, uint32_t *bitp);
 SWITCH_DECLARE(switch_status_t) switch_network_list_create(switch_network_list_t **list, const char *name, switch_bool_t default_type,
index 56e48cb2e0a76744084080b1a8320292f14fdaff..45a1f6fdd3c22c3afb843e58ee8647ec71f5a9a8 100644 (file)
@@ -1879,11 +1879,35 @@ end:
 
 static switch_status_t av_file_set_string(switch_file_handle_t *handle, switch_audio_col_t col, const char *string)
 {
+       av_file_context_t *context = (av_file_context_t *)handle->private_info;
+
+       if (context->fc) {
+               const char *field = switch_parse_audio_col(col);
+
+               printf("WTF [%s][%s]\n", field, string);
+               if (field) {
+                       av_dict_set(&context->fc->metadata, field, string, 0);
+                       return SWITCH_STATUS_SUCCESS;
+               }
+       }
+
        return SWITCH_STATUS_FALSE;
 }
 
 static switch_status_t av_file_get_string(switch_file_handle_t *handle, switch_audio_col_t col, const char **string)
 {
+       av_file_context_t *context = (av_file_context_t *)handle->private_info;
+
+       if (context->fc) {
+               AVDictionaryEntry *tag = NULL;
+               const char *field = switch_parse_audio_col(col);
+
+               if (field && (tag = av_dict_get(context->fc->metadata, field, tag, 0))) {
+                       *string = tag->value;
+                       return SWITCH_STATUS_SUCCESS;
+               }
+       }
+
        return SWITCH_STATUS_FALSE;
 }
 
index bb5c094fa9779893b89d47bf745de6b8762e50b7..749fd522dc0a264f0627b745af82cf722977dc6b 100644 (file)
@@ -68,6 +68,8 @@ struct local_stream_context {
        int sent_png;
        int last_w;
        int last_h;
+       switch_image_t *banner_img;
+       switch_time_t banner_timeout;
        struct local_stream_context *next;
 };
 
@@ -107,6 +109,7 @@ struct local_stream_source {
        int has_video;
        switch_image_t *blank_img;
        switch_image_t *cover_art;
+       char *banner_txt;
 };
 
 typedef struct local_stream_source local_stream_source_t;
@@ -217,6 +220,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
                while (RUNNING && !source->stopped) {
                        switch_size_t olen;
                        uint8_t abuf[SWITCH_RECOMMENDED_BUFFER_SIZE] = { 0 };
+                       const char *artist = NULL, *title = NULL;
 
                        if (fd > -1) {
                                char *p;
@@ -268,6 +272,13 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
                                continue;
                        }
 
+                       if (switch_core_timer_init(&timer, source->timer_name, source->interval, (int)source->samples, temp_pool) != SWITCH_STATUS_SUCCESS) {
+                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't start timer.\n");
+                               switch_dir_close(source->dir_handle);
+                               source->dir_handle = NULL;
+                               goto done;
+                       }
+
                        switch_img_free(&source->cover_art);
                        switch_set_string(tmp_buf, path_buf);
                        if ((p = strrchr(tmp_buf, '/'))) {
@@ -278,11 +289,20 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
                                }
                        }
                        
-                       if (switch_core_timer_init(&timer, source->timer_name, source->interval, (int)source->samples, temp_pool) != SWITCH_STATUS_SUCCESS) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't start timer.\n");
-                               switch_dir_close(source->dir_handle);
-                               source->dir_handle = NULL;
-                               goto done;
+                       switch_safe_free(source->banner_txt);
+                       title = artist = NULL;
+                       
+                       switch_core_file_get_string(&fh, SWITCH_AUDIO_COL_STR_ARTIST, &artist);
+                       switch_core_file_get_string(&fh, SWITCH_AUDIO_COL_STR_TITLE, &title);
+                       
+                       if (title && (source->cover_art || switch_core_file_has_video(&fh))) {
+                               const char *format = "#cccccc:#333333:FreeSans.ttf:3%:";
+
+                               if (artist) {
+                                       source->banner_txt = switch_mprintf("%s%s (%s)", format, title, artist);
+                               } else {
+                                       source->banner_txt = switch_mprintf("%s%s", format, title);
+                               }
                        }
 
                        while (RUNNING && !source->stopped) {
@@ -322,7 +342,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
 
                          retry:
 
-                               source->has_video = switch_core_file_has_video(use_fh);
+                               source->has_video = switch_core_file_has_video(use_fh) || source->cover_art || source->banner_txt;
 
                                is_open = switch_test_flag(use_fh, SWITCH_FILE_OPEN);
 
@@ -524,6 +544,8 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
 
   done:
 
+       switch_safe_free(source->banner_txt);
+       
        if (switch_test_flag((&fh), SWITCH_FILE_OPEN)) {
                switch_core_file_close(&fh);
        }
@@ -632,7 +654,8 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
                goto end;
        }
 
-       if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) && !source->has_video) {
+       if (!switch_core_has_video() || 
+               (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) && !source->has_video && !source->blank_img && !source->cover_art && !source->banner_txt)) {
                switch_clear_flag(handle, SWITCH_FILE_FLAG_VIDEO);
        }
 
@@ -683,6 +706,8 @@ static switch_status_t local_stream_file_close(switch_file_handle_t *handle)
                }
        }
 
+       switch_img_free(&context->banner_img);
+       
        context->source->total--;
        switch_mutex_unlock(context->source->mutex);
        switch_buffer_destroy(&context->audio_buffer);
@@ -696,6 +721,7 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
        void *pop;
        local_stream_context_t *context = handle->private_info;
        switch_status_t status;
+       switch_time_t now;
 
        if (!(context->ready && context->source->ready)) {
                return SWITCH_STATUS_FALSE;
@@ -724,7 +750,7 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
                                }
 
                                frame->img = img;
-                               return SWITCH_STATUS_SUCCESS;
+                               goto got_img;
                        }
                }
                return SWITCH_STATUS_IGNORE;
@@ -760,10 +786,41 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
                context->sent_png = 0;
                context->last_w = frame->img->d_w;
                context->last_h = frame->img->d_h;
-               return SWITCH_STATUS_SUCCESS;
+               goto got_img;
        }
 
        return (flags & SVR_FLUSH) ? SWITCH_STATUS_BREAK : status;
+
+ got_img:
+
+       now = switch_micro_time_now();
+
+       if (context->banner_img) {
+               if (now >= context->banner_timeout) {
+                       switch_img_free(&context->banner_img);
+               }
+       }
+
+       if (context->source->banner_txt) {
+               if ((!context->banner_timeout || context->banner_timeout >= now)) {
+                       if (!context->banner_img) {
+                               context->banner_img = switch_img_write_text_img(context->last_w, context->last_h, SWITCH_TRUE, context->source->banner_txt);
+                               context->banner_timeout = now + 5000000;
+                       }
+               }
+       } else {
+               if (context->banner_img) {
+                       switch_img_free(&context->banner_img);
+               }
+               context->banner_timeout = 0;
+       }
+
+       if (frame->img && context->banner_img && frame->img->d_w >= context->banner_img->d_w) {
+               //switch_img_overlay(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h, 100);
+               switch_img_patch(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h);
+       }
+       
+       return SWITCH_STATUS_SUCCESS;
 }
 
 static switch_status_t local_stream_file_read(switch_file_handle_t *handle, void *data, size_t *len)
index bd9733850b8767f4c660c9d3cc90001d3b4e802f..1625a541126e30c488d2f56b4d5df5abf01844ff 100644 (file)
@@ -473,7 +473,6 @@ SWITCH_DECLARE(void) switch_img_get_yuv_pixel(switch_image_t *img, switch_yuv_co
 {
 #ifdef SWITCH_HAVE_YUV         
        // switch_assert(img->fmt == SWITCH_IMG_FMT_I420);
-
        if (x < 0 || y < 0 || x >= img->d_w || y >= img->d_h) return;
 
        yuv->y = *(img->planes[SWITCH_PLANE_Y] + img->stride[SWITCH_PLANE_Y] * y + x);
@@ -1010,19 +1009,19 @@ SWITCH_DECLARE(switch_image_t *) switch_img_write_text_img(int w, int h, switch_
        if (strchr(text, ':')) {
                argc = switch_split(duptxt, ':', argv);
                
-               if (argc > 0) {
+               if (argc > 0 && !zstr(argv[0])) {
                        fg = argv[0];
                }
 
-               if (argc > 1) {
+               if (argc > 1 && !zstr(argv[1])) {
                        bg = argv[1];
                }
                
-               if (argc > 2) {
+               if (argc > 2 && !zstr(argv[2])) {
                        font_face = argv[2];
                }
                
-               if (argc > 3) {
+               if (argc > 3 && !zstr(argv[3])) {
                        fontsz = argv[3];
                }
 
@@ -1084,6 +1083,7 @@ SWITCH_DECLARE(switch_image_t *) switch_img_write_text_img(int w, int h, switch_
                                  x, y,
                                  txt, NULL, fg, bg, 0, 0);
        switch_img_txt_handle_destroy(&txthandle);
+
        return txtimg;
 }