From b609dcdc367fc21efed4f9d9a028fb6bc9d0cc8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CEdward=2EWu=E2=80=9D?= <“edward_email@126.com”> Date: Fri, 3 Apr 2020 11:38:06 +0800 Subject: [PATCH] v1.4.5 --- README.md | 4 +- logs/error.log | 146 ++++++++++++++++++++++++++++++++++ sls.conf | 11 ++- slscore/SLSListener.cpp | 14 +++- slscore/SLSListener.hpp | 2 + slscore/SLSManager.cpp | 2 + slscore/SLSManager.hpp | 14 ++-- slscore/SLSMapData.cpp | 39 ++++----- slscore/SLSMapData.hpp | 5 +- slscore/SLSPublisher.cpp | 3 + slscore/SLSPublisher.hpp | 12 ++- slscore/SLSRole.cpp | 165 ++++++++++++++++++++++++++++++++++++++- slscore/SLSRole.hpp | 19 ++++- slscore/common.cpp | 2 +- slscore/common.hpp | 2 + ~/sls/pid.txt | 0 16 files changed, 396 insertions(+), 44 deletions(-) create mode 100644 logs/error.log create mode 100755 ~/sls/pid.txt diff --git a/README.md b/README.md index 9d2d3f7..479f405 100644 --- a/README.md +++ b/README.md @@ -140,4 +140,6 @@ v1.4.4 1. OBS streaming compatible, OBS support the srt protocol which is later than v25.0. (https://obsproject.com/forum/threads/obs-studio-25-0-release-candidate.116067/) - +v1.4.5 +------ +1. add hls record feature. diff --git a/logs/error.log b/logs/error.log new file mode 100644 index 0000000..2993120 --- /dev/null +++ b/logs/error.log @@ -0,0 +1,146 @@ +2020-04-03 11:34:29:893 SLS INFO: [0x7ff0aec029a0]CSLSManager::start, new m_list_role=0x7ff0aed00050. +2020-04-03 11:34:29:894 SLS INFO: [0x1102eb000]CSLSListener::start... +2020-04-03 11:34:29:894 SLS INFO: [0x1102eb000]CSLSListener::init_conf_app, m_back_log=100, m_idle_streams_timeout=10. +2020-04-03 11:34:29:894 SLS INFO: [0x1102eb000]CSLSListener::init_conf_app, add app push 'uplive.sls.com/live'. +2020-04-03 11:34:29:894 SLS INFO: [0x1102eb000]CSLSListener::init_conf_app, add app live='live.sls.com/live', app push='uplive.sls.com/live'. +2020-04-03 11:34:29:894 SLS INFO: [0x1102eb000]CSLSListener::init_conf_app, add app live='live-1.sls.com/live', app push='uplive.sls.com/live'. +2020-04-03 11:34:29:895 SLS INFO: [0x7ff0b0000000]CSLSSrt::libsrt_setup, fd=1048655853. +2020-04-03 11:34:29:895 SLS INFO: [0x1102eb000]CSLSListener::start, libsrt_setup ok. +2020-04-03 11:34:29:895 SLS INFO: [0x7ff0b0000000]CSLSSrt::libsrt_listen, ok, fd=1048655853, at port=8080. +2020-04-03 11:34:29:895 SLS INFO: [0x1102eb000]CSLSListener::start, m_list_role=0x7ff0aed00050. +2020-04-03 11:34:29:895 SLS INFO: [0x1102eb000]CSLSListener::start, push to m_list_role=0x7ff0aed00050. +2020-04-03 11:34:29:895 SLS INFO: [0x7ff0aec029a0]CSLSManager::start, init listeners, count=1. +2020-04-03 11:34:29:895 SLS INFO: [0x7ff0af01c800]CSLSGroup::start, worker_number=0. +2020-04-03 11:34:29:895 SLS INFO: [0x7ff0af01c800]CSLSEpollThread::work, begin th_id=0. +2020-04-03 11:34:29:895 SLS INFO: [0x7ff0af01c800]CSLSThread::start, pthread_create ok, m_th_id=123145466294272. +2020-04-03 11:34:29:895 SLS INFO: [0x7ff0aec029a0]CSLSManager::start, init worker, count=1. +2020-04-03 11:34:29:906 SLS INFO: [0x1102eb000]CSLSRole::add_to_epoll, listener, sock=1048655853, m_is_write=0, ret=0. +2020-04-03 11:34:29:906 SLS INFO: [0x7ff0af01c800]CSLSGroup::check_new_role, worker_number=0, listener=0x1102eb000, add_to_epoll fd=1048655853, role_map.size=1. +2020-04-03 11:34:39:071 SLS INFO: [0x7ff0b0000000]CSLSSrt::libsrt_accept ok, new sock=1048655852, 127.0.0.1:50576. +2020-04-03 11:34:39:071 SLS INFO: [0x1102eb000]CSLSListener::handler, new client[127.0.0.1:50576], fd=1048655852. +2020-04-03 11:34:39:071 SLS INFO: [0x1102eb000]CSLSListener::handler, [127.0.0.1:50576], sid 'uplive.sls.com/live/test123' +2020-04-03 11:34:39:071 SLS INFO: [0x1102eb000]CSLSListener::handler, new pub=0x1103a2000, key_stream_name=uplive.sls.com/live/test123. +2020-04-03 11:34:39:071 SLS INFO: [0x7ff0aed00478]CSLSMapData::add ok, key='uplive.sls.com/live/test123'. +2020-04-03 11:34:39:071 SLS INFO: [0x7ff0aed00588]CSLSMapPublisher::set_push_2_pushlisher, ok, publisher=0x1103a2000, app_streamname=uplive.sls.com/live/test123, m_map_push_2_pushlisher.size()=1. +2020-04-03 11:34:39:071 SLS INFO: [0x1102eb000]CSLSListener::handler, new publisher[127.0.0.1:50576], key_stream_name=uplive.sls.com/live/test123. +2020-04-03 11:34:39:071 SLS INFO: [0x7ff0aed007c8]CSLSMapRelay::add_relay_manager, no relay conf info, app_uplive=uplive.sls.com/live, stream_name=test123. +2020-04-03 11:34:39:071 SLS INFO: [0x1102eb000]CSLSListener::handler, m_map_pusher->add_relay_manager failed, new role[127.0.0.1:50576], key_stream_name=uplive.sls.com/live/test123. +2020-04-03 11:34:39:071 SLS INFO: [0x1103a2000]CSLSRole::add_to_epoll, publisher, sock=1048655852, m_is_write=0, ret=0. +2020-04-03 11:34:39:071 SLS INFO: [0x7ff0af01c800]CSLSGroup::check_new_role, worker_number=0, publisher=0x1103a2000, add_to_epoll fd=1048655852, role_map.size=2. +2020-04-03 11:34:45:923 SLS ERROR: CSLSSrt::libsrt_neterrno, err=2001, Connection was broken. +2020-04-03 11:34:45:923 SLS WARNING: [0x7ff0af034000]CSLSSrt::libsrt_read failed, sock=1048655852, ret=-1, err_no=2001. +2020-04-03 11:34:45:923 SLS ERROR: [0x1103a2000]CSLSRole::handler_read_data, libsrt_read failure, n=-1. +2020-04-03 11:34:45:923 SLS INFO: [0x1103a2000]CSLSRole::invalid_srt, close sock=1048655852, m_state=1. +2020-04-03 11:34:45:923 SLS INFO: [0x7ff0af034000]CSLSSrt::libsrt_close, fd=1048655852. +2020-04-03 11:34:45:923 SLS ERROR: [0x1103a2000]CSLSRole::handler_read_data, m_srt is null. +2020-04-03 11:34:45:923 SLS INFO: [0x1103a2000]CSLSRole::get_state, get_sock_state, ret=-16777216, call invalid_srt. +2020-04-03 11:34:45:923 SLS INFO: [0x7ff0af01c800]CSLSGroup::check_invalid_sock, worker_number=0, publisher=0x1103a2000, invalid sock=0, state=2, role_map.size=2. +2020-04-03 11:34:45:923 SLS INFO: [0x7ff0aed00478]CSLSMapData::remove, key='uplive.sls.com/live/test123' delete array_data=0x7ff0aec04410. +2020-04-03 11:34:45:923 SLS INFO: [0x1103a2000]CSLSPublisher::uninit, removed publisher from m_map_data, ret=0. +2020-04-03 11:34:45:923 SLS INFO: [0x7ff0aed00588]CSLSMapPublisher::remove, publisher=0x1103a2000, live_key=uplive.sls.com/live/test123. +2020-04-03 11:34:45:923 SLS INFO: [0x1103a2000]CSLSPublisher::uninit, removed publisher from m_map_publisher, ret=0. +2020-04-03 11:34:45:923 SLS INFO: [0x7ff0af01c800]CSLSGroup::check_invalid_sock, worker_number=0, publisher=0x1103a2000, delete. +2020-04-03 11:34:46:650 SLS INFO: exit, stop srt live server... +2020-04-03 11:34:46:650 SLS INFO: [0x7ff0aec029a0]CSLSManager::stop. +2020-04-03 11:34:46:651 SLS INFO: [0x1102eb000]CSLSListener::stop. +2020-04-03 11:34:46:651 SLS INFO: [0x1102eb000]CSLSRole::remove_from_epoll, listener, sock=1048655853, ret=0. +2020-04-03 11:34:46:651 SLS INFO: [0x1102eb000]CSLSRole::invalid_srt, close sock=1048655853, m_state=0. +2020-04-03 11:34:46:651 SLS INFO: [0x7ff0b0000000]CSLSSrt::libsrt_close, fd=1048655853. +2020-04-03 11:34:46:651 SLS INFO: [0x7ff0af01c800]CSLSGroup::stop, worker_number=0. +2020-04-03 11:34:46:651 SLS INFO: [0x7ff0af01c800]CSLSThread::stop, m_th_id=123145466294272. +2020-04-03 11:34:46:653 SLS INFO: [0x1102eb000]CSLSRole::get_state, get_sock_state, ret=-16777216, call invalid_srt. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0af01c800]CSLSGroup::check_invalid_sock, worker_number=0, listener=0x1102eb000, invalid sock=0, state=2, role_map.size=1. +2020-04-03 11:34:46:653 SLS INFO: [0x1102eb000]CSLSListener::stop. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0af01c800]CSLSGroup::check_invalid_sock, worker_number=0, listener=0x1102eb000, delete. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0af01c800]CSLSGroup::clear, worker_number=0, role_map.size=0. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0af01c800]CSLSEpollThread::work, end th_id=123145466294272. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0af01c800]CSLSGroup::clear, worker_number=0, role_map.size=0. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0af01c800]CSLSGroup::stop, m_list_wait_http_role.clear, worker_number=0. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0af01c800]CSLSEpollThread::work, srt_epoll_release ok, m_th_id=0. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0aed00588]CSLSMapPublisher::clear. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0aed006b8]CSLSMapRelay::clear. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0aed007c8]CSLSMapRelay::clear. +2020-04-03 11:34:46:653 SLS INFO: [0x7ff0aec029a0]CSLSManager::stop, release rolelist, size=0. +2020-04-03 11:34:46:653 SLS INFO: exit, release sls_manager ok. +2020-04-03 11:34:46:653 SLS INFO: exit, release reload_manager_list begin,count=0. +2020-04-03 11:34:46:653 SLS INFO: exit, release reload_manager_list ok. +2020-04-03 11:34:46:653 SLS INFO: exit, release http_stat_client. +2020-04-03 11:34:46:653 SLS INFO: exit, uninit srt . +2020-04-03 11:34:46:662 SLS INFO: exit, close conf. +2020-04-03 11:35:10:910 SLS INFO: [0x7ff47e5001a0]CSLSManager::start, new m_list_role=0x7ff47e700220. +2020-04-03 11:35:10:910 SLS INFO: [0x106d5f000]CSLSListener::start... +2020-04-03 11:35:10:910 SLS INFO: [0x106d5f000]CSLSListener::init_conf_app, m_back_log=100, m_idle_streams_timeout=10. +2020-04-03 11:35:10:910 SLS INFO: [0x106d5f000]CSLSListener::init_conf_app, add app push 'uplive.sls.com/live'. +2020-04-03 11:35:10:910 SLS INFO: [0x106d5f000]CSLSListener::init_conf_app, add app live='live.sls.com/live', app push='uplive.sls.com/live'. +2020-04-03 11:35:10:910 SLS INFO: [0x106d5f000]CSLSListener::init_conf_app, add app live='live-1.sls.com/live', app push='uplive.sls.com/live'. +2020-04-03 11:35:10:911 SLS INFO: [0x7ff47e81c800]CSLSSrt::libsrt_setup, fd=115487778. +2020-04-03 11:35:10:911 SLS INFO: [0x106d5f000]CSLSListener::start, libsrt_setup ok. +2020-04-03 11:35:10:911 SLS INFO: [0x7ff47e81c800]CSLSSrt::libsrt_listen, ok, fd=115487778, at port=8080. +2020-04-03 11:35:10:911 SLS INFO: [0x106d5f000]CSLSListener::start, m_list_role=0x7ff47e700220. +2020-04-03 11:35:10:911 SLS INFO: [0x106d5f000]CSLSListener::start, push to m_list_role=0x7ff47e700220. +2020-04-03 11:35:10:911 SLS INFO: [0x7ff47e5001a0]CSLSManager::start, init listeners, count=1. +2020-04-03 11:35:10:911 SLS INFO: [0x7ff47e824200]CSLSGroup::start, worker_number=0. +2020-04-03 11:35:10:911 SLS INFO: [0x7ff47e824200]CSLSThread::start, pthread_create ok, m_th_id=123145556434944. +2020-04-03 11:35:10:911 SLS INFO: [0x7ff47e5001a0]CSLSManager::start, init worker, count=1. +2020-04-03 11:35:10:911 SLS INFO: [0x7ff47e824200]CSLSEpollThread::work, begin th_id=123145556434944. +2020-04-03 11:35:10:923 SLS INFO: [0x106d5f000]CSLSRole::add_to_epoll, listener, sock=115487778, m_is_write=0, ret=0. +2020-04-03 11:35:10:923 SLS INFO: [0x7ff47e824200]CSLSGroup::check_new_role, worker_number=0, listener=0x106d5f000, add_to_epoll fd=115487778, role_map.size=1. +2020-04-03 11:35:14:516 SLS INFO: [0x7ff47e81c800]CSLSSrt::libsrt_accept ok, new sock=115487777, 127.0.0.1:53232. +2020-04-03 11:35:14:516 SLS INFO: [0x106d5f000]CSLSListener::handler, new client[127.0.0.1:53232], fd=115487777. +2020-04-03 11:35:14:516 SLS INFO: [0x106d5f000]CSLSListener::handler, [127.0.0.1:53232], sid 'uplive.sls.com/live/test123' +2020-04-03 11:35:14:516 SLS INFO: [0x106d5f000]CSLSListener::handler, new pub=0x106e16000, key_stream_name=uplive.sls.com/live/test123. +2020-04-03 11:35:14:516 SLS INFO: [0x7ff47e500478]CSLSMapData::add ok, key='uplive.sls.com/live/test123'. +2020-04-03 11:35:14:516 SLS INFO: [0x7ff47e500588]CSLSMapPublisher::set_push_2_pushlisher, ok, publisher=0x106e16000, app_streamname=uplive.sls.com/live/test123, m_map_push_2_pushlisher.size()=1. +2020-04-03 11:35:14:516 SLS INFO: [0x106d5f000]CSLSListener::handler, new publisher[127.0.0.1:53232], key_stream_name=uplive.sls.com/live/test123. +2020-04-03 11:35:14:516 SLS INFO: [0x7ff47e700118]CSLSMapRelay::add_relay_manager, no relay conf info, app_uplive=uplive.sls.com/live, stream_name=test123. +2020-04-03 11:35:14:516 SLS INFO: [0x106d5f000]CSLSListener::handler, m_map_pusher->add_relay_manager failed, new role[127.0.0.1:53232], key_stream_name=uplive.sls.com/live/test123. +2020-04-03 11:35:14:516 SLS INFO: [0x106e16000]CSLSRole::add_to_epoll, publisher, sock=115487777, m_is_write=0, ret=0. +2020-04-03 11:35:14:516 SLS INFO: [0x7ff47e824200]CSLSGroup::check_new_role, worker_number=0, publisher=0x106e16000, add_to_epoll fd=115487777, role_map.size=2. +2020-04-03 11:35:14:550 SLS INFO: [0x106e16000]CSLSRole::check_hls_file, '/tmp/mov/sls/8080/uplive.sls.com/live/test123' exist. + +2020-04-03 11:35:14:552 SLS INFO: [0x106e16000]CSLSRole::check_hls_file, create ts file='/tmp/mov/sls/8080/uplive.sls.com/live/test123/1585884914.ts', fd=6. +2020-04-03 11:35:24:562 SLS INFO: [0x106e16000]CSLSRole::check_hls_file, '/tmp/mov/sls/8080/uplive.sls.com/live/test123' exist. + +2020-04-03 11:35:24:562 SLS INFO: [0x106e16000]CSLSRole::check_hls_file, close ts file='1585884914.ts', fd=6. +2020-04-03 11:35:24:564 SLS INFO: [0x106e16000]CSLSRole::check_hls_file, create vod file='/tmp/mov/sls/8080/uplive.sls.com/live/test123/vod-1585884924.m3u8.extinfo', fd=6. +2020-04-03 11:35:24:564 SLS INFO: [0x106e16000]CSLSRole::check_hls_file, create ts file='/tmp/mov/sls/8080/uplive.sls.com/live/test123/1585884924.ts', fd=7. +2020-04-03 11:35:27:786 SLS INFO: [0x106e16000]CSLSRole::get_state, get_sock_state, ret=6, call invalid_srt. +2020-04-03 11:35:27:786 SLS ERROR: CSLSSrt::libsrt_neterrno, err=6003, Non-blocking call failure: transmission timed out. +2020-04-03 11:35:27:786 SLS INFO: [0x106e16000]CSLSRole::invalid_srt, close sock=115487777, m_state=2. +2020-04-03 11:35:27:786 SLS INFO: [0x7ff47e826400]CSLSSrt::libsrt_close, fd=115487777. +2020-04-03 11:35:27:786 SLS INFO: [0x7ff47e824200]CSLSGroup::check_invalid_sock, worker_number=0, publisher=0x106e16000, invalid sock=0, state=2, role_map.size=2. +2020-04-03 11:35:27:786 SLS INFO: [0x7ff47e500478]CSLSMapData::remove, key='uplive.sls.com/live/test123' delete array_data=0x7ff47e403aa0. +2020-04-03 11:35:27:786 SLS INFO: [0x106e16000]CSLSPublisher::uninit, removed publisher from m_map_data, ret=0. +2020-04-03 11:35:27:786 SLS INFO: [0x7ff47e500588]CSLSMapPublisher::remove, publisher=0x106e16000, live_key=uplive.sls.com/live/test123. +2020-04-03 11:35:27:786 SLS INFO: [0x106e16000]CSLSPublisher::uninit, removed publisher from m_map_publisher, ret=0. +2020-04-03 11:35:27:786 SLS INFO: [0x106e16000]CSLSRole::close_hls_file, close ts file='1585884924.ts', fd=7. +2020-04-03 11:35:27:787 SLS INFO: [0x106e16000]CSLSRole::close_hls_file, prepare open '/tmp/mov/sls/8080/uplive.sls.com/live/test123/vod-1585884924.m3u8.extinfo', fd=6. +2020-04-03 11:35:27:788 SLS INFO: [0x106e16000]CSLSRole::close_hls_file, read data len=30, fd=6. +2020-04-03 11:35:27:788 SLS INFO: [0x7ff47e824200]CSLSGroup::check_invalid_sock, worker_number=0, publisher=0x106e16000, delete. +2020-04-03 11:36:00:156 SLS INFO: exit, stop srt live server... +2020-04-03 11:36:00:156 SLS INFO: [0x7ff47e5001a0]CSLSManager::stop. +2020-04-03 11:36:00:156 SLS INFO: [0x106d5f000]CSLSListener::stop. +2020-04-03 11:36:00:156 SLS INFO: [0x106d5f000]CSLSRole::remove_from_epoll, listener, sock=115487778, ret=0. +2020-04-03 11:36:00:156 SLS INFO: [0x106d5f000]CSLSRole::invalid_srt, close sock=115487778, m_state=0. +2020-04-03 11:36:00:156 SLS INFO: [0x7ff47e81c800]CSLSSrt::libsrt_close, fd=115487778. +2020-04-03 11:36:00:156 SLS INFO: [0x7ff47e824200]CSLSGroup::stop, worker_number=0. +2020-04-03 11:36:00:156 SLS INFO: [0x7ff47e824200]CSLSThread::stop, m_th_id=123145556434944. +2020-04-03 11:36:00:158 SLS INFO: [0x106d5f000]CSLSRole::get_state, get_sock_state, ret=-16777216, call invalid_srt. +2020-04-03 11:36:00:158 SLS INFO: [0x7ff47e824200]CSLSGroup::check_invalid_sock, worker_number=0, listener=0x106d5f000, invalid sock=0, state=2, role_map.size=1. +2020-04-03 11:36:00:158 SLS INFO: [0x106d5f000]CSLSListener::stop. +2020-04-03 11:36:00:158 SLS INFO: [0x7ff47e824200]CSLSGroup::check_invalid_sock, worker_number=0, listener=0x106d5f000, delete. +2020-04-03 11:36:00:158 SLS INFO: [0x7ff47e824200]CSLSGroup::clear, worker_number=0, role_map.size=0. +2020-04-03 11:36:00:158 SLS INFO: [0x7ff47e824200]CSLSEpollThread::work, end th_id=123145556434944. +2020-04-03 11:36:00:159 SLS INFO: [0x7ff47e824200]CSLSGroup::clear, worker_number=0, role_map.size=0. +2020-04-03 11:36:00:159 SLS INFO: [0x7ff47e824200]CSLSGroup::stop, m_list_wait_http_role.clear, worker_number=0. +2020-04-03 11:36:00:159 SLS INFO: [0x7ff47e824200]CSLSEpollThread::work, srt_epoll_release ok, m_th_id=0. +2020-04-03 11:36:00:159 SLS INFO: [0x7ff47e500588]CSLSMapPublisher::clear. +2020-04-03 11:36:00:159 SLS INFO: [0x7ff47e700008]CSLSMapRelay::clear. +2020-04-03 11:36:00:159 SLS INFO: [0x7ff47e700118]CSLSMapRelay::clear. +2020-04-03 11:36:00:159 SLS INFO: [0x7ff47e5001a0]CSLSManager::stop, release rolelist, size=0. +2020-04-03 11:36:00:159 SLS INFO: exit, release sls_manager ok. +2020-04-03 11:36:00:159 SLS INFO: exit, release reload_manager_list begin,count=0. +2020-04-03 11:36:00:159 SLS INFO: exit, release reload_manager_list ok. +2020-04-03 11:36:00:159 SLS INFO: exit, release http_stat_client. +2020-04-03 11:36:00:160 SLS INFO: exit, uninit srt . +2020-04-03 11:36:00:170 SLS INFO: exit, close conf. diff --git a/sls.conf b/sls.conf index 265b29e..e9799bb 100644 --- a/sls.conf +++ b/sls.conf @@ -1,4 +1,4 @@ -srt { #SRT +srt { #SRT worker_threads 1; worker_connections 300 ; @@ -7,7 +7,10 @@ srt { #SRT #stat_post_url http://192.168.31.106:8001/sls/stat; #stat_post_interval 5;#s - + + record_hls_path_prefix /tmp/mov/sls; + #vod file name: /tmp/mov/sls/$listen/$domain_publisher/$app_publisher/$stream_name/vod.m3u8 + server { listen 8080; latency 20; #ms @@ -20,6 +23,10 @@ srt { #SRT app { app_player live ; app_publisher live ; + + record_hls off;#on, off + record_hls_segment_duration 10; #unit s + #relay { # type pull; # mode loop;#loop; hash; diff --git a/slscore/SLSListener.cpp b/slscore/SLSListener.cpp index 26689be..42dc729 100644 --- a/slscore/SLSListener.cpp +++ b/slscore/SLSListener.cpp @@ -96,6 +96,7 @@ CSLSListener::CSLSListener() m_idle_streams_timeout_role = 0; m_stat_info = std::string(""); memset(m_http_url_role, 0, URL_MAX_LEN); + memset(m_record_hls_path_prefix, 0, URL_MAX_LEN); sprintf(m_role_name, "listener"); } @@ -137,6 +138,13 @@ void CSLSListener::set_map_pusher(CSLSMapRelay *map_pusher) m_map_pusher = map_pusher; } +void CSLSListener::set_record_hls_path_prefix(char *path) +{ + if (path != NULL && strlen(path) > 0) { + strcpy(m_record_hls_path_prefix, path); + } +} + int CSLSListener::init_conf_app() { string strLive; @@ -288,7 +296,7 @@ int CSLSListener::start() if (latency > 0) { ret = m_srt->libsrt_setsockopt(SRTO_LATENCY, "SRTO_LATENCY", &latency, sizeof (latency)); if (SLS_OK != ret) { - sls_log(SLS_LOG_INFO, "[%p]CSLSListener::start, libsrt_setsockopt failure.", this); + sls_log(SLS_LOG_INFO, "[%p]CSLSListener::start, libsrt_setsockopt latency=%d failure.", this, latency); return ret; } } @@ -502,6 +510,10 @@ int CSLSListener::handler() std::string stat_info = std::string(tmp); pub->set_stat_info_base(stat_info); pub->set_http_url(m_http_url_role); + //set hls record path + sprintf(tmp, "%s/%d/%s", + m_record_hls_path_prefix, m_port, key_stream_name); + pub->set_record_hls_path(tmp); sls_log(SLS_LOG_INFO, "[%p]CSLSListener::handler, new pub=%p, key_stream_name=%s.", this, pub, key_stream_name); diff --git a/slscore/SLSListener.hpp b/slscore/SLSListener.hpp index d9452d7..9bb16bf 100644 --- a/slscore/SLSListener.hpp +++ b/slscore/SLSListener.hpp @@ -86,6 +86,7 @@ public : void set_map_publisher(CSLSMapPublisher * publisher); void set_map_puller(CSLSMapRelay *map_puller); void set_map_pusher(CSLSMapRelay *map_puller); + void set_record_hls_path_prefix(char *path); virtual std::string get_stat_info(); @@ -100,6 +101,7 @@ public : int m_idle_streams_timeout_role; std::string m_stat_info; char m_http_url_role[URL_MAX_LEN]; + char m_record_hls_path_prefix[URL_MAX_LEN]; int init_conf_app(); diff --git a/slscore/SLSManager.cpp b/slscore/SLSManager.cpp index c28b54a..9b7bfe3 100644 --- a/slscore/SLSManager.cpp +++ b/slscore/SLSManager.cpp @@ -53,6 +53,7 @@ CSLSManager::CSLSManager() m_map_publisher = NULL; m_map_puller = NULL; m_map_pusher = NULL; + } CSLSManager::~CSLSManager() @@ -101,6 +102,7 @@ int CSLSManager::start() CSLSListener * p = new CSLSListener();//deleted by groups p->set_role_list(m_list_role); p->set_conf(conf); + p->set_record_hls_path_prefix(conf_srt->record_hls_path_prefix); p->set_map_data("", &m_map_data[i]); p->set_map_publisher(&m_map_publisher[i]); p->set_map_puller(&m_map_puller[i]); diff --git a/slscore/SLSManager.hpp b/slscore/SLSManager.hpp index b7a2c5d..3e65d2b 100644 --- a/slscore/SLSManager.hpp +++ b/slscore/SLSManager.hpp @@ -46,6 +46,7 @@ int worker_threads; int worker_connections; char stat_post_url[URL_MAX_LEN]; int stat_post_interval; +char record_hls_path_prefix[URL_MAX_LEN]; SLS_CONF_DYNAMIC_DECLARE_END @@ -53,12 +54,13 @@ SLS_CONF_DYNAMIC_DECLARE_END * srt cmd declare */ SLS_CONF_CMD_DYNAMIC_DECLARE_BEGIN(srt) -SLS_SET_CONF(srt, string, log_file, "save log file name.", 1, URL_MAX_LEN-1), -SLS_SET_CONF(srt, string, log_level, "log level", 1, URL_MAX_LEN-1), -SLS_SET_CONF(srt, int, worker_threads, "count of worker thread, if 0, only main thread.", 0, 100), -SLS_SET_CONF(srt, int, worker_connections, "", 1, 1024), -SLS_SET_CONF(srt, string, stat_post_url, "statistic info post url", 1, URL_MAX_LEN-1), -SLS_SET_CONF(srt, int, stat_post_interval, "interval of statistic info post.", 1, 60), +SLS_SET_CONF(srt, string, log_file, "save log file name.", 1, URL_MAX_LEN-1), +SLS_SET_CONF(srt, string, log_level, "log level", 1, URL_MAX_LEN-1), +SLS_SET_CONF(srt, int, worker_threads, "count of worker thread, if 0, only main thread.", 0, 100), +SLS_SET_CONF(srt, int, worker_connections, "", 1, 1024), +SLS_SET_CONF(srt, string, stat_post_url, "statistic info post url", 1, URL_MAX_LEN-1), +SLS_SET_CONF(srt, int, stat_post_interval, "interval of statistic info post.", 1, 60), +SLS_SET_CONF(srt, string, record_hls_path_prefix, "hls path prefix", 1, URL_MAX_LEN-1), SLS_CONF_CMD_DYNAMIC_DECLARE_END diff --git a/slscore/SLSMapData.cpp b/slscore/SLSMapData.cpp index 9f2f608..e41f6df 100644 --- a/slscore/SLSMapData.cpp +++ b/slscore/SLSMapData.cpp @@ -138,21 +138,6 @@ int CSLSMapData::put(char *key, char *data, int len, int64_t *last_read_time) this, key); } - /*//for test, in future, add the record feature. - //save data - static char out_file_name[URL_MAX_LEN] = {0}; - if (strlen(out_file_name) == 0) { - char cur_tm[256]; - sls_gettime_default_string(cur_tm); - sprintf(out_file_name, "./obs_%s.ts", cur_tm); - } - static int fd_out = open(out_file_name, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IXOTH); - - if (0 != fd_out) { - write(fd_out, data, len); - } - */ - ret = array_data->put(data, len); if (ret != len) { sls_log(SLS_LOG_ERROR, "[%p]CSLSMapData::put, key=%s, array_data->put failed, len=%d, but ret=%d.", @@ -208,15 +193,25 @@ int CSLSMapData::get(char *key, char *data, int len, SLSRecycleArrayID *read_id, ret = array_data->get(data, len, read_id, aligned); if (b_first) { //get sps and pps - ts_info *ti = NULL; - std::map::iterator item_ti; - item_ti = m_map_ts_info.find(strKey); - if (item_ti != m_map_ts_info.end()) { - ti = item_ti->second; + ret = get_ts_info(key, data, len); + sls_log(SLS_LOG_INFO, "[%p]CSLSMapData::get, get sps pps ok, key=%s, len=%d.", + this, key, ret); + } + return ret; +} + +int CSLSMapData::get_ts_info(char *key, char *data, int len) +{ + int ret = 0; + ts_info *ti = NULL; + std::string strKey = std::string(key); + std::map::iterator item_ti; + item_ti = m_map_ts_info.find(strKey); + if (item_ti != m_map_ts_info.end()) { + ti = item_ti->second; + if (len >= TS_UDP_LEN) { memcpy(data, ti->ts_data, TS_UDP_LEN); ret = TS_UDP_LEN; - sls_log(SLS_LOG_INFO, "[%p]CSLSMapData::get, get sps pps ok, key=%s, len=%d.", - this, key, ret); } } return ret; diff --git a/slscore/SLSMapData.hpp b/slscore/SLSMapData.hpp index 5537fb9..8ac6987 100644 --- a/slscore/SLSMapData.hpp +++ b/slscore/SLSMapData.hpp @@ -42,11 +42,12 @@ class CSLSMapData int remove(char *key); void clear(); - int put(char *key, char *data, int len, int64_t *last_read_time=NULL); - int get(char *key, char *data, int len, SLSRecycleArrayID *read_id, int aligned=0); + int put(char *key, char *data, int len, int64_t *last_read_time=NULL); + int get(char *key, char *data, int len, SLSRecycleArrayID *read_id, int aligned=0); bool is_exist(char *key); + int get_ts_info(char *key, char *data, int len); private: std::map m_map_array; //uplive_key_stream:data' std::map m_map_ts_info; //uplive_key_stream:ts_info' diff --git a/slscore/SLSPublisher.cpp b/slscore/SLSPublisher.cpp index 6194651..7b31f6d 100644 --- a/slscore/SLSPublisher.cpp +++ b/slscore/SLSPublisher.cpp @@ -58,7 +58,10 @@ int CSLSPublisher::init() { int ret = CSLSRole::init(); if (m_conf) { + sls_conf_app_t * app_conf = ((sls_conf_app_t *)m_conf); //m_exit_delay = ((sls_conf_app_t *)m_conf)->publisher_exit_delay; + strcpy(m_record_hls, app_conf->record_hls); + m_record_hls_segment_duration = app_conf->record_hls_segment_duration; } return ret; diff --git a/slscore/SLSPublisher.hpp b/slscore/SLSPublisher.hpp index 8dc590d..d317463 100644 --- a/slscore/SLSPublisher.hpp +++ b/slscore/SLSPublisher.hpp @@ -36,18 +36,22 @@ * sls_conf_app_t */ SLS_CONF_DYNAMIC_DECLARE_BEGIN(app) -char app_player[1024]; -char app_publisher[1024]; +char app_player[STR_MAX_LEN]; +char app_publisher[STR_MAX_LEN]; int publisher_exit_delay; +char record_hls[SHORT_STR_MAX_LEN]; +int record_hls_segment_duration; SLS_CONF_DYNAMIC_DECLARE_END /** * app cmd declare */ SLS_CONF_CMD_DYNAMIC_DECLARE_BEGIN(app) -SLS_SET_CONF(app, string, app_player, "live", 1, 1023), -SLS_SET_CONF(app, string, app_publisher, "uplive", 1, 1023), +SLS_SET_CONF(app, string, app_player, "live", 1, STR_MAX_LEN-1), +SLS_SET_CONF(app, string, app_publisher, "uplive", 1, STR_MAX_LEN-1), SLS_SET_CONF(app, int, publisher_exit_delay, "delay exit time, unit second.", 1, 300), +SLS_SET_CONF(app, string, record_hls, "record_hls switch", 1, SHORT_STR_MAX_LEN-1), +SLS_SET_CONF(app, int, record_hls_segment_duration, "record_hls_segment_duration", 1, 3600), SLS_CONF_CMD_DYNAMIC_DECLARE_END diff --git a/slscore/SLSRole.cpp b/slscore/SLSRole.cpp index a414e98..2290438 100644 --- a/slscore/SLSRole.cpp +++ b/slscore/SLSRole.cpp @@ -25,7 +25,7 @@ #include #include - +#include #include "SLSRole.hpp" #include "SLSLog.hpp" @@ -68,6 +68,16 @@ CSLSRole::CSLSRole() m_need_reconnect = false; m_http_client = NULL; + sprintf(m_record_hls, "off");//default off + m_record_hls_ts_fd = 0; + memset(m_record_hls_ts_filename, 0, URL_MAX_LEN); + m_record_hls_vod_fd = 0; + memset(m_record_hls_vod_filename, 0, URL_MAX_LEN); + sprintf(m_record_hls_path, "./vod");//default current path + m_record_hls_begin_tm_ms = 0; + m_record_hls_segment_duration = 10;//default 10s + m_record_hls_target_duration = m_record_hls_segment_duration; + sprintf(m_role_name, "role"); } @@ -104,6 +114,8 @@ int CSLSRole::uninit() remove_from_epoll(); invalid_srt(); } + close_hls_file(); + return ret; } @@ -274,6 +286,14 @@ bool CSLSRole::check_idle_streams_duration(int64_t cur_time_ms) return false; } +void CSLSRole::set_record_hls_path(const char *hls_path) +{ + if (hls_path && strlen(hls_path) > 0) { + strcpy(m_record_hls_path, hls_path); + } +} + + int CSLSRole::check_http_client() { if (NULL == m_http_client) { @@ -282,6 +302,141 @@ int CSLSRole::check_http_client() return SLS_OK; } +void CSLSRole::close_hls_file() +{ + + if (m_record_hls_ts_fd) { + sls_log(SLS_LOG_INFO, "[%p]CSLSRole::close_hls_file, close ts file='%s', fd=%d.", this, m_record_hls_ts_filename, m_record_hls_ts_fd); + ::close(m_record_hls_ts_fd); + m_record_hls_ts_fd = 0; + } + if (0 != m_record_hls_vod_fd) { + ::close(m_record_hls_vod_fd); + int vod_fd = 0; + vod_fd = ::open(m_record_hls_vod_filename, O_RDONLY, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IXOTH); + sls_log(SLS_LOG_INFO, "[%p]CSLSRole::close_hls_file, prepare open '%s', fd=%d.", this, m_record_hls_vod_filename, vod_fd); + sprintf(m_record_hls_vod_filename, "%s/vod.m3u8", m_record_hls_path); + struct stat stat_file; + if (0 == stat(m_record_hls_vod_filename, &stat_file)) { + m_record_hls_vod_fd = ::open(m_record_hls_vod_filename, O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IXOTH); + } else { + m_record_hls_vod_fd = ::open(m_record_hls_vod_filename, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IXOTH); + } + //write header + char m3u8_info[URL_MAX_LEN] = {0}; + sprintf(m3u8_info, "#EXTM3U\n\ +#EXT-X-VERSION:3\n\ +#EXT-X-TARGETDURATION:%d\n", (int)(m_record_hls_target_duration+1)); + ::write(m_record_hls_vod_fd, m3u8_info, strlen(m3u8_info)); + const int buf_len = 4096; + char buf[buf_len] = {0}; + while(true) { + int len = ::read(vod_fd, buf, buf_len); + sls_log(SLS_LOG_INFO, "[%p]CSLSRole::close_hls_file, read data len=%d, fd=%d.", this, len, vod_fd); + if (len == buf_len) { + ::write(m_record_hls_vod_fd, buf, len); + } else { + if (len > 0) + ::write(m_record_hls_vod_fd, buf, len); + break; + } + } + ::close(vod_fd); + + sprintf(m3u8_info, "#EXT-X-ENDLIST"); + ::write(m_record_hls_vod_fd, m3u8_info, strlen(m3u8_info)); + ::close(m_record_hls_vod_fd); + m_record_hls_vod_fd = 0; + } +} + +void CSLSRole::check_hls_file() +{ + //check file duration + int64_t cur_tm_ms = sls_gettime_ms(); + float d = cur_tm_ms - m_record_hls_begin_tm_ms; + d /=1000; + if (d < m_record_hls_segment_duration) { + return ; + } + m_record_hls_begin_tm_ms = cur_tm_ms; + + //check path + if (sls_mkdir_p(m_record_hls_path) != -1) { + sls_log(SLS_LOG_INFO, "[%p]CSLSRole::check_hls_file, mkdir '%s' ok.\n", this, m_record_hls_path); + } else { + if (errno != EEXIST) { + sls_log(SLS_LOG_INFO, "[%p]CSLSRole::check_hls_file, mkdir '%s' failed.\n", this, m_record_hls_path); + return ; + } + sls_log(SLS_LOG_INFO, "[%p]CSLSRole::check_hls_file, '%s' exist.\n", this, m_record_hls_path); + } + + //update ts file + if (m_record_hls_ts_fd) { + m_record_hls_target_duration = m_record_hls_target_durationget_ts_info(m_map_data_key, ts_info, TS_UDP_LEN); + if (re > 0) { + ::write(m_record_hls_ts_fd, ts_info, re); + } + } + } +} + +void CSLSRole::record_data2hls(char* data, int len) +{ + //check hls file + check_hls_file(); + + if (0 != m_record_hls_ts_fd) { + ::write(m_record_hls_ts_fd, data, len); + } + /* + //save data + static char out_file_name[URL_MAX_LEN] = {0}; + if (strlen(out_file_name) == 0) { + char cur_tm[256]; + sls_gettime_default_string(cur_tm); + sprintf(out_file_name, "./obs_%s.ts", cur_tm); + } + static int fd_out = open(out_file_name, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IXOTH); + + if (0 != fd_out) { + write(fd_out, data, len); + } + */ + +} int CSLSRole::handler_read_data(int64_t *last_read_time) { @@ -324,7 +479,13 @@ int CSLSRole::handler_read_data(int64_t *last_read_time) sls_log(SLS_LOG_TRACE, "[%p]CSLSRole::handler_read_data, ok, libsrt_read n=%d.", this, n); int ret = m_map_data->put(m_map_data_key, szData, n, last_read_time); - return ret; + + //record data + if (strcmp(m_record_hls, "on") == 0) { + record_data2hls(szData, n); + } + + return ret; } int CSLSRole::handler_write_data() diff --git a/slscore/SLSRole.hpp b/slscore/SLSRole.hpp index 054eb83..880ca4a 100644 --- a/slscore/SLSRole.hpp +++ b/slscore/SLSRole.hpp @@ -98,6 +98,7 @@ public : int check_http_client(); int check_http_passed(); + void set_record_hls_path(const char *hls_path); protected: CSLSSrt *m_srt; bool m_is_write;//listener: 0, publisher: 0, player: 1 @@ -131,9 +132,21 @@ public : std::string m_stat_info_base; CHttpClient *m_http_client; - int handler_write_data(); - int handler_read_data(int64_t *last_read_time=NULL); - + char m_record_hls[SHORT_STR_MAX_LEN]; + int m_record_hls_ts_fd ; + char m_record_hls_ts_filename[URL_MAX_LEN]; + int m_record_hls_vod_fd ; + char m_record_hls_vod_filename[URL_MAX_LEN]; + char m_record_hls_path[URL_MAX_LEN]; + int64_t m_record_hls_begin_tm_ms ; + int m_record_hls_segment_duration; + float m_record_hls_target_duration; + + int handler_write_data(); + int handler_read_data(int64_t *last_read_time=NULL); + void record_data2hls(char *data, int len); + void check_hls_file(); + void close_hls_file(); private: }; diff --git a/slscore/common.cpp b/slscore/common.cpp index 8ab102e..f7c1ab1 100644 --- a/slscore/common.cpp +++ b/slscore/common.cpp @@ -281,7 +281,7 @@ static int av_strncasecmp(const char *a, const char *b, size_t n) return c1 - c2; } -static int sls_mkdir_p(const char *path) +int sls_mkdir_p(const char *path) { int ret = 0; diff --git a/slscore/common.hpp b/slscore/common.hpp index c1738ec..30aeeea 100644 --- a/slscore/common.hpp +++ b/slscore/common.hpp @@ -76,6 +76,7 @@ using namespace std; #define TS_PACK_LEN 188 #define TS_UDP_LEN 1316 //7*188 +#define SHORT_STR_MAX_LEN 256 #define STR_MAX_LEN 1024 #define URL_MAX_LEN STR_MAX_LEN #define STR_DATE_TIME_LEN 32 @@ -94,6 +95,7 @@ void sls_remove_marks(char *s); uint32_t sls_hash_key(const char *data, int len); int sls_gethostbyname(const char *hostname, char *ip); +int sls_mkdir_p(const char *path); int sls_read_pid(); int sls_write_pid(int pid); diff --git a/~/sls/pid.txt b/~/sls/pid.txt new file mode 100755 index 0000000..e69de29