diff --git a/NEWS b/NEWS index 3d8353a..ef144bb 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,7 @@ Changes in 1.0.2, released on XXXX-XX-XX: + * Add support for setting an RFC 5646 language tag on streams via the + option * Fix a crash, if metadata placeholders are configured for input files that do not contain the respective values. From gui-lux on Github (#16). * Fix a crash in one instance of querying the metadata program. From taku0220 diff --git a/doc/ezstream.1.in.in b/doc/ezstream.1.in.in index 2c9c8c3..1b4bf4b 100644 --- a/doc/ezstream.1.in.in +++ b/doc/ezstream.1.in.in @@ -359,6 +359,15 @@ stream input media files as-is. The configured encoder's output stream format must match what is configured in .Sy \& . +.It Sy \& +RFC 5646 language tag, such as +.Em en-US , +describing the target audience +.Pq not necessarily the actual content +language(s) of the stream. +.Pp +Default: +.Em none .It Sy \& Informational name of the broadcast. .Pp diff --git a/examples/ezstream-full.xml b/examples/ezstream-full.xml index 07e20be..89e9f3d 100644 --- a/examples/ezstream-full.xml +++ b/examples/ezstream-full.xml @@ -114,6 +114,9 @@ OggEnc-Q1.5 + + en-US, i-klingon + Test Stream http://localhost:8000/ diff --git a/src/cfg_stream.c b/src/cfg_stream.c index 7aa6df8..3d13784 100644 --- a/src/cfg_stream.c +++ b/src/cfg_stream.c @@ -43,6 +43,7 @@ struct cfg_stream { char *stream_bitrate; char *stream_samplerate; char *stream_channels; + char *language_tag; }; TAILQ_HEAD(cfg_stream_list, cfg_stream); @@ -162,6 +163,7 @@ cfg_stream_destroy(struct cfg_stream **s_p) xfree(s->stream_bitrate); xfree(s->stream_samplerate); xfree(s->stream_channels); + xfree(s->language_tag); xfree(s); *s_p = NULL; } @@ -383,6 +385,16 @@ cfg_stream_set_stream_channels(struct cfg_stream *s, return (0); } +int +cfg_stream_set_language_tag(struct cfg_stream *s, + struct cfg_stream_list *not_used, const char *language_tag, + const char **errstrp) +{ + (void)not_used; + SET_XSTRDUP(s->language_tag, language_tag, errstrp); + return (0); +} + int cfg_stream_validate(struct cfg_stream *s, const char **errstrp) { @@ -490,3 +502,9 @@ cfg_stream_get_stream_channels(struct cfg_stream *s) { return (s->stream_channels); } + +const char * +cfg_stream_get_language_tag(struct cfg_stream *s) +{ + return (s->language_tag); +} diff --git a/src/cfg_stream.h b/src/cfg_stream.h index 2df6b83..6a8da08 100644 --- a/src/cfg_stream.h +++ b/src/cfg_stream.h @@ -86,6 +86,8 @@ int cfg_stream_set_stream_samplerate(cfg_stream_t, cfg_stream_list_t, const char *, const char **); int cfg_stream_set_stream_channels(cfg_stream_t, cfg_stream_list_t, const char *, const char **); +int cfg_stream_set_language_tag(cfg_stream_t, cfg_stream_list_t, + const char *, const char **); int cfg_stream_validate(cfg_stream_t, const char **); @@ -120,5 +122,7 @@ const char * cfg_stream_get_stream_samplerate(cfg_stream_t); const char * cfg_stream_get_stream_channels(cfg_stream_t); +const char * + cfg_stream_get_language_tag(cfg_stream_t); #endif /* __CFG_STREAM_H__ */ diff --git a/src/cfgfile_xml.c b/src/cfgfile_xml.c index 37e9e1f..a7a8901 100644 --- a/src/cfgfile_xml.c +++ b/src/cfgfile_xml.c @@ -163,6 +163,7 @@ _cfgfile_xml_parse_stream(xmlDocPtr doc, xmlNodePtr cur) XML_STREAM_SET(s, sl, cfg_stream_set_stream_bitrate, "stream_bitrate"); XML_STREAM_SET(s, sl, cfg_stream_set_stream_samplerate, "stream_samplerate"); XML_STREAM_SET(s, sl, cfg_stream_set_stream_channels, "stream_channels"); + XML_STREAM_SET(s, sl, cfg_stream_set_language_tag, "language_tag"); } if (0 > cfg_stream_validate(s, &errstr)) { diff --git a/src/stream.c b/src/stream.c index 02906fb..7ca70e3 100644 --- a/src/stream.c +++ b/src/stream.c @@ -257,6 +257,13 @@ _stream_cfg_stream(struct stream *s, cfg_stream_t cfg_stream) s->name, cfg_stream_get_format_str(cfg_stream)); return (-1); } + if (cfg_stream_get_language_tag(cfg_stream) && + SHOUTERR_SUCCESS != + shout_set_content_language(s->shout, cfg_stream_get_language_tag(cfg_stream))) { + log_error("stream: %s: language: %s", + s->name, shout_get_error(s->shout)); + return (-1); + } if (SHOUTERR_SUCCESS != shout_set_public(s->shout, (unsigned int)cfg_stream_get_public(cfg_stream))) { log_error("stream: %s: public: %s", diff --git a/tests/check_cfg_stream.c b/tests/check_cfg_stream.c index e2e27a4..eea037b 100644 --- a/tests/check_cfg_stream.c +++ b/tests/check_cfg_stream.c @@ -200,6 +200,13 @@ START_TEST(test_stream_stream_channels) } END_TEST +START_TEST(test_stream_language_tag) +{ + TEST_XSTRDUP_T(cfg_stream_t, cfg_stream_list_get, streams, + cfg_stream_set_language_tag, cfg_stream_get_language_tag); +} +END_TEST + START_TEST(test_stream_validate) { cfg_stream_t str = cfg_stream_list_get(streams, "test_stream_validate"); @@ -244,6 +251,7 @@ cfg_suite(void) tcase_add_test(tc_stream, test_stream_stream_bitrate); tcase_add_test(tc_stream, test_stream_stream_samplerate); tcase_add_test(tc_stream, test_stream_stream_channels); + tcase_add_test(tc_stream, test_stream_language_tag); tcase_add_test(tc_stream, test_stream_validate); suite_add_tcase(s, tc_stream); diff --git a/tests/check_stream.c b/tests/check_stream.c index 59c63d6..257847f 100644 --- a/tests/check_stream.c +++ b/tests/check_stream.c @@ -72,6 +72,7 @@ START_TEST(test_stream) ck_assert_int_eq(cfg_stream_set_stream_bitrate(str_cfg, streams, "test", NULL), 0); ck_assert_int_eq(cfg_stream_set_stream_samplerate(str_cfg, streams, "test", NULL), 0); ck_assert_int_eq(cfg_stream_set_stream_channels(str_cfg, streams, "test", NULL), 0); + ck_assert_int_eq(cfg_stream_set_language_tag(str_cfg, streams, "test", NULL), 0); ck_assert_int_eq(cfg_stream_set_public(str_cfg, streams, "true", NULL), 0); ck_assert_int_eq(stream_configure(s), 0);