2014-04-19 20:54:18 -07:00
|
|
|
#include <util/platform.h>
|
2016-04-09 23:34:16 -07:00
|
|
|
#include <util/dstr.h>
|
2014-04-19 20:54:18 -07:00
|
|
|
#include <obs-module.h>
|
|
|
|
#include <jansson.h>
|
|
|
|
|
2015-08-19 16:19:03 -07:00
|
|
|
#include "rtmp-format-ver.h"
|
2017-08-01 02:41:00 -07:00
|
|
|
#include "twitch.h"
|
2015-08-19 16:19:03 -07:00
|
|
|
|
2014-04-19 20:54:18 -07:00
|
|
|
struct rtmp_common {
|
|
|
|
char *service;
|
|
|
|
char *server;
|
|
|
|
char *key;
|
2017-07-13 03:12:53 -07:00
|
|
|
|
|
|
|
char *output;
|
2014-04-19 20:54:18 -07:00
|
|
|
};
|
|
|
|
|
2015-09-16 01:30:51 -07:00
|
|
|
static const char *rtmp_common_getname(void *unused)
|
2014-04-19 20:54:18 -07:00
|
|
|
{
|
2015-09-16 01:30:51 -07:00
|
|
|
UNUSED_PARAMETER(unused);
|
2014-07-09 22:12:57 -07:00
|
|
|
return obs_module_text("StreamingServices");
|
2014-04-19 20:54:18 -07:00
|
|
|
}
|
|
|
|
|
2017-07-13 03:12:53 -07:00
|
|
|
static json_t *open_services_file(void);
|
|
|
|
static inline json_t *find_service(json_t *root, const char *name);
|
|
|
|
static inline const char *get_string_val(json_t *service, const char *key);
|
|
|
|
|
2017-10-09 10:06:50 -07:00
|
|
|
extern void twitch_ingests_refresh(int seconds);
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void rtmp_common_update(void *data, obs_data_t *settings)
|
2014-04-19 20:54:18 -07:00
|
|
|
{
|
|
|
|
struct rtmp_common *service = data;
|
|
|
|
|
|
|
|
bfree(service->service);
|
|
|
|
bfree(service->server);
|
2017-07-13 03:12:53 -07:00
|
|
|
bfree(service->output);
|
2014-04-19 20:54:18 -07:00
|
|
|
bfree(service->key);
|
|
|
|
|
2014-08-05 11:09:29 -07:00
|
|
|
service->service = bstrdup(obs_data_get_string(settings, "service"));
|
|
|
|
service->server = bstrdup(obs_data_get_string(settings, "server"));
|
|
|
|
service->key = bstrdup(obs_data_get_string(settings, "key"));
|
2017-07-13 03:12:53 -07:00
|
|
|
service->output = NULL;
|
|
|
|
|
|
|
|
json_t *root = open_services_file();
|
|
|
|
if (root) {
|
|
|
|
json_t *serv = find_service(root, service->service);
|
|
|
|
if (serv) {
|
|
|
|
json_t *rec = json_object_get(serv, "recommended");
|
|
|
|
if (rec && json_is_object(rec)) {
|
|
|
|
const char *out = get_string_val(rec, "output");
|
|
|
|
if (out)
|
|
|
|
service->output = bstrdup(out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
json_decref(root);
|
|
|
|
|
|
|
|
if (!service->output)
|
2017-07-17 16:44:42 -07:00
|
|
|
service->output = bstrdup("rtmp_output");
|
2014-04-19 20:54:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void rtmp_common_destroy(void *data)
|
|
|
|
{
|
|
|
|
struct rtmp_common *service = data;
|
|
|
|
|
|
|
|
bfree(service->service);
|
|
|
|
bfree(service->server);
|
2017-07-13 03:12:53 -07:00
|
|
|
bfree(service->output);
|
2014-04-19 20:54:18 -07:00
|
|
|
bfree(service->key);
|
|
|
|
bfree(service);
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void *rtmp_common_create(obs_data_t *settings, obs_service_t *service)
|
2014-04-19 20:54:18 -07:00
|
|
|
{
|
|
|
|
struct rtmp_common *data = bzalloc(sizeof(struct rtmp_common));
|
|
|
|
rtmp_common_update(data, settings);
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(service);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
static inline const char *get_string_val(json_t *service, const char *key)
|
|
|
|
{
|
|
|
|
json_t *str_val = json_object_get(service, key);
|
|
|
|
if (!str_val || !json_is_string(str_val))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return json_string_value(str_val);
|
|
|
|
}
|
|
|
|
|
2015-08-19 15:46:28 -07:00
|
|
|
static inline int get_int_val(json_t *service, const char *key)
|
|
|
|
{
|
|
|
|
json_t *integer_val = json_object_get(service, key);
|
|
|
|
if (!integer_val || !json_is_integer(integer_val))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return (int)json_integer_value(integer_val);
|
|
|
|
}
|
|
|
|
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
static inline bool get_bool_val(json_t *service, const char *key)
|
|
|
|
{
|
|
|
|
json_t *bool_val = json_object_get(service, key);
|
|
|
|
if (!bool_val || !json_is_boolean(bool_val))
|
2015-08-16 10:37:40 -07:00
|
|
|
return false;
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
|
|
|
|
return json_is_true(bool_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void add_service(obs_property_t *list, json_t *service, bool show_all,
|
|
|
|
const char *cur_service)
|
2014-04-19 20:54:18 -07:00
|
|
|
{
|
|
|
|
json_t *servers;
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
const char *name;
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
bool common;
|
2014-04-19 20:54:18 -07:00
|
|
|
|
|
|
|
if (!json_is_object(service)) {
|
|
|
|
blog(LOG_WARNING, "rtmp-common.c: [add_service] service "
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
"is not an object");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
name = get_string_val(service, "name");
|
|
|
|
if (!name) {
|
|
|
|
blog(LOG_WARNING, "rtmp-common.c: [add_service] service "
|
|
|
|
"has no name");
|
2014-04-19 20:54:18 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
common = get_bool_val(service, "common");
|
|
|
|
if (!show_all && !common && strcmp(cur_service, name) != 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-19 20:54:18 -07:00
|
|
|
servers = json_object_get(service, "servers");
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
if (!servers || !json_is_array(servers)) {
|
2014-04-19 20:54:18 -07:00
|
|
|
blog(LOG_WARNING, "rtmp-common.c: [add_service] service "
|
|
|
|
"'%s' has no servers", name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
obs_property_list_add_string(list, name, name);
|
|
|
|
}
|
|
|
|
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
static void add_services(obs_property_t *list, json_t *root, bool show_all,
|
|
|
|
const char *cur_service)
|
2014-04-19 20:54:18 -07:00
|
|
|
{
|
|
|
|
json_t *service;
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
size_t index;
|
2014-04-19 20:54:18 -07:00
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
if (!json_is_array(root)) {
|
2014-04-19 20:54:18 -07:00
|
|
|
blog(LOG_WARNING, "rtmp-common.c: [add_services] JSON file "
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
"root is not an array");
|
2014-04-19 20:54:18 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
json_array_foreach (root, index, service) {
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
add_service(list, service, show_all, cur_service);
|
2014-04-19 20:54:18 -07:00
|
|
|
}
|
2017-05-19 01:14:57 -07:00
|
|
|
|
|
|
|
service = find_service(root, cur_service);
|
|
|
|
if (!service && cur_service && *cur_service) {
|
|
|
|
obs_property_list_insert_string(list, 0, cur_service,
|
|
|
|
cur_service);
|
|
|
|
obs_property_list_item_disable(list, 0, true);
|
|
|
|
}
|
2014-04-19 20:54:18 -07:00
|
|
|
}
|
|
|
|
|
2014-06-16 21:31:36 -07:00
|
|
|
static json_t *open_json_file(const char *file)
|
2014-04-19 20:54:18 -07:00
|
|
|
{
|
|
|
|
char *file_data = os_quick_read_utf8_file(file);
|
|
|
|
json_error_t error;
|
|
|
|
json_t *root;
|
2015-08-19 16:19:03 -07:00
|
|
|
json_t *list;
|
|
|
|
int format_ver;
|
2014-04-19 20:54:18 -07:00
|
|
|
|
|
|
|
if (!file_data)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
root = json_loads(file_data, JSON_REJECT_DUPLICATES, &error);
|
|
|
|
bfree(file_data);
|
|
|
|
|
|
|
|
if (!root) {
|
2014-06-16 21:31:36 -07:00
|
|
|
blog(LOG_WARNING, "rtmp-common.c: [open_json_file] "
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
"Error reading JSON file (%d): %s",
|
|
|
|
error.line, error.text);
|
2014-04-19 20:54:18 -07:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-08-19 16:19:03 -07:00
|
|
|
format_ver = get_int_val(root, "format_version");
|
|
|
|
|
|
|
|
if (format_ver != RTMP_SERVICES_FORMAT_VERSION) {
|
2017-07-14 11:42:58 -07:00
|
|
|
blog(LOG_DEBUG, "rtmp-common.c: [open_json_file] "
|
|
|
|
"Wrong format version (%d), expected %d",
|
|
|
|
format_ver, RTMP_SERVICES_FORMAT_VERSION);
|
2015-08-19 16:19:03 -07:00
|
|
|
json_decref(root);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
list = json_object_get(root, "services");
|
|
|
|
if (list)
|
|
|
|
json_incref(list);
|
|
|
|
json_decref(root);
|
|
|
|
|
|
|
|
if (!list) {
|
|
|
|
blog(LOG_WARNING, "rtmp-common.c: [open_json_file] "
|
|
|
|
"No services list");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
2014-06-16 21:31:36 -07:00
|
|
|
}
|
|
|
|
|
2015-08-19 16:21:58 -07:00
|
|
|
static json_t *open_services_file(void)
|
|
|
|
{
|
|
|
|
char *file;
|
|
|
|
json_t *root = NULL;
|
|
|
|
|
|
|
|
file = obs_module_config_path("services.json");
|
|
|
|
if (file) {
|
|
|
|
root = open_json_file(file);
|
|
|
|
bfree(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!root) {
|
|
|
|
file = obs_module_file("services.json");
|
|
|
|
if (file) {
|
|
|
|
root = open_json_file(file);
|
|
|
|
bfree(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return root;
|
|
|
|
}
|
|
|
|
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
static void build_service_list(obs_property_t *list, json_t *root,
|
|
|
|
bool show_all, const char *cur_service)
|
2014-06-16 21:31:36 -07:00
|
|
|
{
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
obs_property_list_clear(list);
|
|
|
|
add_services(list, root, show_all, cur_service);
|
2014-04-19 20:54:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void properties_data_destroy(void *data)
|
|
|
|
{
|
|
|
|
json_t *root = data;
|
|
|
|
if (root)
|
|
|
|
json_decref(root);
|
|
|
|
}
|
|
|
|
|
2017-08-01 02:41:00 -07:00
|
|
|
static bool fill_twitch_servers_locked(obs_property_t *servers_prop)
|
|
|
|
{
|
|
|
|
size_t count = twitch_ingest_count();
|
|
|
|
|
2017-08-02 13:31:23 -07:00
|
|
|
obs_property_list_add_string(servers_prop,
|
|
|
|
obs_module_text("Server.Auto"), "auto");
|
|
|
|
|
2017-10-09 10:06:50 -07:00
|
|
|
if (count <= 1)
|
|
|
|
return false;
|
|
|
|
|
2017-08-01 02:41:00 -07:00
|
|
|
for (size_t i = 0; i < count; i++) {
|
|
|
|
struct twitch_ingest ing = twitch_ingest(i);
|
|
|
|
obs_property_list_add_string(servers_prop, ing.name, ing.url);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline bool fill_twitch_servers(obs_property_t *servers_prop)
|
|
|
|
{
|
|
|
|
bool success;
|
|
|
|
|
|
|
|
twitch_ingests_lock();
|
|
|
|
success = fill_twitch_servers_locked(servers_prop);
|
|
|
|
twitch_ingests_unlock();
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static void fill_servers(obs_property_t *servers_prop, json_t *service,
|
2014-04-19 20:54:18 -07:00
|
|
|
const char *name)
|
|
|
|
{
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
json_t *servers, *server;
|
|
|
|
size_t index;
|
2014-04-19 20:54:18 -07:00
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
obs_property_list_clear(servers_prop);
|
2014-04-19 20:54:18 -07:00
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
servers = json_object_get(service, "servers");
|
|
|
|
|
|
|
|
if (!json_is_array(servers)) {
|
2014-04-19 20:54:18 -07:00
|
|
|
blog(LOG_WARNING, "rtmp-common.c: [fill_servers] "
|
|
|
|
"Servers for service '%s' not a valid object",
|
|
|
|
name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-07-31 16:16:21 -07:00
|
|
|
if (strcmp(name, "Mixer.com - FTL") == 0) {
|
|
|
|
obs_property_list_add_string(servers_prop,
|
|
|
|
obs_module_text("Server.Auto"), "auto");
|
|
|
|
}
|
2017-08-01 02:41:00 -07:00
|
|
|
if (name && strcmp(name, "Twitch") == 0) {
|
|
|
|
if (fill_twitch_servers(servers_prop))
|
|
|
|
return;
|
|
|
|
}
|
2017-07-31 16:16:21 -07:00
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
json_array_foreach (servers, index, server) {
|
|
|
|
const char *server_name = get_string_val(server, "name");
|
|
|
|
const char *url = get_string_val(server, "url");
|
|
|
|
|
|
|
|
if (!server_name || !url)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
obs_property_list_add_string(servers_prop, server_name, url);
|
2014-04-19 20:54:18 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
static inline json_t *find_service(json_t *root, const char *name)
|
|
|
|
{
|
|
|
|
size_t index;
|
|
|
|
json_t *service;
|
|
|
|
|
|
|
|
json_array_foreach (root, index, service) {
|
|
|
|
const char *cur_name = get_string_val(service, "name");
|
|
|
|
|
|
|
|
if (strcmp(name, cur_name) == 0)
|
|
|
|
return service;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
static bool service_selected(obs_properties_t *props, obs_property_t *p,
|
|
|
|
obs_data_t *settings)
|
2014-04-19 20:54:18 -07:00
|
|
|
{
|
2014-08-05 11:09:29 -07:00
|
|
|
const char *name = obs_data_get_string(settings, "service");
|
2014-04-19 20:54:18 -07:00
|
|
|
json_t *root = obs_properties_get_param(props);
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
json_t *service;
|
|
|
|
|
|
|
|
if (!name || !*name)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
service = find_service(root, name);
|
2017-05-19 01:14:57 -07:00
|
|
|
if (!service) {
|
|
|
|
const char *server = obs_data_get_string(settings, "server");
|
|
|
|
|
|
|
|
obs_property_list_insert_string(p, 0, name, name);
|
|
|
|
obs_property_list_item_disable(p, 0, true);
|
|
|
|
|
|
|
|
p = obs_properties_get(props, "server");
|
|
|
|
obs_property_list_insert_string(p, 0, server, server);
|
|
|
|
obs_property_list_item_disable(p, 0, true);
|
|
|
|
return true;
|
|
|
|
}
|
2014-04-19 20:54:18 -07:00
|
|
|
|
|
|
|
fill_servers(obs_properties_get(props, "server"), service, name);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
static bool show_all_services_toggled(obs_properties_t *ppts,
|
|
|
|
obs_property_t *p, obs_data_t *settings)
|
|
|
|
{
|
|
|
|
const char *cur_service = obs_data_get_string(settings, "service");
|
|
|
|
bool show_all = obs_data_get_bool(settings, "show_all");
|
|
|
|
|
|
|
|
json_t *root = obs_properties_get_param(ppts);
|
|
|
|
if (!root)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
build_service_list(obs_properties_get(ppts, "service"), root, show_all,
|
|
|
|
cur_service);
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(p);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-09-29 08:36:13 -07:00
|
|
|
static obs_properties_t *rtmp_common_properties(void *unused)
|
2014-04-19 20:54:18 -07:00
|
|
|
{
|
2014-09-29 08:36:13 -07:00
|
|
|
UNUSED_PARAMETER(unused);
|
|
|
|
|
2014-09-25 17:44:05 -07:00
|
|
|
obs_properties_t *ppts = obs_properties_create();
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
obs_property_t *p;
|
2015-08-19 16:21:58 -07:00
|
|
|
json_t *root;
|
2014-04-19 20:54:18 -07:00
|
|
|
|
2015-08-19 16:21:58 -07:00
|
|
|
root = open_services_file();
|
|
|
|
if (root)
|
2014-04-19 20:54:18 -07:00
|
|
|
obs_properties_set_param(ppts, root, properties_data_destroy);
|
|
|
|
|
rtmp-services: Add "Show all services" option
I made the rather tough call of not showing all services by default; I
didn't want to have to do this, but too many services are asking to be
put in to the program, and any time I add a service in to the list, I
feel uncomfortable because I feel like I'm potentially advertising them,
and/or they're using our program to advertise as well. Some of these
services are particularly bad at policing illegal/copyrighted content,
host content that I personally find distasteful or incredibly stupid
(what the heck is up with these "vaping" streams?), or are just fairly
terrible websites in general that I just feel uncomfortable with showing
by default.
However, I do not really want to reject anyone either, I want to let
their users be able to use our program with relative ease, but more than
anything I just simple don't want to be seen as "endorsing" some of
these websites (more than others in particular). I know that a "show
all services" checkbox is probably pretty pointless/superfluous thing to
do, but I feel like it's at the very least a means of saying "hey, I
don't really endorse these guys," or "use at your own risk," or
"warning: this website is incredibly terrible."
Honestly, I couldn't really think of any better solution that would
a.) still list all services without outright censoring them, and
b.) prevent us from being seen as "endorsing" all services.
(Although maybe this whole thing feels a bit.. passive aggressive. I
feel like I'm tipping over someone's garden gnome in the middle of the
night while they're sleeping. Still, it's something.)
NOTE: This code is backward compatible; i.e., if you previously had a
service selected that's not common but don't have the "show all"
checkbox checked, it'll still show that service for convenience.
2015-08-14 14:19:20 -07:00
|
|
|
p = obs_properties_add_list(ppts, "service",
|
|
|
|
obs_module_text("Service"),
|
|
|
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
|
|
|
|
|
|
|
|
obs_property_set_modified_callback(p, service_selected);
|
|
|
|
|
|
|
|
p = obs_properties_add_bool(ppts, "show_all",
|
|
|
|
obs_module_text("ShowAll"));
|
|
|
|
|
|
|
|
obs_property_set_modified_callback(p, show_all_services_toggled);
|
|
|
|
|
2014-07-09 22:12:57 -07:00
|
|
|
obs_properties_add_list(ppts, "server", obs_module_text("Server"),
|
2014-04-19 20:54:18 -07:00
|
|
|
OBS_COMBO_TYPE_LIST, OBS_COMBO_FORMAT_STRING);
|
|
|
|
|
2014-07-09 22:12:57 -07:00
|
|
|
obs_properties_add_text(ppts, "key", obs_module_text("StreamKey"),
|
|
|
|
OBS_TEXT_PASSWORD);
|
2014-04-19 20:54:18 -07:00
|
|
|
return ppts;
|
|
|
|
}
|
|
|
|
|
2015-03-07 16:32:00 -08:00
|
|
|
static void apply_video_encoder_settings(obs_data_t *settings,
|
2014-06-16 21:31:36 -07:00
|
|
|
json_t *recommended)
|
|
|
|
{
|
|
|
|
json_t *item = json_object_get(recommended, "keyint");
|
|
|
|
if (item && json_is_integer(item)) {
|
|
|
|
int keyint = (int)json_integer_value(item);
|
2014-08-05 11:09:29 -07:00
|
|
|
obs_data_set_int(settings, "keyint_sec", keyint);
|
2014-06-16 21:31:36 -07:00
|
|
|
}
|
|
|
|
|
2016-05-08 11:19:02 -07:00
|
|
|
obs_data_set_string(settings, "rate_control", "CBR");
|
2014-06-16 21:31:36 -07:00
|
|
|
|
|
|
|
item = json_object_get(recommended, "profile");
|
|
|
|
if (item && json_is_string(item)) {
|
|
|
|
const char *profile = json_string_value(item);
|
2015-01-07 03:16:02 -08:00
|
|
|
obs_data_set_string(settings, "profile", profile);
|
2014-06-16 21:31:36 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
item = json_object_get(recommended, "max video bitrate");
|
|
|
|
if (item && json_is_integer(item)) {
|
|
|
|
int max_bitrate = (int)json_integer_value(item);
|
2014-08-05 11:09:29 -07:00
|
|
|
if (obs_data_get_int(settings, "bitrate") > max_bitrate) {
|
|
|
|
obs_data_set_int(settings, "bitrate", max_bitrate);
|
|
|
|
obs_data_set_int(settings, "buffer_size", max_bitrate);
|
2014-06-16 21:31:36 -07:00
|
|
|
}
|
|
|
|
}
|
2016-04-09 23:34:16 -07:00
|
|
|
|
2017-07-13 03:22:44 -07:00
|
|
|
item = json_object_get(recommended, "bframes");
|
|
|
|
if (item && json_is_integer(item))
|
|
|
|
obs_data_set_int(settings, "bf", 0);
|
|
|
|
|
2016-04-09 23:34:16 -07:00
|
|
|
item = json_object_get(recommended, "x264opts");
|
|
|
|
if (item && json_is_string(item)) {
|
|
|
|
const char *x264_settings = json_string_value(item);
|
|
|
|
const char *cur_settings =
|
|
|
|
obs_data_get_string(settings, "x264opts");
|
|
|
|
struct dstr opts;
|
|
|
|
|
|
|
|
dstr_init_copy(&opts, cur_settings);
|
|
|
|
if (!dstr_is_empty(&opts))
|
|
|
|
dstr_cat(&opts, " ");
|
|
|
|
dstr_cat(&opts, x264_settings);
|
|
|
|
|
|
|
|
obs_data_set_string(settings, "x264opts", opts.array);
|
|
|
|
dstr_free(&opts);
|
|
|
|
}
|
2014-06-16 21:31:36 -07:00
|
|
|
}
|
|
|
|
|
2015-03-07 16:32:00 -08:00
|
|
|
static void apply_audio_encoder_settings(obs_data_t *settings,
|
2014-06-16 21:31:36 -07:00
|
|
|
json_t *recommended)
|
|
|
|
{
|
|
|
|
json_t *item = json_object_get(recommended, "max audio bitrate");
|
|
|
|
if (item && json_is_integer(item)) {
|
|
|
|
int max_bitrate = (int)json_integer_value(item);
|
2014-08-05 11:09:29 -07:00
|
|
|
if (obs_data_get_int(settings, "bitrate") > max_bitrate)
|
|
|
|
obs_data_set_int(settings, "bitrate", max_bitrate);
|
2014-06-16 21:31:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-10 19:27:37 -08:00
|
|
|
static void initialize_output(struct rtmp_common *service, json_t *root,
|
2015-03-07 16:32:00 -08:00
|
|
|
obs_data_t *video_settings, obs_data_t *audio_settings)
|
2014-06-16 21:31:36 -07:00
|
|
|
{
|
|
|
|
json_t *json_service = find_service(root, service->service);
|
|
|
|
json_t *recommended;
|
|
|
|
|
|
|
|
if (!json_service) {
|
|
|
|
blog(LOG_WARNING, "rtmp-common.c: [initialize_output] "
|
|
|
|
"Could not find service '%s'",
|
|
|
|
service->service);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
recommended = json_object_get(json_service, "recommended");
|
|
|
|
if (!recommended)
|
|
|
|
return;
|
|
|
|
|
2015-03-07 16:32:00 -08:00
|
|
|
if (video_settings)
|
|
|
|
apply_video_encoder_settings(video_settings, recommended);
|
|
|
|
if (audio_settings)
|
|
|
|
apply_audio_encoder_settings(audio_settings, recommended);
|
2014-06-16 21:31:36 -07:00
|
|
|
}
|
|
|
|
|
2015-02-10 19:27:37 -08:00
|
|
|
static void rtmp_common_apply_settings(void *data,
|
2015-03-07 16:32:00 -08:00
|
|
|
obs_data_t *video_settings, obs_data_t *audio_settings)
|
2014-06-16 21:31:36 -07:00
|
|
|
{
|
|
|
|
struct rtmp_common *service = data;
|
2015-08-19 16:21:58 -07:00
|
|
|
json_t *root = open_services_file();
|
2014-06-16 21:31:36 -07:00
|
|
|
|
2015-08-19 16:21:58 -07:00
|
|
|
if (root) {
|
|
|
|
initialize_output(service, root, video_settings,
|
|
|
|
audio_settings);
|
|
|
|
json_decref(root);
|
2014-06-16 21:31:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-13 03:12:53 -07:00
|
|
|
static const char *rtmp_common_get_output_type(void *data)
|
|
|
|
{
|
|
|
|
struct rtmp_common *service = data;
|
|
|
|
return service->output;
|
|
|
|
}
|
|
|
|
|
2014-04-19 20:54:18 -07:00
|
|
|
static const char *rtmp_common_url(void *data)
|
|
|
|
{
|
|
|
|
struct rtmp_common *service = data;
|
2017-08-01 02:43:09 -07:00
|
|
|
|
|
|
|
if (service->service && strcmp(service->service, "Twitch") == 0) {
|
|
|
|
if (service->server && strcmp(service->server, "auto") == 0) {
|
|
|
|
struct twitch_ingest ing;
|
|
|
|
|
2017-10-09 10:06:50 -07:00
|
|
|
twitch_ingests_refresh(3);
|
|
|
|
|
2017-08-01 02:43:09 -07:00
|
|
|
twitch_ingests_lock();
|
|
|
|
ing = twitch_ingest(0);
|
|
|
|
twitch_ingests_unlock();
|
|
|
|
|
|
|
|
return ing.url;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-19 20:54:18 -07:00
|
|
|
return service->server;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *rtmp_common_key(void *data)
|
|
|
|
{
|
|
|
|
struct rtmp_common *service = data;
|
|
|
|
return service->key;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct obs_service_info rtmp_common_service = {
|
2014-08-04 21:27:52 -07:00
|
|
|
.id = "rtmp_common",
|
|
|
|
.get_name = rtmp_common_getname,
|
|
|
|
.create = rtmp_common_create,
|
|
|
|
.destroy = rtmp_common_destroy,
|
|
|
|
.update = rtmp_common_update,
|
|
|
|
.get_properties = rtmp_common_properties,
|
|
|
|
.get_url = rtmp_common_url,
|
2015-02-10 19:27:37 -08:00
|
|
|
.get_key = rtmp_common_key,
|
|
|
|
.apply_encoder_settings = rtmp_common_apply_settings,
|
2017-07-13 03:12:53 -07:00
|
|
|
.get_output_type = rtmp_common_get_output_type,
|
2014-04-19 20:54:18 -07:00
|
|
|
};
|