mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
support HLS, refine the dir use app
This commit is contained in:
parent
57ea56970d
commit
04cfe20279
7 changed files with 74 additions and 20 deletions
|
@ -13,6 +13,8 @@ vhost __defaultVhost__ {
|
|||
gop_cache on;
|
||||
hls on;
|
||||
hls_path ./objs/nginx/html;
|
||||
hls_fragment 10;
|
||||
hls_window 60;
|
||||
}
|
||||
# the vhost disabled.
|
||||
vhost removed.vhost.com {
|
||||
|
@ -39,6 +41,12 @@ vhost no-hls.vhost.com {
|
|||
# in a word, the hls_path is for vhost.
|
||||
# default: ./objs/nginx/html
|
||||
hls_path /data/nginx/html;
|
||||
# the hls fragment in seconds, the duration of a piece of ts.
|
||||
# default: 10
|
||||
hls_fragment 10;
|
||||
# the hls window in seconds, the number of ts in m3u8.
|
||||
# default: 60
|
||||
hls_window 60;
|
||||
}
|
||||
# the vhost with hls disabled.
|
||||
vhost no-hls.vhost.com {
|
||||
|
|
|
@ -332,7 +332,7 @@ int SrsClient::publish(SrsSource* source, bool is_fmle)
|
|||
SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);
|
||||
|
||||
// notify the hls to prepare when publish start.
|
||||
if ((ret = source->on_publish(req->vhost, req->stream)) != ERROR_SUCCESS) {
|
||||
if ((ret = source->on_publish(req->vhost, req->app, req->stream)) != ERROR_SUCCESS) {
|
||||
srs_error("hls on_publish failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define ERROR_HLS_METADATA 600
|
||||
#define ERROR_HLS_DECODE_ERROR 601
|
||||
//#define ERROR_HLS_BUSY 602
|
||||
#define ERROR_HLS_CREATE_DIR 602
|
||||
#define ERROR_HLS_OPEN_FAILED 603
|
||||
#define ERROR_HLS_WRITE_FAILED 604
|
||||
#define ERROR_HLS_AAC_FRAME_LENGTH 605
|
||||
|
|
|
@ -403,12 +403,13 @@ SrsHLS::~SrsHLS()
|
|||
srs_freep(video_frame);
|
||||
}
|
||||
|
||||
int SrsHLS::on_publish(std::string _vhost, std::string _stream)
|
||||
int SrsHLS::on_publish(std::string _vhost, std::string _app, std::string _stream)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
vhost = _vhost;
|
||||
stream = _stream;
|
||||
app = _app;
|
||||
|
||||
if ((ret = reopen()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
|
@ -555,6 +556,7 @@ int SrsHLS::on_video(SrsSharedPtrMessage* video)
|
|||
if (sample->frame_type == SrsCodecVideoAVCFrameKeyFrame) {
|
||||
int64_t diff = stream_dts - m3u8_dts;
|
||||
// 10s.
|
||||
// TODO: config it.
|
||||
if (diff / 90000 >= 10) {
|
||||
if ((ret = reopen()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
|
@ -590,6 +592,11 @@ int SrsHLS::reopen()
|
|||
hls_path = conf->arg0();
|
||||
}
|
||||
|
||||
// create dir for app.
|
||||
if ((ret = create_dir()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// start new segment.
|
||||
if (current) {
|
||||
current->duration = (stream_dts - current->segment_start_dts) / 90000.0;
|
||||
|
@ -610,6 +617,8 @@ int SrsHLS::reopen()
|
|||
|
||||
current->full_path = hls_path;
|
||||
current->full_path += "/";
|
||||
current->full_path += app;
|
||||
current->full_path += "/";
|
||||
current->full_path += filename;
|
||||
|
||||
// TODO: support base url, and so on.
|
||||
|
@ -619,7 +628,7 @@ int SrsHLS::reopen()
|
|||
srs_error("open hls muxer failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_trace("open HLS muxer success. vhost=%s, path=%s", vhost.c_str(), current->full_path.c_str());
|
||||
srs_info("open HLS muxer success. vhost=%s, path=%s", vhost.c_str(), current->full_path.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -628,16 +637,33 @@ int SrsHLS::refresh_m3u8()
|
|||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
std::string m3u8_file = hls_path;
|
||||
m3u8_file += "/";
|
||||
m3u8_file += app;
|
||||
m3u8_file += "/";
|
||||
m3u8_file += stream;
|
||||
m3u8_file += ".m3u8";
|
||||
|
||||
m3u8 = m3u8_file;
|
||||
m3u8_file += ".temp";
|
||||
|
||||
int fd = -1;
|
||||
ret = _refresh_m3u8(fd);
|
||||
ret = _refresh_m3u8(fd, m3u8_file);
|
||||
if (fd >= 0) {
|
||||
close(fd);
|
||||
if (rename(m3u8_file.c_str(), m3u8.c_str()) < 0) {
|
||||
ret = ERROR_HLS_WRITE_FAILED;
|
||||
srs_error("rename m3u8 file failed. ret=%d", ret);
|
||||
}
|
||||
}
|
||||
|
||||
// remove the temp file.
|
||||
unlink(m3u8_file.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHLS::_refresh_m3u8(int& fd)
|
||||
int SrsHLS::_refresh_m3u8(int& fd, std::string m3u8_file)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
@ -646,19 +672,14 @@ int SrsHLS::_refresh_m3u8(int& fd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
m3u8 = hls_path;
|
||||
m3u8 += "/";
|
||||
m3u8 += stream;
|
||||
m3u8 += ".m3u8";
|
||||
|
||||
int flags = O_CREAT|O_WRONLY|O_TRUNC;
|
||||
mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH;
|
||||
if ((fd = ::open(m3u8.c_str(), flags, mode)) < 0) {
|
||||
if ((fd = ::open(m3u8_file.c_str(), flags, mode)) < 0) {
|
||||
ret = ERROR_HLS_OPEN_FAILED;
|
||||
srs_error("open m3u8 file %s failed. ret=%d", m3u8.c_str(), ret);
|
||||
srs_error("open m3u8 file %s failed. ret=%d", m3u8_file.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("open m3u8 file %s success.", m3u8.c_str());
|
||||
srs_info("open m3u8 file %s success.", m3u8_file.c_str());
|
||||
|
||||
// #EXTM3U\n#EXT-X-VERSION:3\n
|
||||
char header[] = {
|
||||
|
@ -728,11 +749,34 @@ int SrsHLS::_refresh_m3u8(int& fd)
|
|||
}
|
||||
srs_verbose("write m3u8 segment uri success.");
|
||||
}
|
||||
srs_info("write m3u8 %s success.", m3u8.c_str());
|
||||
srs_info("write m3u8 %s success.", m3u8_file.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHLS::create_dir()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
std::string app_dir = hls_path;
|
||||
app_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;
|
||||
}
|
||||
}
|
||||
srs_info("create app dir %s success.", app_dir.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
SrsTSMuxer::SrsTSMuxer()
|
||||
{
|
||||
fd = -1;
|
||||
|
|
|
@ -72,6 +72,7 @@ class SrsHLS
|
|||
private:
|
||||
std::string vhost;
|
||||
std::string stream;
|
||||
std::string app;
|
||||
std::string hls_path;
|
||||
private:
|
||||
int file_index;
|
||||
|
@ -103,7 +104,7 @@ public:
|
|||
SrsHLS();
|
||||
virtual ~SrsHLS();
|
||||
public:
|
||||
virtual int on_publish(std::string _vhost, std::string _stream);
|
||||
virtual int on_publish(std::string _vhost, std::string _app, std::string _stream);
|
||||
virtual void on_unpublish();
|
||||
virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
|
||||
virtual int on_audio(SrsSharedPtrMessage* audio);
|
||||
|
@ -111,7 +112,8 @@ public:
|
|||
private:
|
||||
virtual int reopen();
|
||||
virtual int refresh_m3u8();
|
||||
virtual int _refresh_m3u8(int& fd);
|
||||
virtual int _refresh_m3u8(int& fd, std::string m3u8_file);
|
||||
virtual int create_dir();
|
||||
};
|
||||
|
||||
class SrsTSMuxer
|
||||
|
|
|
@ -452,9 +452,9 @@ int SrsSource::on_video(SrsCommonMessage* video)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsSource::on_publish(std::string vhost, std::string stream)
|
||||
int SrsSource::on_publish(std::string vhost, std::string app, std::string stream)
|
||||
{
|
||||
return hls->on_publish(vhost, stream);
|
||||
return hls->on_publish(vhost, app, stream);
|
||||
}
|
||||
|
||||
void SrsSource::on_unpublish()
|
||||
|
|
|
@ -166,7 +166,7 @@ public:
|
|||
virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata);
|
||||
virtual int on_audio(SrsCommonMessage* audio);
|
||||
virtual int on_video(SrsCommonMessage* video);
|
||||
virtual int on_publish(std::string vhost, std::string stream);
|
||||
virtual int on_publish(std::string vhost, std::string app, std::string stream);
|
||||
virtual void on_unpublish();
|
||||
public:
|
||||
virtual int create_consumer(SrsConsumer*& consumer);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue