diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 6142d0c0fa..73b6de1241 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -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, diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index 56e48cb2e0..45a1f6fdd3 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -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; } diff --git a/src/mod/formats/mod_local_stream/mod_local_stream.c b/src/mod/formats/mod_local_stream/mod_local_stream.c index bb5c094fa9..749fd522dc 100644 --- a/src/mod/formats/mod_local_stream/mod_local_stream.c +++ b/src/mod/formats/mod_local_stream/mod_local_stream.c @@ -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) diff --git a/src/switch_core_video.c b/src/switch_core_video.c index bd9733850b..1625a54112 100644 --- a/src/switch_core_video.c +++ b/src/switch_core_video.c @@ -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; }