Toggle navigation
Toggle navigation
此项目
正在载入...
Sign in
胡斌
/
srs
转到一个项目
Toggle navigation
项目
群组
代码片段
帮助
Toggle navigation pinning
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
winlin
2014-04-22 17:32:45 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
733ca2475d8bcda0e50ddbde6341e29f40ee46fe
733ca247
1 parent
36d8fdfc
call http api when dvr got keyframe
隐藏空白字符变更
内嵌
并排对比
正在显示
9 个修改的文件
包含
179 行增加
和
58 行删除
trunk/conf/full.conf
trunk/src/app/srs_app_config.cpp
trunk/src/app/srs_app_config.hpp
trunk/src/app/srs_app_dvr.cpp
trunk/src/app/srs_app_dvr.hpp
trunk/src/app/srs_app_http_hooks.cpp
trunk/src/app/srs_app_http_hooks.hpp
trunk/src/app/srs_app_rtmp_conn.cpp
trunk/src/app/srs_app_rtmp_conn.hpp
trunk/conf/full.conf
查看文件 @
733ca24
...
...
@@ -96,6 +96,8 @@ vhost dvr.srs.com {
# dvr RTMP stream to file,
# start to record to file when encoder publish,
# reap flv according by specified dvr_plan.
# http callbacks:
# @see http callback on_dvr_keyframe on http_hooks section.
dvr
{
# whether enabled dvr features
# default: off
...
...
@@ -320,6 +322,19 @@ vhost hooks.callback.srs.com {
# support multiple api hooks, format:
# on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN
on_stop
http
://
127
.
0
.
0
.
1
:
8085
/
api
/
v1
/
sessions
http
://
localhost
:
8085
/
api
/
v1
/
sessions
;
# when dvr got an keyframe, call the hook,
# the request in the POST data string is a object encode by json:
# {
# "action": "on_dvr_keyframe",
# "vhost": "video.test.com", "app": "live",
# "stream": "livestream"
# }
# if valid, the hook must return HTTP code 200(Stauts OK) and response
# an int value specifies the error code(0 corresponding to success):
# 0
# support multiple api hooks, format:
# on_stop http://xxx/api0 http://xxx/api1 http://xxx/apiN
on_dvr_keyframe
http
://
127
.
0
.
0
.
1
:
8085
/
api
/
v1
/
dvrs
http
://
localhost
:
8085
/
api
/
v1
/
dvrs
;
}
}
...
...
trunk/src/app/srs_app_config.cpp
查看文件 @
733ca24
...
...
@@ -1560,6 +1560,27 @@ SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost)
return
conf
->
get
(
"on_stop"
);
}
SrsConfDirective
*
SrsConfig
::
get_vhost_on_dvr_keyframe
(
string
vhost
)
{
SrsConfDirective
*
conf
=
get_vhost
(
vhost
);
if
(
!
conf
)
{
return
NULL
;
}
conf
=
conf
->
get
(
"http_hooks"
);
if
(
!
conf
)
{
return
NULL
;
}
SrsConfDirective
*
enabled
=
conf
->
get
(
"enabled"
);
if
(
!
enabled
||
enabled
->
arg0
()
!=
"on"
)
{
return
NULL
;
}
return
conf
->
get
(
"on_dvr_keyframe"
);
}
bool
SrsConfig
::
get_vhost_enabled
(
string
vhost
)
{
SrsConfDirective
*
vhost_conf
=
get_vhost
(
vhost
);
...
...
trunk/src/app/srs_app_config.hpp
查看文件 @
733ca24
...
...
@@ -173,6 +173,7 @@ public:
virtual
SrsConfDirective
*
get_vhost_on_unpublish
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_vhost_on_play
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_vhost_on_stop
(
std
::
string
vhost
);
virtual
SrsConfDirective
*
get_vhost_on_dvr_keyframe
(
std
::
string
vhost
);
virtual
bool
get_gop_cache
(
std
::
string
vhost
);
virtual
bool
get_atc
(
std
::
string
vhost
);
virtual
double
get_queue_length
(
std
::
string
vhost
);
...
...
trunk/src/app/srs_app_dvr.cpp
查看文件 @
733ca24
...
...
@@ -37,6 +37,8 @@ using namespace std;
#include <srs_core_autofree.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_app_http_hooks.hpp>
#include <srs_app_codec.hpp>
SrsFileStream
::
SrsFileStream
()
{
...
...
@@ -364,34 +366,6 @@ int SrsDvrPlan::on_publish()
return
ret
;
}
int
SrsDvrPlan
::
flv_open
(
string
stream
,
string
path
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
fs
->
open
(
path
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"open file stream for file %s failed. ret=%d"
,
path
.
c_str
(),
ret
);
return
ret
;
}
if
((
ret
=
enc
->
initialize
(
fs
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"initialize enc by fs for file %s failed. ret=%d"
,
path
.
c_str
(),
ret
);
return
ret
;
}
if
((
ret
=
enc
->
write_header
())
!=
ERROR_SUCCESS
)
{
srs_error
(
"write flv header for file %s failed. ret=%d"
,
path
.
c_str
(),
ret
);
return
ret
;
}
srs_trace
(
"dvr stream %s to file %s"
,
stream
.
c_str
(),
path
.
c_str
());
return
ret
;
}
int
SrsDvrPlan
::
flv_close
()
{
return
fs
->
close
();
}
int
SrsDvrPlan
::
on_meta_data
(
SrsOnMetaDataPacket
*
metadata
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -459,6 +433,16 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video)
return
ret
;
}
#ifdef SRS_AUTO_HTTP_CALLBACK
bool
is_key_frame
=
SrsCodec
::
video_is_keyframe
((
int8_t
*
)
payload
,
size
);
srs_verbose
(
"dvr video is key: %d"
,
is_key_frame
);
if
(
is_key_frame
)
{
if
((
ret
=
on_dvr_keyframe
())
!=
ERROR_SUCCESS
)
{
return
ret
;
}
}
#endif
if
((
ret
=
on_video_msg
(
video
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
...
...
@@ -466,6 +450,29 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video)
return
ret
;
}
int
SrsDvrPlan
::
flv_open
(
string
stream
,
string
path
)
{
int
ret
=
ERROR_SUCCESS
;
if
((
ret
=
fs
->
open
(
path
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"open file stream for file %s failed. ret=%d"
,
path
.
c_str
(),
ret
);
return
ret
;
}
if
((
ret
=
enc
->
initialize
(
fs
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"initialize enc by fs for file %s failed. ret=%d"
,
path
.
c_str
(),
ret
);
return
ret
;
}
if
((
ret
=
enc
->
write_header
())
!=
ERROR_SUCCESS
)
{
srs_error
(
"write flv header for file %s failed. ret=%d"
,
path
.
c_str
(),
ret
);
return
ret
;
}
srs_trace
(
"dvr stream %s to file %s"
,
stream
.
c_str
(),
path
.
c_str
());
return
ret
;
}
int
SrsDvrPlan
::
on_audio_msg
(
SrsSharedPtrMessage
*
/*audio*/
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -478,6 +485,32 @@ int SrsDvrPlan::on_video_msg(SrsSharedPtrMessage* /*video*/)
return
ret
;
}
int
SrsDvrPlan
::
flv_close
()
{
return
fs
->
close
();
}
int
SrsDvrPlan
::
on_dvr_keyframe
()
{
int
ret
=
ERROR_SUCCESS
;
#ifdef SRS_AUTO_HTTP_CALLBACK
// HTTP: on_dvr_keyframe
SrsConfDirective
*
on_dvr_keyframe
=
_srs_config
->
get_vhost_on_dvr_keyframe
(
_req
->
vhost
);
if
(
!
on_dvr_keyframe
)
{
srs_info
(
"ignore the empty http callback: on_dvr_keyframe"
);
return
ret
;
}
for
(
int
i
=
0
;
i
<
(
int
)
on_dvr_keyframe
->
args
.
size
();
i
++
)
{
std
::
string
url
=
on_dvr_keyframe
->
args
.
at
(
i
);
SrsHttpHooks
::
on_dvr_keyframe
(
url
,
_req
);
}
#endif
return
ret
;
}
SrsDvrPlan
*
SrsDvrPlan
::
create_plan
(
string
vhost
)
{
std
::
string
plan
=
_srs_config
->
get_dvr_plan
(
vhost
);
...
...
trunk/src/app/srs_app_dvr.hpp
查看文件 @
733ca24
...
...
@@ -146,6 +146,8 @@ protected:
virtual
int
on_audio_msg
(
SrsSharedPtrMessage
*
audio
);
virtual
int
on_video_msg
(
SrsSharedPtrMessage
*
video
);
virtual
int
flv_close
();
private
:
virtual
int
on_dvr_keyframe
();
public
:
static
SrsDvrPlan
*
create_plan
(
std
::
string
vhost
);
};
...
...
trunk/src/app/srs_app_http_hooks.cpp
查看文件 @
733ca24
...
...
@@ -55,7 +55,7 @@ SrsHttpClient::~SrsHttpClient()
srs_freep
(
parser
);
}
int
SrsHttpClient
::
post
(
SrsHttpUri
*
uri
,
st
d
::
string
req
,
std
::
string
&
res
)
int
SrsHttpClient
::
post
(
SrsHttpUri
*
uri
,
st
ring
req
,
string
&
res
)
{
res
=
""
;
...
...
@@ -183,7 +183,7 @@ SrsHttpHooks::~SrsHttpHooks()
{
}
int
SrsHttpHooks
::
on_connect
(
st
d
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
)
int
SrsHttpHooks
::
on_connect
(
st
ring
url
,
int
client_id
,
string
ip
,
SrsRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -236,7 +236,7 @@ int SrsHttpHooks::on_connect(std::string url, int client_id, std::string ip, Srs
return
ret
;
}
void
SrsHttpHooks
::
on_close
(
st
d
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
)
void
SrsHttpHooks
::
on_close
(
st
ring
url
,
int
client_id
,
string
ip
,
SrsRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -289,7 +289,7 @@ void SrsHttpHooks::on_close(std::string url, int client_id, std::string ip, SrsR
return
;
}
int
SrsHttpHooks
::
on_publish
(
st
d
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
)
int
SrsHttpHooks
::
on_publish
(
st
ring
url
,
int
client_id
,
string
ip
,
SrsRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -343,7 +343,7 @@ int SrsHttpHooks::on_publish(std::string url, int client_id, std::string ip, Srs
return
ret
;
}
void
SrsHttpHooks
::
on_unpublish
(
st
d
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
)
void
SrsHttpHooks
::
on_unpublish
(
st
ring
url
,
int
client_id
,
string
ip
,
SrsRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -397,7 +397,7 @@ void SrsHttpHooks::on_unpublish(std::string url, int client_id, std::string ip,
return
;
}
int
SrsHttpHooks
::
on_play
(
st
d
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
)
int
SrsHttpHooks
::
on_play
(
st
ring
url
,
int
client_id
,
string
ip
,
SrsRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -451,7 +451,7 @@ int SrsHttpHooks::on_play(std::string url, int client_id, std::string ip, SrsReq
return
ret
;
}
void
SrsHttpHooks
::
on_stop
(
st
d
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
)
void
SrsHttpHooks
::
on_stop
(
st
ring
url
,
int
client_id
,
string
ip
,
SrsRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -505,4 +505,54 @@ void SrsHttpHooks::on_stop(std::string url, int client_id, std::string ip, SrsRe
return
;
}
void
SrsHttpHooks
::
on_dvr_keyframe
(
string
url
,
SrsRequest
*
req
)
{
int
ret
=
ERROR_SUCCESS
;
SrsHttpUri
uri
;
if
((
ret
=
uri
.
initialize
(
url
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"http uri parse on_dvr_keyframe url failed, ignored. "
"url=%s, ret=%d"
,
url
.
c_str
(),
ret
);
return
;
}
/**
{
"action": "on_dvr_keyframe",
"vhost": "video.test.com", "app": "live",
"stream": "livestream"
}
*/
std
::
stringstream
ss
;
ss
<<
JOBJECT_START
<<
JFIELD_STR
(
"action"
,
"on_dvr_keyframe"
)
<<
JFIELD_CONT
<<
JFIELD_STR
(
"vhost"
,
req
->
vhost
)
<<
JFIELD_CONT
<<
JFIELD_STR
(
"app"
,
req
->
app
)
<<
JFIELD_CONT
<<
JFIELD_STR
(
"stream"
,
req
->
stream
)
<<
JOBJECT_END
;
std
::
string
data
=
ss
.
str
();
std
::
string
res
;
SrsHttpClient
http
;
if
((
ret
=
http
.
post
(
&
uri
,
data
,
res
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"http post on_dvr_keyframe uri failed, ignored. "
"url=%s, request=%s, response=%s, ret=%d"
,
url
.
c_str
(),
data
.
c_str
(),
res
.
c_str
(),
ret
);
return
;
}
if
(
res
.
empty
()
||
res
!=
SRS_HTTP_RESPONSE_OK
)
{
ret
=
ERROR_HTTP_DATA_INVLIAD
;
srs_warn
(
"http hook on_dvr_keyframe validate failed, ignored. "
"res=%s, ret=%d"
,
res
.
c_str
(),
ret
);
return
;
}
srs_trace
(
"http hook on_dvr_keyframe success. "
"url=%s, request=%s, response=%s, ret=%d"
,
url
.
c_str
(),
data
.
c_str
(),
res
.
c_str
(),
ret
);
return
;
}
#endif
...
...
trunk/src/app/srs_app_http_hooks.hpp
查看文件 @
733ca24
...
...
@@ -71,8 +71,9 @@ private:
*/
class
SrsHttpHooks
{
p
ublic
:
p
rivate
:
SrsHttpHooks
();
public
:
virtual
~
SrsHttpHooks
();
public
:
/**
...
...
@@ -82,14 +83,14 @@ public:
* ignore if empty.
* @return valid failed or connect to the url failed.
*/
virtual
int
on_connect
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
static
int
on_connect
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
/**
* on_close hook, when client disconnect to srs, where client is valid by on_connect.
* @param client_id the id of client on server.
* @param url the api server url, to process the event.
* ignore if empty.
*/
virtual
void
on_close
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
static
void
on_close
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
/**
* on_publish hook, when client(encoder) start to publish stream
* @param client_id the id of client on server.
...
...
@@ -97,14 +98,14 @@ public:
* ignore if empty.
* @return valid failed or connect to the url failed.
*/
virtual
int
on_publish
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
static
int
on_publish
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
/**
* on_unpublish hook, when client(encoder) stop publish stream.
* @param client_id the id of client on server.
* @param url the api server url, to process the event.
* ignore if empty.
*/
virtual
void
on_unpublish
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
static
void
on_unpublish
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
/**
* on_play hook, when client start to play stream.
* @param client_id the id of client on server.
...
...
@@ -112,14 +113,21 @@ public:
* ignore if empty.
* @return valid failed or connect to the url failed.
*/
virtual
int
on_play
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
static
int
on_play
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
/**
* on_stop hook, when client stop to play the stream.
* @param client_id the id of client on server.
* @param url the api server url, to process the event.
* ignore if empty.
*/
virtual
void
on_stop
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
static
void
on_stop
(
std
::
string
url
,
int
client_id
,
std
::
string
ip
,
SrsRequest
*
req
);
public
:
/**
* on_dvr_keyframe hook, when dvr get keyframe.
* @param url the api server url, to process the event.
* ignore if empty.
*/
static
void
on_dvr_keyframe
(
std
::
string
url
,
SrsRequest
*
req
);
};
#endif
...
...
trunk/src/app/srs_app_rtmp_conn.cpp
查看文件 @
733ca24
...
...
@@ -68,9 +68,6 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd)
skt
=
new
SrsSocket
(
client_stfd
);
rtmp
=
new
SrsRtmpServer
(
skt
);
refer
=
new
SrsRefer
();
#ifdef SRS_AUTO_HTTP_CALLBACK
http_hooks
=
new
SrsHttpHooks
();
#endif
bandwidth
=
new
SrsBandwidth
();
duration
=
0
;
...
...
@@ -86,9 +83,6 @@ SrsRtmpConn::~SrsRtmpConn()
srs_freep
(
rtmp
);
srs_freep
(
skt
);
srs_freep
(
refer
);
#ifdef SRS_AUTO_HTTP_CALLBACK
srs_freep
(
http_hooks
);
#endif
srs_freep
(
bandwidth
);
}
...
...
@@ -730,7 +724,7 @@ int SrsRtmpConn::on_connect()
{
int
ret
=
ERROR_SUCCESS
;
#ifdef SRS_AUTO_HTTP_CALLBACK
#ifdef SRS_AUTO_HTTP_CALLBACK
// HTTP: on_connect
SrsConfDirective
*
on_connect
=
_srs_config
->
get_vhost_on_connect
(
req
->
vhost
);
if
(
!
on_connect
)
{
...
...
@@ -740,7 +734,7 @@ int SrsRtmpConn::on_connect()
for
(
int
i
=
0
;
i
<
(
int
)
on_connect
->
args
.
size
();
i
++
)
{
std
::
string
url
=
on_connect
->
args
.
at
(
i
);
if
((
ret
=
http_hooks
->
on_connect
(
url
,
connection_id
,
ip
,
req
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
SrsHttpHooks
::
on_connect
(
url
,
connection_id
,
ip
,
req
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hook client on_connect failed. url=%s, ret=%d"
,
url
.
c_str
(),
ret
);
return
ret
;
}
...
...
@@ -763,7 +757,7 @@ void SrsRtmpConn::on_close()
for
(
int
i
=
0
;
i
<
(
int
)
on_close
->
args
.
size
();
i
++
)
{
std
::
string
url
=
on_close
->
args
.
at
(
i
);
http_hooks
->
on_close
(
url
,
connection_id
,
ip
,
req
);
SrsHttpHooks
::
on_close
(
url
,
connection_id
,
ip
,
req
);
}
#endif
}
...
...
@@ -782,7 +776,7 @@ int SrsRtmpConn::on_publish()
for
(
int
i
=
0
;
i
<
(
int
)
on_publish
->
args
.
size
();
i
++
)
{
std
::
string
url
=
on_publish
->
args
.
at
(
i
);
if
((
ret
=
http_hooks
->
on_publish
(
url
,
connection_id
,
ip
,
req
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
SrsHttpHooks
::
on_publish
(
url
,
connection_id
,
ip
,
req
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hook client on_publish failed. url=%s, ret=%d"
,
url
.
c_str
(),
ret
);
return
ret
;
}
...
...
@@ -805,7 +799,7 @@ void SrsRtmpConn::on_unpublish()
for
(
int
i
=
0
;
i
<
(
int
)
on_unpublish
->
args
.
size
();
i
++
)
{
std
::
string
url
=
on_unpublish
->
args
.
at
(
i
);
http_hooks
->
on_unpublish
(
url
,
connection_id
,
ip
,
req
);
SrsHttpHooks
::
on_unpublish
(
url
,
connection_id
,
ip
,
req
);
}
#endif
}
...
...
@@ -824,7 +818,7 @@ int SrsRtmpConn::on_play()
for
(
int
i
=
0
;
i
<
(
int
)
on_play
->
args
.
size
();
i
++
)
{
std
::
string
url
=
on_play
->
args
.
at
(
i
);
if
((
ret
=
http_hooks
->
on_play
(
url
,
connection_id
,
ip
,
req
))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
SrsHttpHooks
::
on_play
(
url
,
connection_id
,
ip
,
req
))
!=
ERROR_SUCCESS
)
{
srs_error
(
"hook client on_play failed. url=%s, ret=%d"
,
url
.
c_str
(),
ret
);
return
ret
;
}
...
...
@@ -847,7 +841,7 @@ void SrsRtmpConn::on_stop()
for
(
int
i
=
0
;
i
<
(
int
)
on_stop
->
args
.
size
();
i
++
)
{
std
::
string
url
=
on_stop
->
args
.
at
(
i
);
http_hooks
->
on_stop
(
url
,
connection_id
,
ip
,
req
);
SrsHttpHooks
::
on_stop
(
url
,
connection_id
,
ip
,
req
);
}
#endif
...
...
trunk/src/app/srs_app_rtmp_conn.hpp
查看文件 @
733ca24
...
...
@@ -58,9 +58,6 @@ private:
SrsSocket
*
skt
;
SrsRtmpServer
*
rtmp
;
SrsRefer
*
refer
;
#ifdef SRS_AUTO_HTTP_CALLBACK
SrsHttpHooks
*
http_hooks
;
#endif
SrsBandwidth
*
bandwidth
;
// elapse duration in ms
// for live play duration, for instance, rtmpdump to record.
...
...
请
注册
或
登录
后发表评论