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);