正在显示
3 个修改的文件
包含
120 行增加
和
1 行删除
| @@ -38,6 +38,8 @@ using namespace std; | @@ -38,6 +38,8 @@ using namespace std; | ||
| 38 | #include <srs_kernel_utility.hpp> | 38 | #include <srs_kernel_utility.hpp> |
| 39 | #include <srs_protocol_buffer.hpp> | 39 | #include <srs_protocol_buffer.hpp> |
| 40 | #include <srs_kernel_file.hpp> | 40 | #include <srs_kernel_file.hpp> |
| 41 | +#include <srs_kernel_flv.hpp> | ||
| 42 | +#include <srs_core_autofree.hpp> | ||
| 41 | 43 | ||
| 42 | #define SRS_DEFAULT_HTTP_PORT 80 | 44 | #define SRS_DEFAULT_HTTP_PORT 80 |
| 43 | 45 | ||
| @@ -284,6 +286,29 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* | @@ -284,6 +286,29 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* | ||
| 284 | 286 | ||
| 285 | string fullpath = dir + "/" + upath; | 287 | string fullpath = dir + "/" + upath; |
| 286 | 288 | ||
| 289 | + if (srs_string_ends_with(fullpath, ".flv") || srs_string_ends_with(fullpath, ".fhv")) { | ||
| 290 | + std::string start = r->query_get("start"); | ||
| 291 | + if (start.empty()) { | ||
| 292 | + return serve_file(fullpath, w, r); | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + int offset = ::atoi(start.c_str()); | ||
| 296 | + if (offset <= 0) { | ||
| 297 | + return serve_file(fullpath, w, r); | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + return serve_flv_stream(fullpath, w, r, offset); | ||
| 301 | + } else { | ||
| 302 | + return serve_file(fullpath, w, r); | ||
| 303 | + } | ||
| 304 | + | ||
| 305 | + return ret; | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +int SrsGoHttpFileServer::serve_file(string fullpath, ISrsGoHttpResponseWriter* w, SrsHttpMessage* r) | ||
| 309 | +{ | ||
| 310 | + int ret = ERROR_SUCCESS; | ||
| 311 | + | ||
| 287 | // open the target file. | 312 | // open the target file. |
| 288 | SrsFileReader fs; | 313 | SrsFileReader fs; |
| 289 | 314 | ||
| @@ -338,6 +363,98 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* | @@ -338,6 +363,98 @@ int SrsGoHttpFileServer::serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* | ||
| 338 | return ret; | 363 | return ret; |
| 339 | } | 364 | } |
| 340 | 365 | ||
| 366 | +int SrsGoHttpFileServer::serve_flv_stream(string fullpath, ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, int offset) | ||
| 367 | +{ | ||
| 368 | + int ret = ERROR_SUCCESS; | ||
| 369 | + | ||
| 370 | + SrsFileReader fs; | ||
| 371 | + | ||
| 372 | + // open flv file | ||
| 373 | + if ((ret = fs.open(fullpath)) != ERROR_SUCCESS) { | ||
| 374 | + return ret; | ||
| 375 | + } | ||
| 376 | + | ||
| 377 | + if (offset > fs.filesize()) { | ||
| 378 | + ret = ERROR_HTTP_FLV_OFFSET_OVERFLOW; | ||
| 379 | + srs_warn("http flv streaming %s overflow. size=%"PRId64", offset=%d, ret=%d", | ||
| 380 | + fullpath.c_str(), fs.filesize(), offset, ret); | ||
| 381 | + return ret; | ||
| 382 | + } | ||
| 383 | + | ||
| 384 | + SrsFlvVodStreamDecoder ffd; | ||
| 385 | + | ||
| 386 | + // open fast decoder | ||
| 387 | + if ((ret = ffd.initialize(&fs)) != ERROR_SUCCESS) { | ||
| 388 | + return ret; | ||
| 389 | + } | ||
| 390 | + | ||
| 391 | + // save header, send later. | ||
| 392 | + char flv_header[13]; | ||
| 393 | + | ||
| 394 | + // send flv header | ||
| 395 | + if ((ret = ffd.read_header_ext(flv_header)) != ERROR_SUCCESS) { | ||
| 396 | + return ret; | ||
| 397 | + } | ||
| 398 | + | ||
| 399 | + // save sequence header, send later | ||
| 400 | + char* sh_data = NULL; | ||
| 401 | + int sh_size = 0; | ||
| 402 | + | ||
| 403 | + if (true) { | ||
| 404 | + // send sequence header | ||
| 405 | + int64_t start = 0; | ||
| 406 | + if ((ret = ffd.read_sequence_header_summary(&start, &sh_size)) != ERROR_SUCCESS) { | ||
| 407 | + return ret; | ||
| 408 | + } | ||
| 409 | + if (sh_size <= 0) { | ||
| 410 | + ret = ERROR_HTTP_FLV_SEQUENCE_HEADER; | ||
| 411 | + srs_warn("http flv streaming no sequence header. size=%d, ret=%d", sh_size, ret); | ||
| 412 | + return ret; | ||
| 413 | + } | ||
| 414 | + } | ||
| 415 | + sh_data = new char[sh_size]; | ||
| 416 | + SrsAutoFree(char, sh_data); | ||
| 417 | + if ((ret = fs.read(sh_data, sh_size, NULL)) != ERROR_SUCCESS) { | ||
| 418 | + return ret; | ||
| 419 | + } | ||
| 420 | + | ||
| 421 | + // seek to data offset | ||
| 422 | + int64_t left = fs.filesize() - offset; | ||
| 423 | + | ||
| 424 | + // write http header for ts. | ||
| 425 | + w->header()->set_content_length((int)(sizeof(flv_header) + sh_size + left)); | ||
| 426 | + w->header()->set_content_type("video/x-flv"); | ||
| 427 | + | ||
| 428 | + // write flv header and sequence header. | ||
| 429 | + if ((ret = w->write(flv_header, sizeof(flv_header))) != ERROR_SUCCESS) { | ||
| 430 | + return ret; | ||
| 431 | + } | ||
| 432 | + if (sh_size > 0 && (ret = w->write(sh_data, sh_size)) != ERROR_SUCCESS) { | ||
| 433 | + return ret; | ||
| 434 | + } | ||
| 435 | + | ||
| 436 | + // write body. | ||
| 437 | + char* buf = r->http_ts_send_buffer(); | ||
| 438 | + if ((ret = ffd.lseek(offset)) != ERROR_SUCCESS) { | ||
| 439 | + return ret; | ||
| 440 | + } | ||
| 441 | + | ||
| 442 | + // send data | ||
| 443 | + while (left > 0) { | ||
| 444 | + ssize_t nread = -1; | ||
| 445 | + if ((ret = fs.read(buf, __SRS_HTTP_TS_SEND_BUFFER_SIZE, &nread)) != ERROR_SUCCESS) { | ||
| 446 | + return ret; | ||
| 447 | + } | ||
| 448 | + | ||
| 449 | + left -= nread; | ||
| 450 | + if ((ret = w->write(buf, nread)) != ERROR_SUCCESS) { | ||
| 451 | + return ret; | ||
| 452 | + } | ||
| 453 | + } | ||
| 454 | + | ||
| 455 | + return ret; | ||
| 456 | +} | ||
| 457 | + | ||
| 341 | SrsGoHttpMuxEntry::SrsGoHttpMuxEntry() | 458 | SrsGoHttpMuxEntry::SrsGoHttpMuxEntry() |
| 342 | { | 459 | { |
| 343 | explicit_match = false; | 460 | explicit_match = false; |
| @@ -204,6 +204,9 @@ public: | @@ -204,6 +204,9 @@ public: | ||
| 204 | virtual ~SrsGoHttpFileServer(); | 204 | virtual ~SrsGoHttpFileServer(); |
| 205 | public: | 205 | public: |
| 206 | virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r); | 206 | virtual int serve_http(ISrsGoHttpResponseWriter* w, SrsHttpMessage* r); |
| 207 | +private: | ||
| 208 | + virtual int serve_file(std::string fullpath, ISrsGoHttpResponseWriter* w, SrsHttpMessage* r); | ||
| 209 | + virtual int serve_flv_stream(std::string fullpath, ISrsGoHttpResponseWriter* w, SrsHttpMessage* r, int offset); | ||
| 207 | }; | 210 | }; |
| 208 | 211 | ||
| 209 | // the mux entry for server mux. | 212 | // the mux entry for server mux. |
| @@ -38,7 +38,6 @@ using namespace std; | @@ -38,7 +38,6 @@ using namespace std; | ||
| 38 | #include <srs_app_st_socket.hpp> | 38 | #include <srs_app_st_socket.hpp> |
| 39 | #include <srs_core_autofree.hpp> | 39 | #include <srs_core_autofree.hpp> |
| 40 | #include <srs_app_config.hpp> | 40 | #include <srs_app_config.hpp> |
| 41 | -#include <srs_kernel_flv.hpp> | ||
| 42 | #include <srs_kernel_utility.hpp> | 41 | #include <srs_kernel_utility.hpp> |
| 43 | 42 | ||
| 44 | SrsHttpServer::SrsHttpServer() | 43 | SrsHttpServer::SrsHttpServer() |
-
请 注册 或 登录 后发表评论