mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
fix #179: dvr support custom filepath by variables. 2.0.87
This commit is contained in:
parent
f89941254a
commit
f881bc43b5
10 changed files with 215 additions and 27 deletions
|
@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#include <fcntl.h>
|
||||
#include <sstream>
|
||||
#include <sys/time.h>
|
||||
using namespace std;
|
||||
|
||||
#include <srs_app_config.hpp>
|
||||
|
@ -136,14 +137,97 @@ int SrsDvrPlan::open_new_segment()
|
|||
|
||||
SrsRequest* req = _req;
|
||||
|
||||
// new flv file
|
||||
std::stringstream path;
|
||||
// the path in config, for example,
|
||||
// /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv
|
||||
std::string path_config = _srs_config->get_dvr_path(req->vhost);
|
||||
|
||||
path << _srs_config->get_dvr_path(req->vhost)
|
||||
<< "/" << req->app << "/"
|
||||
<< req->stream << "." << srs_get_system_time_ms() << ".flv";
|
||||
// add [stream].[timestamp].flv as filename for dir
|
||||
if (path_config.find(".flv") != path_config.length() - 4) {
|
||||
path_config += "/[stream].[timestamp].flv";
|
||||
}
|
||||
|
||||
if ((ret = flv_open(req->get_stream_url(), path.str())) != ERROR_SUCCESS) {
|
||||
// the flv file path
|
||||
std::string path = path_config;
|
||||
|
||||
// variable [vhost]
|
||||
path = srs_string_replace(path, "[vhost]", req->vhost);
|
||||
// variable [app]
|
||||
path = srs_string_replace(path, "[app]", req->app);
|
||||
// variable [stream]
|
||||
path = srs_string_replace(path, "[stream]", req->stream);
|
||||
|
||||
// date and time substitude
|
||||
// clock time
|
||||
timeval tv;
|
||||
if (gettimeofday(&tv, NULL) == -1) {
|
||||
return ERROR_SYSTEM_TIME;
|
||||
}
|
||||
|
||||
// to calendar time
|
||||
struct tm* tm;
|
||||
if ((tm = localtime(&tv.tv_sec)) == NULL) {
|
||||
return ERROR_SYSTEM_TIME;
|
||||
}
|
||||
|
||||
// the buffer to format the date and time.
|
||||
char buf[64];
|
||||
|
||||
// [2006], replace with current year.
|
||||
if (true) {
|
||||
snprintf(buf, sizeof(buf), "%d", 1900 + tm->tm_year);
|
||||
path = srs_string_replace(path, "[2006]", buf);
|
||||
}
|
||||
// [2006], replace with current year.
|
||||
if (true) {
|
||||
snprintf(buf, sizeof(buf), "%d", 1900 + tm->tm_year);
|
||||
path = srs_string_replace(path, "[2006]", buf);
|
||||
}
|
||||
// [01], replace this const to current month.
|
||||
if (true) {
|
||||
snprintf(buf, sizeof(buf), "%d", 1 + tm->tm_mon);
|
||||
path = srs_string_replace(path, "[01]", buf);
|
||||
}
|
||||
// [02], replace this const to current date.
|
||||
if (true) {
|
||||
snprintf(buf, sizeof(buf), "%d", tm->tm_mday);
|
||||
path = srs_string_replace(path, "[02]", buf);
|
||||
}
|
||||
// [15], replace this const to current hour.
|
||||
if (true) {
|
||||
snprintf(buf, sizeof(buf), "%d", tm->tm_hour);
|
||||
path = srs_string_replace(path, "[15]", buf);
|
||||
}
|
||||
// [04], repleace this const to current minute.
|
||||
if (true) {
|
||||
snprintf(buf, sizeof(buf), "%d", tm->tm_min);
|
||||
path = srs_string_replace(path, "[04]", buf);
|
||||
}
|
||||
// [05], repleace this const to current second.
|
||||
if (true) {
|
||||
snprintf(buf, sizeof(buf), "%d", tm->tm_sec);
|
||||
path = srs_string_replace(path, "[05]", buf);
|
||||
}
|
||||
// [999], repleace this const to current millisecond.
|
||||
if (true) {
|
||||
snprintf(buf, sizeof(buf), "%03d", (int)(tv.tv_usec / 1000));
|
||||
path = srs_string_replace(path, "[999]", buf);
|
||||
}
|
||||
// [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
if (true) {
|
||||
int64_t now_us = ((int64_t)tv.tv_sec) * 1000 * 1000 + (int64_t)tv.tv_usec;
|
||||
snprintf(buf, sizeof(buf), "%"PRId64, now_us / 1000);
|
||||
path = srs_string_replace(path, "[timestamp]", buf);
|
||||
}
|
||||
|
||||
// create dir first.
|
||||
std::string dir = path.substr(0, path.rfind("/"));
|
||||
if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) {
|
||||
srs_error("create dir=%s failed. ret=%d", dir.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("create dir=%s ok", dir.c_str());
|
||||
|
||||
if ((ret = flv_open(req->get_stream_url(), path)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
dvr_enabled = true;
|
||||
|
|
|
@ -951,16 +951,12 @@ int SrsHlsMuxer::create_dir()
|
|||
app_dir += app;
|
||||
|
||||
// TODO: cleanup the dir when startup.
|
||||
|
||||
mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH;
|
||||
if (::mkdir(app_dir.c_str(), mode) < 0) {
|
||||
if (errno != EEXIST) {
|
||||
ret = ERROR_HLS_CREATE_DIR;
|
||||
srs_error("create app dir %s failed. ret=%d", app_dir.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = srs_create_dir_recursively(app_dir)) != ERROR_SUCCESS) {
|
||||
srs_error("create app dir %s failed. ret=%d", app_dir.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("create app dir %s success.", app_dir.c_str());
|
||||
srs_info("create app dir %s ok", app_dir.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -98,6 +98,9 @@ int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std:
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case SrsRtmpConnUnknown:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// when matched, donot search more.
|
||||
|
@ -140,6 +143,9 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case SrsRtmpConnUnknown:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// when matched, donot search more.
|
||||
|
|
|
@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
// current release version
|
||||
#define VERSION_MAJOR 2
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 86
|
||||
#define VERSION_REVISION 87
|
||||
// server info.
|
||||
#define RTMP_SIG_SRS_KEY "SRS"
|
||||
#define RTMP_SIG_SRS_ROLE "origin/edge server"
|
||||
|
|
|
@ -93,6 +93,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_SYSTEM_SECURITY 1052
|
||||
#define ERROR_SYSTEM_SECURITY_DENY 1053
|
||||
#define ERROR_SYSTEM_SECURITY_ALLOW 1054
|
||||
#define ERROR_SYSTEM_TIME 1055
|
||||
#define ERROR_SYSTEM_DIR_EXISTS 1056
|
||||
#define ERROR_SYSTEM_CREATE_DIR 1057
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// RTMP protocol error.
|
||||
|
@ -152,7 +155,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
///////////////////////////////////////////////////////
|
||||
#define ERROR_HLS_METADATA 3000
|
||||
#define ERROR_HLS_DECODE_ERROR 3001
|
||||
#define ERROR_HLS_CREATE_DIR 3002
|
||||
//#define ERROR_HLS_CREATE_DIR 3002
|
||||
#define ERROR_HLS_OPEN_FAILED 3003
|
||||
#define ERROR_HLS_WRITE_FAILED 3004
|
||||
#define ERROR_HLS_AAC_FRAME_LENGTH 3005
|
||||
|
|
|
@ -32,10 +32,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <srs_kernel_log.hpp>
|
||||
#include <srs_kernel_error.hpp>
|
||||
|
||||
// this value must:
|
||||
// equals to (SRS_SYS_CYCLE_INTERVAL*SRS_SYS_TIME_RESOLUTION_MS_TIMES)*1000
|
||||
|
@ -222,3 +225,56 @@ bool srs_string_ends_with(string str, string flag)
|
|||
return str.rfind(flag) == str.length() - flag.length();
|
||||
}
|
||||
|
||||
int __srs_create_dir_recursively(string dir)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
struct stat st;
|
||||
|
||||
// stat current dir, if exists, return error.
|
||||
if (stat(dir.c_str(), &st) == 0) {
|
||||
return ERROR_SYSTEM_DIR_EXISTS;
|
||||
}
|
||||
|
||||
// create parent first.
|
||||
size_t pos;
|
||||
if ((pos = dir.rfind("/")) != std::string::npos) {
|
||||
std::string parent = dir.substr(0, pos);
|
||||
ret = __srs_create_dir_recursively(parent);
|
||||
// return for error.
|
||||
if (ret != ERROR_SUCCESS && ret != ERROR_SYSTEM_DIR_EXISTS) {
|
||||
return ret;
|
||||
}
|
||||
// parent exists, set to ok.
|
||||
ret = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
// create curren dir.
|
||||
mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH;
|
||||
if (::mkdir(dir.c_str(), mode) < 0) {
|
||||
if (errno == EEXIST) {
|
||||
return ERROR_SYSTEM_DIR_EXISTS;
|
||||
}
|
||||
|
||||
ret = ERROR_SYSTEM_CREATE_DIR;
|
||||
srs_error("create dir %s failed. ret=%d", dir.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("create dir %s success.", dir.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srs_create_dir_recursively(string dir)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
ret = __srs_create_dir_recursively(dir);
|
||||
|
||||
if (ret == ERROR_SYSTEM_DIR_EXISTS) {
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,5 +59,8 @@ extern std::string srs_string_remove(std::string str, std::string remove_chars);
|
|||
// whether string end with
|
||||
extern bool srs_string_ends_with(std::string str, std::string flag);
|
||||
|
||||
// create dir recursively
|
||||
extern int srs_create_dir_recursively(std::string dir);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue