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
2015-01-18 09:12:53 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
c695a8fcbd7d3dd7937632393ab61891fd5fbe09
c695a8fc
1 parent
e71bc0cb
refine code for #277, extract the flv vod stream.
显示空白字符变更
内嵌
并排对比
正在显示
4 个修改的文件
包含
147 行增加
和
103 行删除
trunk/src/app/srs_app_http.cpp
trunk/src/app/srs_app_http.hpp
trunk/src/app/srs_app_http_conn.cpp
trunk/src/app/srs_app_http_conn.hpp
trunk/src/app/srs_app_http.cpp
查看文件 @
c695a8f
...
...
@@ -38,7 +38,6 @@ using namespace std;
#include <srs_kernel_utility.hpp>
#include <srs_protocol_buffer.hpp>
#include <srs_kernel_file.hpp>
#include <srs_kernel_flv.hpp>
#include <srs_core_autofree.hpp>
#define SRS_DEFAULT_HTTP_PORT 80
...
...
@@ -289,23 +288,23 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
if
(
srs_string_ends_with
(
fullpath
,
".flv"
)
||
srs_string_ends_with
(
fullpath
,
".fhv"
))
{
std
::
string
start
=
r
->
query_get
(
"start"
);
if
(
start
.
empty
())
{
return
serve_file
(
fullpath
,
w
,
r
);
return
serve_file
(
w
,
r
,
fullpath
);
}
int
offset
=
::
atoi
(
start
.
c_str
());
if
(
offset
<=
0
)
{
return
serve_file
(
fullpath
,
w
,
r
);
return
serve_file
(
w
,
r
,
fullpath
);
}
return
serve_flv_stream
(
fullpath
,
w
,
r
,
offset
);
return
serve_flv_stream
(
w
,
r
,
fullpath
,
offset
);
}
else
{
return
serve_file
(
fullpath
,
w
,
r
);
return
serve_file
(
w
,
r
,
fullpath
);
}
return
ret
;
}
int
SrsGoHttpFileServer
::
serve_file
(
string
fullpath
,
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
)
int
SrsGoHttpFileServer
::
serve_file
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
string
fullpath
)
{
int
ret
=
ERROR_SUCCESS
;
...
...
@@ -345,110 +344,35 @@ int SrsGoHttpFileServer::serve_file(string fullpath, ISrsGoHttpResponseWriter* w
// write body.
int64_t
left
=
length
;
char
*
buf
=
r
->
http_ts_send_buffer
();
while
(
left
>
0
)
{
ssize_t
nread
=
-
1
;
if
((
ret
=
fs
.
read
(
buf
,
__SRS_HTTP_TS_SEND_BUFFER_SIZE
,
&
nread
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"read file %s failed, ret=%d"
,
fullpath
.
c_str
(),
ret
);
break
;
}
left
-=
nread
;
if
((
ret
=
w
->
write
(
buf
,
nread
))
!=
ERROR_SUCCESS
)
{
break
;
}
if
((
ret
=
copy
(
&
fs
,
w
,
r
,
left
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"read file=%s size=%d failed, ret=%d"
,
fullpath
.
c_str
(),
left
,
ret
);
return
ret
;
}
return
ret
;
}
int
SrsGoHttpFileServer
::
serve_flv_stream
(
string
fullpath
,
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
int
offset
)
int
SrsGoHttpFileServer
::
serve_flv_stream
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
string
fullpath
,
int
offset
)
{
int
ret
=
ERROR_SUCCESS
;
SrsFileReader
fs
;
// open flv file
if
((
ret
=
fs
.
open
(
fullpath
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
offset
>
fs
.
filesize
())
{
ret
=
ERROR_HTTP_FLV_OFFSET_OVERFLOW
;
srs_warn
(
"http flv streaming %s overflow. size=%"
PRId64
", offset=%d, ret=%d"
,
fullpath
.
c_str
(),
fs
.
filesize
(),
offset
,
ret
);
return
ret
;
}
SrsFlvVodStreamDecoder
ffd
;
// open fast decoder
if
((
ret
=
ffd
.
initialize
(
&
fs
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// save header, send later.
char
flv_header
[
13
];
// send flv header
if
((
ret
=
ffd
.
read_header_ext
(
flv_header
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// save sequence header, send later
char
*
sh_data
=
NULL
;
int
sh_size
=
0
;
if
(
true
)
{
// send sequence header
int64_t
start
=
0
;
if
((
ret
=
ffd
.
read_sequence_header_summary
(
&
start
,
&
sh_size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
sh_size
<=
0
)
{
ret
=
ERROR_HTTP_FLV_SEQUENCE_HEADER
;
srs_warn
(
"http flv streaming no sequence header. size=%d, ret=%d"
,
sh_size
,
ret
);
return
ret
;
}
}
sh_data
=
new
char
[
sh_size
];
SrsAutoFree
(
char
,
sh_data
);
if
((
ret
=
fs
.
read
(
sh_data
,
sh_size
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// seek to data offset
int64_t
left
=
fs
.
filesize
()
-
offset
;
// write http header for ts.
w
->
header
()
->
set_content_length
((
int
)(
sizeof
(
flv_header
)
+
sh_size
+
left
));
w
->
header
()
->
set_content_type
(
"video/x-flv"
);
return
serve_file
(
w
,
r
,
fullpath
);
}
// write flv header and sequence header.
if
((
ret
=
w
->
write
(
flv_header
,
sizeof
(
flv_header
)))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
sh_size
>
0
&&
(
ret
=
w
->
write
(
sh_data
,
sh_size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
int
SrsGoHttpFileServer
::
copy
(
SrsFileReader
*
fs
,
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
int
size
)
{
int
ret
=
ERROR_SUCCESS
;
// write body.
int
left
=
size
;
char
*
buf
=
r
->
http_ts_send_buffer
();
if
((
ret
=
ffd
.
lseek
(
offset
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// send data
while
(
left
>
0
)
{
ssize_t
nread
=
-
1
;
if
((
ret
=
fs
.
read
(
buf
,
__SRS_HTTP_TS_SEND_BUFFER_SIZE
,
&
nread
))
!=
ERROR_SUCCESS
)
{
return
ret
;
if
((
ret
=
fs
->
read
(
buf
,
__SRS_HTTP_TS_SEND_BUFFER_SIZE
,
&
nread
))
!=
ERROR_SUCCESS
)
{
break
;
}
left
-=
nread
;
if
((
ret
=
w
->
write
(
buf
,
nread
))
!=
ERROR_SUCCESS
)
{
return
ret
;
break
;
}
}
...
...
trunk/src/app/srs_app_http.hpp
查看文件 @
c695a8f
...
...
@@ -40,12 +40,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <srs_app_st.hpp>
class
SrsSimpleBuffer
;
class
SrsRequest
;
class
SrsStSocket
;
class
SrsHttpUri
;
class
SrsHttpMessage
;
class
SrsHttpHandler
;
class
SrsFileReader
;
class
SrsSimpleBuffer
;
class
ISrsGoHttpResponseWriter
;
// http specification
...
...
@@ -197,16 +197,27 @@ public:
// http.Handle("/", SrsGoHttpFileServer("static-dir"))
class
SrsGoHttpFileServer
:
public
ISrsGoHttpHandler
{
pr
ivate
:
pr
otected
:
std
::
string
dir
;
public
:
SrsGoHttpFileServer
(
std
::
string
root_dir
);
virtual
~
SrsGoHttpFileServer
();
public
:
virtual
int
serve_http
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
private
:
virtual
int
serve_file
(
std
::
string
fullpath
,
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
);
virtual
int
serve_flv_stream
(
std
::
string
fullpath
,
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
int
offset
);
protected
:
/**
* serve the file by specified path.
*/
virtual
int
serve_file
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
std
::
string
fullpath
);
/**
* when access flv file with start=xxx.
*/
virtual
int
serve_flv_stream
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
std
::
string
fullpath
,
int
offset
);
protected
:
/**
* copy the fs to response writer in size bytes.
*/
virtual
int
copy
(
SrsFileReader
*
fs
,
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
int
size
);
};
// the mux entry for server mux.
...
...
trunk/src/app/srs_app_http_conn.cpp
查看文件 @
c695a8f
...
...
@@ -39,6 +39,101 @@ using namespace std;
#include <srs_core_autofree.hpp>
#include <srs_app_config.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_kernel_file.hpp>
#include <srs_kernel_flv.hpp>
SrsVodStream
::
SrsVodStream
(
string
root_dir
)
:
SrsGoHttpFileServer
(
root_dir
)
{
}
SrsVodStream
::~
SrsVodStream
()
{
}
int
SrsVodStream
::
serve_flv_stream
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
string
fullpath
,
int
offset
)
{
int
ret
=
ERROR_SUCCESS
;
SrsFileReader
fs
;
// open flv file
if
((
ret
=
fs
.
open
(
fullpath
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
offset
>
fs
.
filesize
())
{
ret
=
ERROR_HTTP_FLV_OFFSET_OVERFLOW
;
srs_warn
(
"http flv streaming %s overflow. size=%"
PRId64
", offset=%d, ret=%d"
,
fullpath
.
c_str
(),
fs
.
filesize
(),
offset
,
ret
);
return
ret
;
}
SrsFlvVodStreamDecoder
ffd
;
// open fast decoder
if
((
ret
=
ffd
.
initialize
(
&
fs
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// save header, send later.
char
flv_header
[
13
];
// send flv header
if
((
ret
=
ffd
.
read_header_ext
(
flv_header
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// save sequence header, send later
char
*
sh_data
=
NULL
;
int
sh_size
=
0
;
if
(
true
)
{
// send sequence header
int64_t
start
=
0
;
if
((
ret
=
ffd
.
read_sequence_header_summary
(
&
start
,
&
sh_size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
sh_size
<=
0
)
{
ret
=
ERROR_HTTP_FLV_SEQUENCE_HEADER
;
srs_warn
(
"http flv streaming no sequence header. size=%d, ret=%d"
,
sh_size
,
ret
);
return
ret
;
}
}
sh_data
=
new
char
[
sh_size
];
SrsAutoFree
(
char
,
sh_data
);
if
((
ret
=
fs
.
read
(
sh_data
,
sh_size
,
NULL
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// seek to data offset
int64_t
left
=
fs
.
filesize
()
-
offset
;
// write http header for ts.
w
->
header
()
->
set_content_length
((
int
)(
sizeof
(
flv_header
)
+
sh_size
+
left
));
w
->
header
()
->
set_content_type
(
"video/x-flv"
);
// write flv header and sequence header.
if
((
ret
=
w
->
write
(
flv_header
,
sizeof
(
flv_header
)))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
if
(
sh_size
>
0
&&
(
ret
=
w
->
write
(
sh_data
,
sh_size
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// write body.
if
((
ret
=
ffd
.
lseek
(
offset
))
!=
ERROR_SUCCESS
)
{
return
ret
;
}
// send data
if
((
ret
=
copy
(
&
fs
,
w
,
r
,
left
))
!=
ERROR_SUCCESS
)
{
srs_warn
(
"read flv=%s size=%d failed, ret=%d"
,
fullpath
.
c_str
(),
left
,
ret
);
return
ret
;
}
return
ret
;
}
SrsHttpServer
::
SrsHttpServer
()
{
...
...
@@ -71,7 +166,7 @@ int SrsHttpServer::initialize()
std
::
string
mount
=
_srs_config
->
get_vhost_http_mount
(
vhost
);
std
::
string
dir
=
_srs_config
->
get_vhost_http_dir
(
vhost
);
if
((
ret
=
mux
.
handle
(
mount
,
new
Srs
GoHttpFileServer
(
dir
)))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
mux
.
handle
(
mount
,
new
Srs
VodStream
(
dir
)))
!=
ERROR_SUCCESS
)
{
srs_error
(
"http: mount dir=%s for vhost=%s failed. ret=%d"
,
dir
.
c_str
(),
vhost
.
c_str
(),
ret
);
return
ret
;
}
...
...
@@ -84,7 +179,7 @@ int SrsHttpServer::initialize()
if
(
!
default_root_exists
)
{
// add root
std
::
string
dir
=
_srs_config
->
get_http_stream_dir
();
if
((
ret
=
mux
.
handle
(
"/"
,
new
Srs
GoHttpFileServer
(
dir
)))
!=
ERROR_SUCCESS
)
{
if
((
ret
=
mux
.
handle
(
"/"
,
new
Srs
VodStream
(
dir
)))
!=
ERROR_SUCCESS
)
{
srs_error
(
"http: mount root dir=%s failed. ret=%d"
,
dir
.
c_str
(),
ret
);
return
ret
;
}
...
...
trunk/src/app/srs_app_http_conn.hpp
查看文件 @
c695a8f
...
...
@@ -41,7 +41,21 @@ class SrsHttpParser;
class
SrsHttpMessage
;
class
SrsHttpHandler
;
// for http server.
/**
* the flv vod stream supports flv?start=offset-bytes.
* for example, http://server/file.flv?start=10240
* server will write flv header and sequence header,
* then seek(10240) and response flv tag data.
*/
class
SrsVodStream
:
public
SrsGoHttpFileServer
{
public
:
SrsVodStream
(
std
::
string
root_dir
);
virtual
~
SrsVodStream
();
protected
:
virtual
int
serve_flv_stream
(
ISrsGoHttpResponseWriter
*
w
,
SrsHttpMessage
*
r
,
std
::
string
fullpath
,
int
offset
);
};
class
SrsHttpServer
{
public
:
...
...
请
注册
或
登录
后发表评论