1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

for #299, srs http server support dash vod stream over mp4 range. 2.0.103

This commit is contained in:
winlin 2015-01-23 13:45:59 +08:00
parent e0ee8de2fb
commit 73cfdea332
5 changed files with 64 additions and 50 deletions

View file

@ -306,51 +306,9 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
// handle file according to its extension. // handle file according to its extension.
// use vod stream for .flv/.fhv // use vod stream for .flv/.fhv
if (srs_string_ends_with(fullpath, ".flv") || srs_string_ends_with(fullpath, ".fhv")) { if (srs_string_ends_with(fullpath, ".flv") || srs_string_ends_with(fullpath, ".fhv")) {
std::string start = r->query_get("start"); return serve_flv_file(w, r, fullpath);
if (start.empty()) {
return serve_file(w, r, fullpath);
}
int offset = ::atoi(start.c_str());
if (offset <= 0) {
return serve_file(w, r, fullpath);
}
return serve_flv_stream(w, r, fullpath, offset);
} else if (srs_string_ends_with(fullpath, ".mp4")) { } else if (srs_string_ends_with(fullpath, ".mp4")) {
// for flash to request mp4 range in query string. return serve_mp4_file(w, r, fullpath);
// for example, http://digitalprimates.net/dash/DashTest.html?url=http://dashdemo.edgesuite.net/digitalprimates/nexus/oops-20120802-manifest.mpd
std::string range = r->query_get("range");
// or, use bytes to request range,
// for example, http://dashas.castlabs.com/demo/try.html
if (range.empty()) {
range = r->query_get("bytes");
}
// rollback to serve whole file.
size_t pos = string::npos;
if (range.empty() || (pos = range.find("-")) == string::npos) {
return serve_file(w, r, fullpath);
}
// parse the start in query string
int start = 0;
if (pos > 0) {
start = ::atoi(range.substr(0, pos).c_str());
}
// parse end in query string.
int end = -1;
if (pos < range.length() - 1) {
end = ::atoi(range.substr(pos + 1).c_str());
}
// invalid param, serve as whole mp4 file.
if (start < 0 || (end != -1 && start > end)) {
return serve_file(w, r, fullpath);
}
return serve_mp4_range(w, r, fullpath, start, end);
} }
// serve common static file. // serve common static file.
@ -427,12 +385,64 @@ int SrsGoHttpFileServer::serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
return w->final_request(); return w->final_request();
} }
int SrsGoHttpFileServer::serve_flv_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath)
{
std::string start = r->query_get("start");
if (start.empty()) {
return serve_file(w, r, fullpath);
}
int offset = ::atoi(start.c_str());
if (offset <= 0) {
return serve_file(w, r, fullpath);
}
return serve_flv_stream(w, r, fullpath, offset);
}
int SrsGoHttpFileServer::serve_mp4_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath)
{
// for flash to request mp4 range in query string.
// for example, http://digitalprimates.net/dash/DashTest.html?url=http://dashdemo.edgesuite.net/digitalprimates/nexus/oops-20120802-manifest.mpd
std::string range = r->query_get("range");
// or, use bytes to request range,
// for example, http://dashas.castlabs.com/demo/try.html
if (range.empty()) {
range = r->query_get("bytes");
}
// rollback to serve whole file.
size_t pos = string::npos;
if (range.empty() || (pos = range.find("-")) == string::npos) {
return serve_file(w, r, fullpath);
}
// parse the start in query string
int start = 0;
if (pos > 0) {
start = ::atoi(range.substr(0, pos).c_str());
}
// parse end in query string.
int end = -1;
if (pos < range.length() - 1) {
end = ::atoi(range.substr(pos + 1).c_str());
}
// invalid param, serve as whole mp4 file.
if (start < 0 || (end != -1 && start > end)) {
return serve_file(w, r, fullpath);
}
return serve_mp4_stream(w, r, fullpath, start, end);
}
int SrsGoHttpFileServer::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset) int SrsGoHttpFileServer::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int offset)
{ {
return serve_file(w, r, fullpath); return serve_file(w, r, fullpath);
} }
int SrsGoHttpFileServer::serve_mp4_range(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end) int SrsGoHttpFileServer::serve_mp4_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end)
{ {
return serve_file(w, r, fullpath); return serve_file(w, r, fullpath);
} }

View file

@ -149,6 +149,7 @@ public:
// will trigger an implicit WriteHeader(http.StatusOK). // will trigger an implicit WriteHeader(http.StatusOK).
// Thus explicit calls to WriteHeader are mainly used to // Thus explicit calls to WriteHeader are mainly used to
// send error codes. // send error codes.
// @remark, user must set header then write or write_header.
virtual void write_header(int code) = 0; virtual void write_header(int code) = 0;
}; };
@ -211,11 +212,14 @@ public:
virtual ~SrsGoHttpFileServer(); virtual ~SrsGoHttpFileServer();
public: public:
virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r); virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r);
protected: private:
/** /**
* serve the file by specified path * serve the file by specified path
*/ */
virtual int serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath); virtual int serve_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
virtual int serve_flv_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
virtual int serve_mp4_file(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath);
protected:
/** /**
* when access flv file with x.flv?start=xxx * when access flv file with x.flv?start=xxx
*/ */
@ -226,7 +230,7 @@ protected:
* @param end the end offset in bytes. -1 to end of file. * @param end the end offset in bytes. -1 to end of file.
* @remark response data in [start, end]. * @remark response data in [start, end].
*/ */
virtual int serve_mp4_range(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end); virtual int serve_mp4_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end);
protected: protected:
/** /**
* copy the fs to response writer in size bytes. * copy the fs to response writer in size bytes.

View file

@ -141,7 +141,7 @@ int SrsVodStream::serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage*
return ret; return ret;
} }
int SrsVodStream::serve_mp4_range(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end) int SrsVodStream::serve_mp4_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, string fullpath, int start, int end)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;

View file

@ -66,7 +66,7 @@ public:
virtual ~SrsVodStream(); virtual ~SrsVodStream();
protected: protected:
virtual int serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int offset); virtual int serve_flv_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int offset);
virtual int serve_mp4_range(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end); virtual int serve_mp4_stream(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, std::string fullpath, int start, int end);
}; };
/** /**

View file

@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version // current release version
#define VERSION_MAJOR 2 #define VERSION_MAJOR 2
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_REVISION 102 #define VERSION_REVISION 103
// server info. // server info.
#define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_KEY "SRS"