Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小白菜888
Obs Studio
提交
80547455
O
Obs Studio
项目概览
小白菜888
/
Obs Studio
通知
4
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
Obs Studio
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
80547455
编写于
4月 14, 2020
作者:
T
Toasterapp
提交者:
jp9000
9月 08, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rtmp-services: Add SHOWROOM
上级
0ba9b201
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
212 addition
and
0 deletion
+212
-0
plugins/rtmp-services/CMakeLists.txt
plugins/rtmp-services/CMakeLists.txt
+2
-0
plugins/rtmp-services/data/services.json
plugins/rtmp-services/data/services.json
+16
-0
plugins/rtmp-services/rtmp-common.c
plugins/rtmp-services/rtmp-common.c
+18
-0
plugins/rtmp-services/rtmp-services-main.c
plugins/rtmp-services/rtmp-services-main.c
+2
-0
plugins/rtmp-services/showroom.c
plugins/rtmp-services/showroom.c
+163
-0
plugins/rtmp-services/showroom.h
plugins/rtmp-services/showroom.h
+11
-0
未找到文件。
plugins/rtmp-services/CMakeLists.txt
浏览文件 @
80547455
...
...
@@ -10,6 +10,7 @@ set(rtmp-services_SOURCES
twitch.c
younow.c
nimotv.c
showroom.c
rtmp-common.c
rtmp-custom.c
rtmp-services-main.c
)
...
...
@@ -25,6 +26,7 @@ set(rtmp-services_HEADERS
twitch.h
younow.h
nimotv.h
showroom.h
rtmp-format-ver.h
)
set
(
RTMP_SERVICES_URL
...
...
plugins/rtmp-services/data/services.json
浏览文件 @
80547455
...
...
@@ -1756,6 +1756,22 @@
"max video bitrate"
:
20000
,
"max audio bitrate"
:
192
}
},
{
"name"
:
"SHOWROOM"
,
"servers"
:
[
{
"name"
:
"Default"
,
"url"
:
"https://www.showroom-live.com/api/obs/streaming_info?obs_key="
}
],
"recommended"
:
{
"keyint"
:
2
,
"profile"
:
"main"
,
"max video bitrate"
:
1500
,
"max audio bitrate"
:
160
,
"x264opts"
:
"tune=zerolatency"
}
}
]
}
plugins/rtmp-services/rtmp-common.c
浏览文件 @
80547455
...
...
@@ -2,11 +2,13 @@
#include <util/dstr.h>
#include <obs-module.h>
#include <jansson.h>
#include <obs-config.h>
#include "rtmp-format-ver.h"
#include "twitch.h"
#include "younow.h"
#include "nimotv.h"
#include "showroom.h"
struct
rtmp_common
{
char
*
service
;
...
...
@@ -619,12 +621,28 @@ static const char *rtmp_common_url(void *data)
}
}
if
(
service
->
service
&&
strcmp
(
service
->
service
,
"SHOWROOM"
)
==
0
)
{
if
(
service
->
server
&&
service
->
key
)
{
struct
showroom_ingest
*
ingest
;
ingest
=
showroom_get_ingest
(
service
->
server
,
service
->
key
);
return
ingest
->
url
;
}
}
return
service
->
server
;
}
static
const
char
*
rtmp_common_key
(
void
*
data
)
{
struct
rtmp_common
*
service
=
data
;
if
(
service
->
service
&&
strcmp
(
service
->
service
,
"SHOWROOM"
)
==
0
)
{
if
(
service
->
server
&&
service
->
key
)
{
struct
showroom_ingest
*
ingest
;
ingest
=
showroom_get_ingest
(
service
->
server
,
service
->
key
);
return
ingest
->
key
;
}
}
return
service
->
key
;
}
...
...
plugins/rtmp-services/rtmp-services-main.c
浏览文件 @
80547455
...
...
@@ -7,6 +7,7 @@
#include "rtmp-format-ver.h"
#include "lookup-config.h"
#include "showroom.h"
OBS_DECLARE_MODULE
()
OBS_MODULE_USE_DEFAULT_LOCALE
(
"rtmp-services"
,
"en-US"
)
...
...
@@ -107,5 +108,6 @@ void obs_module_unload(void)
{
update_info_destroy
(
update_info
);
unload_twitch_data
();
free_showroom_data
();
dstr_free
(
&
module_name
);
}
plugins/rtmp-services/showroom.c
0 → 100644
浏览文件 @
80547455
#include <util/curl/curl-helper.h>
#include <stdlib.h>
#include <string.h>
#include <jansson.h>
#include <util/dstr.h>
#include <util/darray.h>
#include "util/base.h"
#include <obs-module.h>
#include <util/platform.h>
#include "showroom.h"
#include <util/threading.h>
struct
showroom_ingest_info
{
char
*
access_key
;
uint64_t
last_time
;
struct
showroom_ingest
ingest
;
};
static
DARRAY
(
struct
showroom_ingest_info
)
cur_ingests
=
{
0
};
struct
showroom_ingest
invalid_ingest
=
{
""
,
""
};
void
free_showroom_data
(
void
)
{
for
(
size_t
i
=
0
;
i
<
cur_ingests
.
num
;
i
++
)
{
struct
showroom_ingest_info
*
info
=
&
cur_ingests
.
array
[
i
];
bfree
(
info
->
access_key
);
bfree
((
void
*
)
info
->
ingest
.
key
);
bfree
((
void
*
)
info
->
ingest
.
url
);
}
da_free
(
cur_ingests
);
}
static
size_t
showroom_write_cb
(
void
*
data
,
size_t
size
,
size_t
nmemb
,
void
*
user_pointer
)
{
struct
dstr
*
json
=
user_pointer
;
size_t
realsize
=
size
*
nmemb
;
dstr_ncat
(
json
,
data
,
realsize
);
return
realsize
;
}
static
struct
showroom_ingest_info
*
find_ingest
(
const
char
*
access_key
)
{
struct
showroom_ingest_info
*
ret
=
NULL
;
for
(
size_t
i
=
0
;
i
<
cur_ingests
.
num
;
i
++
)
{
struct
showroom_ingest_info
*
info
=
&
cur_ingests
.
array
[
i
];
if
(
strcmp
(
info
->
access_key
,
access_key
)
==
0
)
{
ret
=
info
;
break
;
}
}
return
ret
;
}
#ifndef SEC_TO_NSEC
#define SEC_TO_NSEC 1000000000ULL
#endif
static
struct
showroom_ingest_info
*
get_ingest_from_json
(
char
*
str
,
const
char
*
access_key
)
{
json_error_t
error
;
json_t
*
root
;
root
=
json_loads
(
str
,
JSON_REJECT_DUPLICATES
,
&
error
);
if
(
!
root
)
{
return
NULL
;
}
const
char
*
url_str
=
json_string_value
(
json_object_get
(
root
,
"streaming_url_rtmp"
));
const
char
*
key_str
=
json_string_value
(
json_object_get
(
root
,
"streaming_key"
));
struct
showroom_ingest_info
*
info
=
find_ingest
(
access_key
);
if
(
!
info
)
{
info
=
da_push_back_new
(
cur_ingests
);
info
->
access_key
=
bstrdup
(
access_key
);
}
bfree
((
void
*
)
info
->
ingest
.
url
);
bfree
((
void
*
)
info
->
ingest
.
key
);
info
->
ingest
.
url
=
bstrdup
(
url_str
);
info
->
ingest
.
key
=
bstrdup
(
key_str
);
info
->
last_time
=
os_gettime_ns
()
/
SEC_TO_NSEC
;
json_decref
(
root
);
return
info
;
}
struct
showroom_ingest
*
showroom_get_ingest
(
const
char
*
server
,
const
char
*
access_key
)
{
struct
showroom_ingest_info
*
info
=
find_ingest
(
access_key
);
CURL
*
curl_handle
;
CURLcode
res
;
struct
dstr
json
=
{
0
};
struct
dstr
uri
=
{
0
};
long
response_code
;
if
(
info
)
{
/* this function is called a bunch of times for the same data,
* so in order to prevent multiple unnecessary queries in a
* short period of time, return the same data for 10 seconds */
uint64_t
ts_sec
=
os_gettime_ns
()
/
SEC_TO_NSEC
;
if
(
ts_sec
-
info
->
last_time
<
10
)
{
return
&
info
->
ingest
;
}
else
{
info
=
NULL
;
}
}
curl_handle
=
curl_easy_init
();
dstr_copy
(
&
uri
,
server
);
dstr_cat
(
&
uri
,
access_key
);
curl_easy_setopt
(
curl_handle
,
CURLOPT_URL
,
uri
.
array
);
curl_easy_setopt
(
curl_handle
,
CURLOPT_SSL_VERIFYPEER
,
true
);
curl_easy_setopt
(
curl_handle
,
CURLOPT_SSL_VERIFYHOST
,
2L
);
curl_easy_setopt
(
curl_handle
,
CURLOPT_TIMEOUT
,
30L
);
curl_easy_setopt
(
curl_handle
,
CURLOPT_WRITEFUNCTION
,
showroom_write_cb
);
curl_easy_setopt
(
curl_handle
,
CURLOPT_WRITEDATA
,
(
void
*
)
&
json
);
curl_obs_set_revoke_setting
(
curl_handle
);
#if LIBCURL_VERSION_NUM >= 0x072400
curl_easy_setopt
(
curl_handle
,
CURLOPT_SSL_ENABLE_ALPN
,
0
);
#endif
res
=
curl_easy_perform
(
curl_handle
);
dstr_free
(
&
uri
);
if
(
res
!=
CURLE_OK
)
{
blog
(
LOG_WARNING
,
"showroom_get_ingest: curl_easy_perform() failed: %s"
,
curl_easy_strerror
(
res
));
goto
cleanup
;
}
curl_easy_getinfo
(
curl_handle
,
CURLINFO_RESPONSE_CODE
,
&
response_code
);
if
(
response_code
!=
200
)
{
blog
(
LOG_WARNING
,
"showroom_get_ingest: curl_easy_perform() returned "
"code: %ld"
,
response_code
);
goto
cleanup
;
}
if
(
json
.
len
==
0
)
{
blog
(
LOG_WARNING
,
"showroom_get_ingest: curl_easy_perform() returned "
"empty response"
);
goto
cleanup
;
}
info
=
get_ingest_from_json
(
json
.
array
,
access_key
);
cleanup:
curl_easy_cleanup
(
curl_handle
);
dstr_free
(
&
json
);
return
info
?
&
info
->
ingest
:
&
invalid_ingest
;
}
plugins/rtmp-services/showroom.h
0 → 100644
浏览文件 @
80547455
#pragma once
struct
showroom_ingest
{
const
char
*
url
;
const
char
*
key
;
};
extern
struct
showroom_ingest
*
showroom_get_ingest
(
const
char
*
server
,
const
char
*
access_key
);
extern
void
free_showroom_data
();
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录