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

update dvr, support segment plan

This commit is contained in:
winlin 2014-04-17 17:35:21 +08:00
parent 6f19a83114
commit 2d1c28cff9
7 changed files with 230 additions and 23 deletions

View file

@ -26,6 +26,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifdef SRS_AUTO_DVR
#include <fcntl.h>
#include <sstream>
using namespace std;
#include <srs_app_config.hpp>
@ -35,6 +36,7 @@ using namespace std;
#include <srs_app_source.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_kernel_utility.hpp>
SrsFileStream::SrsFileStream()
{
@ -302,7 +304,7 @@ SrsDvrPlan::~SrsDvrPlan()
srs_freep(enc);
}
int SrsDvrPlan::initialize(SrsSource* source)
int SrsDvrPlan::initialize(SrsSource* source, SrsRequest* /*req*/)
{
int ret = ERROR_SUCCESS;
@ -401,9 +403,16 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video)
return ret;
}
SrsDvrPlan* SrsDvrPlan::create_plan()
SrsDvrPlan* SrsDvrPlan::create_plan(string vhost)
{
return new SrsDvrSessionPlan();
std::string plan = _srs_config->get_dvr_plan(vhost);
if (plan == SRS_CONF_DEFAULT_DVR_PLAN_SEGMENT) {
return new SrsDvrSegmentPlan();
} else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_SESSION) {
return new SrsDvrSessionPlan();
} else {
return new SrsDvrSessionPlan();
}
}
SrsDvrSessionPlan::SrsDvrSessionPlan()
@ -427,14 +436,13 @@ int SrsDvrSessionPlan::on_publish(SrsRequest* req)
return ret;
}
std::string path = _srs_config->get_dvr_path(req->vhost);
path += "/";
path += req->app;
path += "/";
path += req->stream;
path += ".flv";
std::stringstream path;
if ((ret = flv_open(req->get_stream_url(), path)) != ERROR_SUCCESS) {
path << _srs_config->get_dvr_path(req->vhost)
<< "/" << req->app << "/"
<< req->stream << "." << srs_get_system_time_ms() << ".flv";
if ((ret = flv_open(req->get_stream_url(), path.str())) != ERROR_SUCCESS) {
return ret;
}
dvr_enabled = true;
@ -458,6 +466,132 @@ void SrsDvrSessionPlan::on_unpublish()
dvr_enabled = false;
}
SrsDvrSegmentPlan::SrsDvrSegmentPlan()
{
starttime = -1;
duration = 0;
segment_duration = -1;
}
SrsDvrSegmentPlan::~SrsDvrSegmentPlan()
{
}
int SrsDvrSegmentPlan::initialize(SrsSource* source, SrsRequest* req)
{
int ret = ERROR_SUCCESS;
if ((ret = SrsDvrPlan::initialize(source, req)) != ERROR_SUCCESS) {
return ret;
}
segment_duration = _srs_config->get_dvr_duration(req->vhost);
// to ms
segment_duration *= 1000;
return ret;
}
int SrsDvrSegmentPlan::on_publish(SrsRequest* req)
{
int ret = ERROR_SUCCESS;
// support multiple publish.
if (dvr_enabled) {
return ret;
}
if (!_srs_config->get_dvr_enabled(req->vhost)) {
return ret;
}
std::stringstream path;
path << _srs_config->get_dvr_path(req->vhost)
<< "/" << req->app << "/"
<< req->stream << "." << srs_get_system_time_ms() << ".flv";
if ((ret = flv_open(req->get_stream_url(), path.str())) != ERROR_SUCCESS) {
return ret;
}
dvr_enabled = true;
return ret;
}
void SrsDvrSegmentPlan::on_unpublish()
{
// support multiple publish.
if (!dvr_enabled) {
return;
}
// ignore error.
int ret = flv_close();
if (ret != ERROR_SUCCESS) {
srs_warn("ignore flv close error. ret=%d", ret);
}
dvr_enabled = false;
}
int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* audio)
{
int ret = ERROR_SUCCESS;
if (!dvr_enabled) {
return ret;
}
if ((ret = update_duration(audio)) != ERROR_SUCCESS) {
return ret;
}
if ((ret = SrsDvrPlan::on_audio(audio)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage* video)
{
int ret = ERROR_SUCCESS;
if (!dvr_enabled) {
return ret;
}
if ((ret = update_duration(video)) != ERROR_SUCCESS) {
return ret;
}
if ((ret = SrsDvrPlan::on_video(video)) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
{
int ret = ERROR_SUCCESS;
// foreach msg, collect the duration.
if (starttime < 0 || starttime > msg->header.timestamp) {
starttime = msg->header.timestamp;
}
duration += msg->header.timestamp - starttime;
starttime = msg->header.timestamp;
// reap if exceed duration.
if (duration > 0 && segment_duration > 0 && duration > segment_duration) {
on_unpublish();
}
return ret;
}
SrsDvr::SrsDvr(SrsSource* source)
{
_source = source;
@ -469,14 +603,14 @@ SrsDvr::~SrsDvr()
srs_freep(plan);
}
int SrsDvr::initialize()
int SrsDvr::initialize(SrsRequest* req)
{
int ret = ERROR_SUCCESS;
srs_freep(plan);
plan = SrsDvrPlan::create_plan();
plan = SrsDvrPlan::create_plan(req->vhost);
if ((ret = plan->initialize(_source)) != ERROR_SUCCESS) {
if ((ret = plan->initialize(_source, req)) != ERROR_SUCCESS) {
return ret;
}