mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +08:00
初步完成Windows下的移植
This commit is contained in:
parent
a8b7d53f87
commit
a769d6c284
@ -8,20 +8,31 @@ set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
|||||||
#设置可执行程序路径
|
#设置可执行程序路径
|
||||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||||
#设置子目录
|
#设置子目录
|
||||||
set(SUB_DIR_LIST "Codec" "Common" "Device" "H264" "Http" "MediaFile" "Player" "Rtmp" "RTP" "Rtsp" "Shell" )
|
set(SUB_DIR_LIST "Codec" "Common" "Device" "H264" "Http" "MediaFile" "Player" "Rtmp" "RTP" "Rtsp" )
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
|
list(APPEND SUB_DIR_LIST "Shell")
|
||||||
|
endif()
|
||||||
|
|
||||||
#使能GOP缓存
|
#使能GOP缓存
|
||||||
add_definitions(-DENABLE_RING_USEBUF)
|
add_definitions(-DENABLE_RING_USEBUF)
|
||||||
|
|
||||||
|
|
||||||
|
#安装目录
|
||||||
|
if(WIN32)
|
||||||
|
set(INSTALL_PATH_LIB $ENV{HOME}/${CMAKE_PROJECT_NAME}/lib)
|
||||||
|
set(INSTALL_PATH_INCLUDE $ENV{HOME}/${CMAKE_PROJECT_NAME}/include)
|
||||||
|
else()
|
||||||
|
set(INSTALL_PATH_LIB lib)
|
||||||
|
set(INSTALL_PATH_INCLUDE include)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
foreach(SUB_DIR ${SUB_DIR_LIST})
|
foreach(SUB_DIR ${SUB_DIR_LIST})
|
||||||
#遍历源文件
|
#遍历源文件
|
||||||
aux_source_directory(src/${SUB_DIR} SRC_LIST)
|
aux_source_directory(src/${SUB_DIR} SRC_LIST)
|
||||||
#创建头文件安装文件夹
|
#安装头文件至系统目录
|
||||||
execute_process(COMMAND mkdir -p ${PROJECT_BINARY_DIR}/include/${CMAKE_PROJECT_NAME}/${SUB_DIR}/ )
|
install(DIRECTORY src/${SUB_DIR} DESTINATION ${INSTALL_PATH_INCLUDE}/${CMAKE_PROJECT_NAME} FILES_MATCHING PATTERN "*.h")
|
||||||
#遍历头文件
|
|
||||||
file(GLOB_RECURSE HEADER_FILES "${PROJECT_SOURCE_DIR}/src/${SUB_DIR}/*.h")
|
|
||||||
#拷贝头文件至安装文件夹
|
|
||||||
execute_process(COMMAND cp ${HEADER_FILES} ${PROJECT_BINARY_DIR}/include/${CMAKE_PROJECT_NAME}/${SUB_DIR}/ )
|
|
||||||
endforeach(SUB_DIR ${SUB_DIR_LIST})
|
endforeach(SUB_DIR ${SUB_DIR_LIST})
|
||||||
|
|
||||||
set(LINK_LIB_LIST)
|
set(LINK_LIB_LIST)
|
||||||
@ -91,32 +102,29 @@ include_directories(${PROJECT_SOURCE_DIR}/src)
|
|||||||
#使能c++11
|
#使能c++11
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
|
||||||
|
|
||||||
|
if(NOT WIN32)
|
||||||
#关闭过期接口警告
|
#关闭过期接口警告
|
||||||
add_compile_options(-Wno-deprecated-declarations)
|
add_compile_options(-Wno-deprecated-declarations)
|
||||||
#关闭__FUNCTION__宏在函数外警告
|
#关闭__FUNCTION__宏在函数外警告
|
||||||
add_compile_options(-Wno-predefined-identifier-outside-function)
|
add_compile_options(-Wno-predefined-identifier-outside-function)
|
||||||
|
endif(NOT WIN32)
|
||||||
|
|
||||||
#编译动态库
|
#编译动态库
|
||||||
if(NOT IOS AND NOT ANDROID)
|
if(NOT IOS AND NOT ANDROID)
|
||||||
add_library(${CMAKE_PROJECT_NAME}_shared SHARED ${SRC_LIST})
|
add_library(${CMAKE_PROJECT_NAME}_shared SHARED ${SRC_LIST})
|
||||||
set_target_properties(${CMAKE_PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME "${CMAKE_PROJECT_NAME}")
|
set_target_properties(${CMAKE_PROJECT_NAME}_shared PROPERTIES OUTPUT_NAME "${CMAKE_PROJECT_NAME}")
|
||||||
install(TARGETS ${CMAKE_PROJECT_NAME}_shared LIBRARY DESTINATION lib)
|
install(TARGETS ${CMAKE_PROJECT_NAME}_shared ARCHIVE DESTINATION ${INSTALL_PATH_LIB} LIBRARY DESTINATION ${INSTALL_PATH_LIB})
|
||||||
target_link_libraries(${CMAKE_PROJECT_NAME}_shared ${LINK_LIB_LIST})
|
target_link_libraries(${CMAKE_PROJECT_NAME}_shared ${LINK_LIB_LIST})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#编译静态库
|
#编译静态库
|
||||||
add_library(${CMAKE_PROJECT_NAME}_static STATIC ${SRC_LIST})
|
add_library(${CMAKE_PROJECT_NAME}_static STATIC ${SRC_LIST})
|
||||||
set_target_properties(${CMAKE_PROJECT_NAME}_static PROPERTIES OUTPUT_NAME "${CMAKE_PROJECT_NAME}")
|
set_target_properties(${CMAKE_PROJECT_NAME}_static PROPERTIES OUTPUT_NAME "${CMAKE_PROJECT_NAME}")
|
||||||
install(TARGETS ${CMAKE_PROJECT_NAME}_static ARCHIVE DESTINATION lib)
|
install(TARGETS ${CMAKE_PROJECT_NAME}_static ARCHIVE DESTINATION ${INSTALL_PATH_LIB})
|
||||||
|
|
||||||
#安装头文件至系统目录
|
|
||||||
install(DIRECTORY ${PROJECT_BINARY_DIR}/include/${CMAKE_PROJECT_NAME} DESTINATION include)
|
|
||||||
|
|
||||||
#测试程序
|
#测试程序
|
||||||
if(NOT IOS)
|
if(NOT IOS)
|
||||||
add_subdirectory(tests)
|
add_subdirectory(tests)
|
||||||
else(NOT IOS)
|
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/../ZLToolKit/src)
|
|
||||||
endif(NOT IOS)
|
endif(NOT IOS)
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
include(CheckCXXSourceCompiles)
|
include(CheckCXXSourceCompiles)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
find_path(MYSQL_INCLUDE_DIR mysql/mysql.h
|
find_path(MYSQL_INCLUDE_DIR mysql.h
|
||||||
PATHS
|
PATHS
|
||||||
$ENV{MYSQL_INCLUDE_DIR}
|
$ENV{MYSQL_INCLUDE_DIR}
|
||||||
$ENV{MYSQL_DIR}/include
|
$ENV{MYSQL_DIR}/include
|
||||||
@ -64,6 +64,7 @@ if(WIN32)
|
|||||||
$ENV{MYSQL_DIR}/lib/opt
|
$ENV{MYSQL_DIR}/lib/opt
|
||||||
$ENV{MYSQL_DIR}/client/release
|
$ENV{MYSQL_DIR}/client/release
|
||||||
$ENV{ProgramFiles}/MySQL/*/lib/opt
|
$ENV{ProgramFiles}/MySQL/*/lib/opt
|
||||||
|
$ENV{ProgramFiles}/MySQL/*/lib/
|
||||||
$ENV{SystemDrive}/MySQL/*/lib/opt
|
$ENV{SystemDrive}/MySQL/*/lib/opt
|
||||||
$ENV{ProgramW6432}/MySQL/*/lib
|
$ENV{ProgramW6432}/MySQL/*/lib
|
||||||
)
|
)
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
find_path(ZLTOOLKIT_INCLUDE_DIR
|
find_path(ZLTOOLKIT_INCLUDE_DIR
|
||||||
NAMES ZLToolKit/Network/Socket.h)
|
NAMES ZLToolKit/Network/Socket.h
|
||||||
|
PATHS $ENV{HOME}/ZLToolKit/include)
|
||||||
|
|
||||||
find_library(ZLTOOLKIT_LIBRARY
|
find_library(ZLTOOLKIT_LIBRARY
|
||||||
NAMES ZLToolKit)
|
NAMES ZLToolKit
|
||||||
|
PATHS $ENV{HOME}/ZLToolKit/lib)
|
||||||
|
|
||||||
set(ZLTOOLKIT_LIBRARIES ${ZLTOOLKIT_LIBRARY})
|
set(ZLTOOLKIT_LIBRARIES ${ZLTOOLKIT_LIBRARY})
|
||||||
set(ZLTOOLKIT_INCLUDE_DIRS ${ZLTOOLKIT_INCLUDE_DIR})
|
set(ZLTOOLKIT_INCLUDE_DIRS ${ZLTOOLKIT_INCLUDE_DIR})
|
||||||
|
@ -57,20 +57,20 @@ Vui参数集视频可用性信息视频标准化选项
|
|||||||
int i_sar_height;
|
int i_sar_height;
|
||||||
int i_sar_width; 设置长宽比
|
int i_sar_width; 设置长宽比
|
||||||
|
|
||||||
int i_overscan; 0=undef, 1=no overscan, 2=overscan 过扫描线,默认"undef"(不设置),可选项:show(观看)/crop(去除)
|
int i_overscan; 0=undef, 1=no overscan, 2=overscan 过扫描线,默认"undef"(不设置),可选项:show(观看)/crop(去除)
|
||||||
|
|
||||||
见以下的值h264附件E
|
见以下的值h264附件E
|
||||||
Int i_vidformat; 视频格式,默认"undef",component/pal/ntsc/secam/mac/undef
|
Int i_vidformat; 视频格式,默认"undef",component/pal/ntsc/secam/mac/undef
|
||||||
int b_fullrange; Specify full range samples setting,默认"off",可选项:off/on
|
int b_fullrange; Specify full range samples setting,默认"off",可选项:off/on
|
||||||
int i_colorprim; 原始色度格式,默认"undef",可选项:undef/bt709/bt470m/bt470bg,smpte170m/smpte240m/film
|
int i_colorprim; 原始色度格式,默认"undef",可选项:undef/bt709/bt470m/bt470bg,smpte170m/smpte240m/film
|
||||||
int i_transfer; 转换方式,默认"undef",可选项:undef/bt709/bt470m/bt470bg/linear,log100/log316/smpte170m/smpte240m
|
int i_transfer; 转换方式,默认"undef",可选项:undef/bt709/bt470m/bt470bg/linear,log100/log316/smpte170m/smpte240m
|
||||||
int i_colmatrix; 色度矩阵设置,默认"undef",undef/bt709/fcc/bt470bg,smpte170m/smpte240m/GBR/YCgCo
|
int i_colmatrix; 色度矩阵设置,默认"undef",undef/bt709/fcc/bt470bg,smpte170m/smpte240m/GBR/YCgCo
|
||||||
int i_chroma_loc; both top & bottom色度样本指定,范围0~5,默认0
|
int i_chroma_loc; both top & bottom色度样本指定,范围0~5,默认0
|
||||||
} vui;
|
} vui;
|
||||||
|
|
||||||
int i_fps_num;
|
int i_fps_num;
|
||||||
int i_fps_den;
|
int i_fps_den;
|
||||||
这两个参数是由fps帧率确定的,赋值的过程见下:
|
这两个参数是由fps帧率确定的,赋值的过程见下:
|
||||||
{ float fps;
|
{ float fps;
|
||||||
if( sscanf( value, "%d/%d", &p->i_fps_num, &p->i_fps_den ) == 2 )
|
if( sscanf( value, "%d/%d", &p->i_fps_num, &p->i_fps_den ) == 2 )
|
||||||
;
|
;
|
||||||
@ -137,7 +137,7 @@ Value的值就是fps。
|
|||||||
int i_subpel_refine; 亚像素运动估计质量
|
int i_subpel_refine; 亚像素运动估计质量
|
||||||
int b_chroma_me; 亚像素色度运动估计和P帧的模式选择
|
int b_chroma_me; 亚像素色度运动估计和P帧的模式选择
|
||||||
int b_mixed_references; 允许每个宏块的分区在P帧有它自己的参考号
|
int b_mixed_references; 允许每个宏块的分区在P帧有它自己的参考号
|
||||||
int i_trellis; Trellis量化,对每个8x8的块寻找合适的量化值,需要CABAC,默认0 0:关闭1:只在最后编码时使用2:一直使用
|
int i_trellis; Trellis量化,对每个8x8的块寻找合适的量化值,需要CABAC,默认0 0:关闭1:只在最后编码时使用2:一直使用
|
||||||
int b_fast_pskip; 快速P帧跳过检测
|
int b_fast_pskip; 快速P帧跳过检测
|
||||||
int b_dct_decimate; 在P-frames转换参数域
|
int b_dct_decimate; 在P-frames转换参数域
|
||||||
int i_noise_reduction; 自适应伪盲区
|
int i_noise_reduction; 自适应伪盲区
|
||||||
@ -249,13 +249,13 @@ bool H264Encoder::init(int iWidth, int iHeight, int iFps) {
|
|||||||
这个GOP就称为open-GOP。
|
这个GOP就称为open-GOP。
|
||||||
有些解码器不能完全支持open-GOP码流,
|
有些解码器不能完全支持open-GOP码流,
|
||||||
例如蓝光解码器,因此在x264里面open-GOP是默认关闭的。
|
例如蓝光解码器,因此在x264里面open-GOP是默认关闭的。
|
||||||
对于解码端,接收到的码流如果如下:I0 B0 B1 P0 B2 B3...这就是一个open-GOP码流(I帧后面紧跟B帧)。
|
对于解码端,接收到的码流如果如下:I0 B0 B1 P0 B2 B3...这就是一个open-GOP码流(I帧后面紧跟B帧)。
|
||||||
因此B0 B1的解码需要用到I0前面一个GOP的数据,B0 B1的dts是小于I0的。
|
因此B0 B1的解码需要用到I0前面一个GOP的数据,B0 B1的dts是小于I0的。
|
||||||
如果码流如下: I0 P0 B0 B1 P1 B2 B3...这就是一个close-GOP码流,
|
如果码流如下: I0 P0 B0 B1 P1 B2 B3...这就是一个close-GOP码流,
|
||||||
I0后面所有帧的解码不依赖于I0前面的帧,I0后面所有帧的dts都比I0的大。
|
I0后面所有帧的解码不依赖于I0前面的帧,I0后面所有帧的dts都比I0的大。
|
||||||
如果码流是IDR0 B0 B1 P0 B2 B3...那个这个GOP是close-GOP,B0,B1虽然dst比IDR0小,
|
如果码流是IDR0 B0 B1 P0 B2 B3...那个这个GOP是close-GOP,B0,B1虽然dst比IDR0小,
|
||||||
但编解码端都刷新了参考缓冲,B0,B1参考不到前向GOP帧。
|
但编解码端都刷新了参考缓冲,B0,B1参考不到前向GOP帧。
|
||||||
对于编码端,如果编码帧类型决定如下: ...P0 B1 B2 P3 B4 B5 I6这就会输出open-Gop码流 (P0 P3 B1 B2 I6 B4 B5...),
|
对于编码端,如果编码帧类型决定如下: ...P0 B1 B2 P3 B4 B5 I6这就会输出open-Gop码流 (P0 P3 B1 B2 I6 B4 B5...),
|
||||||
B4 B5的解码依赖P3。
|
B4 B5的解码依赖P3。
|
||||||
如果编码帧类型决定如下...P0 B1 B2 P3 B4 P5 I6这样就不会输出open-GOP码流(P0 P3 B1 B2 P5 B4 I6...)。
|
如果编码帧类型决定如下...P0 B1 B2 P3 B4 P5 I6这样就不会输出open-GOP码流(P0 P3 B1 B2 P5 B4 I6...)。
|
||||||
两者区别在于I6前面的第5帧是设置为B帧还是P帧,
|
两者区别在于I6前面的第5帧是设置为B帧还是P帧,
|
||||||
|
@ -9,6 +9,17 @@
|
|||||||
|
|
||||||
using namespace ZL::Network;
|
using namespace ZL::Network;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
static onceToken g_token([]() {
|
||||||
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
||||||
|
WSADATA wsaData;
|
||||||
|
WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
}, []() {
|
||||||
|
WSACleanup();
|
||||||
|
});
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
namespace Config {
|
namespace Config {
|
||||||
|
|
||||||
void loaIniConfig(){
|
void loaIniConfig(){
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef DEVICE_DEVICE_H_
|
#ifndef DEVICE_DEVICE_H_
|
||||||
#define DEVICE_DEVICE_H_
|
#define DEVICE_DEVICE_H_
|
||||||
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h> /* for uint32_t, etc */
|
#include <stdint.h> /* for uint32_t, etc */
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include "SPSParser.h"
|
#include "SPSParser.h"
|
||||||
|
|
||||||
/********************************************
|
/********************************************
|
||||||
|
@ -173,7 +173,7 @@ return kInvalidStream; \
|
|||||||
start += subsamples[i].clear_bytes;
|
start += subsamples[i].clear_bytes;
|
||||||
|
|
||||||
const uint8_t* end =
|
const uint8_t* end =
|
||||||
std::min(start + subsamples[i].cypher_bytes, stream_end);
|
min(start + subsamples[i].cypher_bytes, stream_end);
|
||||||
encrypted_ranges_.Add(start, end);
|
encrypted_ranges_.Add(start, end);
|
||||||
start = end;
|
start = end;
|
||||||
}
|
}
|
||||||
@ -311,7 +311,7 @@ return kInvalidStream; \
|
|||||||
// The start code is inside an encrypted section so we need to scan
|
// The start code is inside an encrypted section so we need to scan
|
||||||
// for another start code.
|
// for another start code.
|
||||||
*start_code_size = 0;
|
*start_code_size = 0;
|
||||||
start += std::min(*offset + 1, bytes_left);
|
start += min(*offset + 1, bytes_left);
|
||||||
}
|
}
|
||||||
} while (*start_code_size == 0);
|
} while (*start_code_size == 0);
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ namespace media {
|
|||||||
// (assuming no interlacing).
|
// (assuming no interlacing).
|
||||||
int32_t top_foc = pic_order_cnt_msb + slice_hdr.pic_order_cnt_lsb;
|
int32_t top_foc = pic_order_cnt_msb + slice_hdr.pic_order_cnt_lsb;
|
||||||
int32_t bottom_foc = top_foc + slice_hdr.delta_pic_order_cnt_bottom;
|
int32_t bottom_foc = top_foc + slice_hdr.delta_pic_order_cnt_bottom;
|
||||||
*pic_order_cnt = std::min(top_foc, bottom_foc);
|
*pic_order_cnt = min(top_foc, bottom_foc);
|
||||||
|
|
||||||
// Store state.
|
// Store state.
|
||||||
prev_frame_num_ = slice_hdr.frame_num;
|
prev_frame_num_ = slice_hdr.frame_num;
|
||||||
@ -182,7 +182,7 @@ namespace media {
|
|||||||
int32_t top_foc = expected_pic_order_cnt + slice_hdr.delta_pic_order_cnt0;
|
int32_t top_foc = expected_pic_order_cnt + slice_hdr.delta_pic_order_cnt0;
|
||||||
int32_t bottom_foc = top_foc + sps->offset_for_top_to_bottom_field +
|
int32_t bottom_foc = top_foc + sps->offset_for_top_to_bottom_field +
|
||||||
slice_hdr.delta_pic_order_cnt1;
|
slice_hdr.delta_pic_order_cnt1;
|
||||||
*pic_order_cnt = std::min(top_foc, bottom_foc);
|
*pic_order_cnt = min(top_foc, bottom_foc);
|
||||||
|
|
||||||
// Store state.
|
// Store state.
|
||||||
prev_frame_num_ = slice_hdr.frame_num;
|
prev_frame_num_ = slice_hdr.frame_num;
|
||||||
|
@ -27,7 +27,7 @@ void HttpClient::sendRequest(const string &strUrl){
|
|||||||
defaultPort = 443;
|
defaultPort = 443;
|
||||||
isHttps = true;
|
isHttps = true;
|
||||||
}else{
|
}else{
|
||||||
auto strErr = StrPrinter << "非法的协议:" << protocol << endl;
|
auto strErr = StrPrinter << "非法的协议:" << protocol << endl;
|
||||||
throw std::invalid_argument(strErr);
|
throw std::invalid_argument(strErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
#include "strCoding.h"
|
#include "strCoding.h"
|
||||||
@ -146,7 +145,7 @@ void HttpSession::onManager() {
|
|||||||
static uint32_t keepAliveSec = mINI::Instance()[Config::Http::kKeepAliveSecond].as<uint32_t>();
|
static uint32_t keepAliveSec = mINI::Instance()[Config::Http::kKeepAliveSecond].as<uint32_t>();
|
||||||
if(m_ticker.elapsedTime() > keepAliveSec * 1000){
|
if(m_ticker.elapsedTime() > keepAliveSec * 1000){
|
||||||
//1分钟超时
|
//1分钟超时
|
||||||
WarnL<<"HttpSession超时断开!";
|
WarnL<<"HttpSession timeouted!";
|
||||||
shutdown();
|
shutdown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,7 +225,7 @@ inline HttpSession::HttpCode HttpSession::Handle_Req_GET() {
|
|||||||
int64_t iReq = MIN(sendBufSize,*piLeft);
|
int64_t iReq = MIN(sendBufSize,*piLeft);
|
||||||
int64_t iRead = fread(pacSendBuf.get(), 1, iReq, pFilePtr.get());
|
int64_t iRead = fread(pacSendBuf.get(), 1, iReq, pFilePtr.get());
|
||||||
*piLeft -= iRead;
|
*piLeft -= iRead;
|
||||||
//InfoL << "Send file :" << iReq << " " << *piLeft;
|
//InfoL << "Send file :" << iReq << " " << *piLeft;
|
||||||
if (iRead < iReq || !*piLeft) {
|
if (iRead < iReq || !*piLeft) {
|
||||||
//send completed!
|
//send completed!
|
||||||
//FatalL << "send completed!";
|
//FatalL << "send completed!";
|
||||||
@ -280,13 +279,13 @@ inline bool HttpSession::makeMeun(const string &strFullPath, string &strRet) {
|
|||||||
strRet += "<li><a href=\"";
|
strRet += "<li><a href=\"";
|
||||||
strRet += "/";
|
strRet += "/";
|
||||||
strRet += "\">";
|
strRet += "\">";
|
||||||
strRet += "根目录";
|
strRet += "root directory";
|
||||||
strRet += "</a></li>\r\n";
|
strRet += "</a></li>\r\n";
|
||||||
|
|
||||||
strRet += "<li><a href=\"";
|
strRet += "<li><a href=\"";
|
||||||
strRet += "../";
|
strRet += "../";
|
||||||
strRet += "\">";
|
strRet += "\">";
|
||||||
strRet += "上一级目录";
|
strRet += "parent directory";
|
||||||
strRet += "</a></li>\r\n";
|
strRet += "</a></li>\r\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "HLSMaker.h"
|
#include "HLSMaker.h"
|
||||||
#include <sys/time.h>
|
#include "Util/File.h"
|
||||||
|
#include "Util/uv_errno.h"
|
||||||
|
|
||||||
|
using namespace ZL::Util;
|
||||||
|
|
||||||
namespace ZL {
|
namespace ZL {
|
||||||
namespace MediaFile {
|
namespace MediaFile {
|
||||||
@ -126,7 +129,7 @@ void HLSMaker::inputH264(void *data, uint32_t length, uint32_t timeStamp,
|
|||||||
m_Timer.resetTime();
|
m_Timer.resetTime();
|
||||||
removets();
|
removets();
|
||||||
if (write_index_file(m_ui64TsCnt - m_ui32NumSegments, m_ui64TsCnt, 0) == -1) {
|
if (write_index_file(m_ui64TsCnt - m_ui32NumSegments, m_ui64TsCnt, 0) == -1) {
|
||||||
WarnL << "write_index_file error :" << strerror(errno);
|
WarnL << "write_index_file error :" << get_uv_errmsg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 1: //P
|
case 1: //P
|
||||||
|
@ -23,7 +23,7 @@ MediaReader::MediaReader(const string &strApp, const string &strId) {
|
|||||||
|
|
||||||
m_hMP4File = MP4Read(strFileName.data());
|
m_hMP4File = MP4Read(strFileName.data());
|
||||||
if(m_hMP4File == MP4_INVALID_FILE_HANDLE){
|
if(m_hMP4File == MP4_INVALID_FILE_HANDLE){
|
||||||
throw runtime_error(StrPrinter << "打开MP4文件失败:" << strFileName << endl);
|
throw runtime_error(StrPrinter << "打开MP4文件失败:" << strFileName << endl);
|
||||||
}
|
}
|
||||||
m_video_trId = MP4FindTrackId(m_hMP4File, 0, MP4_VIDEO_TRACK_TYPE, 0);
|
m_video_trId = MP4FindTrackId(m_hMP4File, 0, MP4_VIDEO_TRACK_TYPE, 0);
|
||||||
if(m_video_trId != MP4_INVALID_TRACK_ID){
|
if(m_video_trId != MP4_INVALID_TRACK_ID){
|
||||||
@ -106,7 +106,7 @@ MediaReader::MediaReader(const string &strApp, const string &strId) {
|
|||||||
if(m_audio_trId == MP4_INVALID_TRACK_ID && m_video_trId == MP4_INVALID_TRACK_ID){
|
if(m_audio_trId == MP4_INVALID_TRACK_ID && m_video_trId == MP4_INVALID_TRACK_ID){
|
||||||
MP4Close(m_hMP4File);
|
MP4Close(m_hMP4File);
|
||||||
m_hMP4File = MP4_INVALID_FILE_HANDLE;
|
m_hMP4File = MP4_INVALID_FILE_HANDLE;
|
||||||
throw runtime_error(StrPrinter << "该MP4文件音视频格式不支持:" << strFileName << endl);
|
throw runtime_error(StrPrinter << "该MP4文件音视频格式不支持:" << strFileName << endl);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_iDuration = MAX(m_video_ms,m_audio_ms);
|
m_iDuration = MAX(m_video_ms,m_audio_ms);
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TSMaker.h"
|
#include "TSMaker.h"
|
||||||
#include <sys/time.h>
|
|
||||||
#include "Util/logger.h"
|
#include "Util/logger.h"
|
||||||
|
|
||||||
using namespace ZL::Util;
|
using namespace ZL::Util;
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
* Author: xzl
|
* Author: xzl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
#include "RtpMakerAAC.h"
|
#include "RtpMakerAAC.h"
|
||||||
#include "Util/mini.h"
|
#include "Util/mini.h"
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
* Author: xzl
|
* Author: xzl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
#include "RtpMakerH264.h"
|
#include "RtpMakerH264.h"
|
||||||
#include "Util/mini.h"
|
#include "Util/mini.h"
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#ifndef __rtmp_h
|
#ifndef __rtmp_h
|
||||||
#define __rtmp_h
|
#define __rtmp_h
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
@ -12,7 +11,14 @@ using namespace ZL::Util;
|
|||||||
|
|
||||||
#define PORT 1935
|
#define PORT 1935
|
||||||
#define DEFAULT_CHUNK_LEN 128
|
#define DEFAULT_CHUNK_LEN 128
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
#define PACKED __attribute__((packed))
|
#define PACKED __attribute__((packed))
|
||||||
|
#else
|
||||||
|
#define PACKED
|
||||||
|
#endif //!defined(_WIN32)
|
||||||
|
|
||||||
|
|
||||||
#define HANDSHAKE_PLAINTEXT 0x03
|
#define HANDSHAKE_PLAINTEXT 0x03
|
||||||
#define RANDOM_LEN (1536 - 8)
|
#define RANDOM_LEN (1536 - 8)
|
||||||
|
|
||||||
@ -52,6 +58,11 @@ using namespace ZL::Util;
|
|||||||
#define FLV_KEY_FRAME 1
|
#define FLV_KEY_FRAME 1
|
||||||
#define FLV_INTER_FRAME 2
|
#define FLV_INTER_FRAME 2
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
class RtmpHandshake {
|
class RtmpHandshake {
|
||||||
public:
|
public:
|
||||||
RtmpHandshake(uint32_t _time, uint8_t *_random = nullptr) {
|
RtmpHandshake(uint32_t _time, uint8_t *_random = nullptr) {
|
||||||
@ -87,6 +98,9 @@ public:
|
|||||||
uint8_t streamId[4]; /* Note, this is little-endian while others are BE */
|
uint8_t streamId[4]; /* Note, this is little-endian while others are BE */
|
||||||
}PACKED;
|
}PACKED;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#pragma pack(pop)
|
||||||
|
#endif // defined(_WIN32)
|
||||||
|
|
||||||
class RtmpPacket {
|
class RtmpPacket {
|
||||||
public:
|
public:
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef SRC_RTMP_RTMPMEDIASOURCE_H_
|
#ifndef SRC_RTMP_RTMPMEDIASOURCE_H_
|
||||||
#define SRC_RTMP_RTMPMEDIASOURCE_H_
|
#define SRC_RTMP_RTMPMEDIASOURCE_H_
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -19,14 +19,14 @@ RtmpParser::RtmpParser(const AMFValue &val) {
|
|||||||
//264
|
//264
|
||||||
m_bHaveVideo = true;
|
m_bHaveVideo = true;
|
||||||
} else {
|
} else {
|
||||||
InfoL << "不支持RTMP视频格式:" << videoCodec.as_string();
|
InfoL << "不支持RTMP视频格式:" << videoCodec.as_string();
|
||||||
}
|
}
|
||||||
}else if (videoCodec.type() != AMF_NULL){
|
}else if (videoCodec.type() != AMF_NULL){
|
||||||
if (videoCodec.as_integer() == 7) {
|
if (videoCodec.as_integer() == 7) {
|
||||||
//264
|
//264
|
||||||
m_bHaveVideo = true;
|
m_bHaveVideo = true;
|
||||||
} else {
|
} else {
|
||||||
InfoL << "不支持RTMP视频格式:" << videoCodec.as_integer();
|
InfoL << "不支持RTMP视频格式:" << videoCodec.as_integer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,14 +36,14 @@ RtmpParser::RtmpParser(const AMFValue &val) {
|
|||||||
//aac
|
//aac
|
||||||
m_bHaveAudio = true;
|
m_bHaveAudio = true;
|
||||||
} else {
|
} else {
|
||||||
InfoL << "不支持RTMP音频格式:" << audioCodec.as_string();
|
InfoL << "不支持RTMP音频格式:" << audioCodec.as_string();
|
||||||
}
|
}
|
||||||
}else if (audioCodec.type() != AMF_NULL) {
|
}else if (audioCodec.type() != AMF_NULL) {
|
||||||
if (audioCodec.as_integer() == 10) {
|
if (audioCodec.as_integer() == 10) {
|
||||||
//aac
|
//aac
|
||||||
m_bHaveAudio = true;
|
m_bHaveAudio = true;
|
||||||
} else {
|
} else {
|
||||||
InfoL << "不支持RTMP音频格式:" << audioCodec.as_integer();
|
InfoL << "不支持RTMP音频格式:" << audioCodec.as_integer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ inline void RtmpPlayer::send_connect() {
|
|||||||
auto level = val["level"].as_string();
|
auto level = val["level"].as_string();
|
||||||
auto code = val["code"].as_string();
|
auto code = val["code"].as_string();
|
||||||
if(level != "status"){
|
if(level != "status"){
|
||||||
throw std::runtime_error(StrPrinter <<"connect 失败:" << level << " " << code << endl);
|
throw std::runtime_error(StrPrinter <<"connect 失败:" << level << " " << code << endl);
|
||||||
}
|
}
|
||||||
send_createStream();
|
send_createStream();
|
||||||
});
|
});
|
||||||
@ -170,7 +170,7 @@ inline void RtmpPlayer::send_play() {
|
|||||||
auto level = val["level"].as_string();
|
auto level = val["level"].as_string();
|
||||||
auto code = val["code"].as_string();
|
auto code = val["code"].as_string();
|
||||||
if(level != "status"){
|
if(level != "status"){
|
||||||
throw std::runtime_error(StrPrinter <<"play 失败:" << level << " " << code << endl);
|
throw std::runtime_error(StrPrinter <<"play 失败:" << level << " " << code << endl);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
addOnStatusCB(fun);
|
addOnStatusCB(fun);
|
||||||
@ -187,7 +187,7 @@ inline void RtmpPlayer::send_pause(bool bPause) {
|
|||||||
auto code = val["code"].as_string();
|
auto code = val["code"].as_string();
|
||||||
if(level != "status") {
|
if(level != "status") {
|
||||||
if(!bPause){
|
if(!bPause){
|
||||||
throw std::runtime_error(StrPrinter <<"pause 恢复播放失败:" << level << " " << code << endl);
|
throw std::runtime_error(StrPrinter <<"pause 恢复播放失败:" << level << " " << code << endl);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
m_bPaused = bPause;
|
m_bPaused = bPause;
|
||||||
@ -236,7 +236,7 @@ void RtmpPlayer::onCmd_onStatus(AMFDecoder &dec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(val.type() != AMF_OBJECT){
|
if(val.type() != AMF_OBJECT){
|
||||||
throw std::runtime_error("onStatus: 未找到结果对象");
|
throw std::runtime_error("onStatus:the result object was not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
|
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef SRC_RTMP_RtmpPlayer2_H_
|
#ifndef SRC_RTMP_RtmpPlayer2_H_
|
||||||
#define SRC_RTMP_RtmpPlayer2_H_
|
#define SRC_RTMP_RtmpPlayer2_H_
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -14,17 +14,29 @@
|
|||||||
using namespace ZL::Util;
|
using namespace ZL::Util;
|
||||||
|
|
||||||
#ifdef ENABLE_OPENSSL
|
#ifdef ENABLE_OPENSSL
|
||||||
|
#include "Util/SSLBox.h"
|
||||||
#include <openssl/hmac.h>
|
#include <openssl/hmac.h>
|
||||||
static string openssl_HMACsha256(const void *key,unsigned int key_len,
|
static string openssl_HMACsha256(const void *key,unsigned int key_len,
|
||||||
const void *data,unsigned int data_len){
|
const void *data,unsigned int data_len){
|
||||||
std::shared_ptr<char> out(new char[32],[](char *ptr){delete [] ptr;});
|
std::shared_ptr<char> out(new char[32],[](char *ptr){delete [] ptr;});
|
||||||
unsigned int out_len;
|
unsigned int out_len;
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
HMAC_CTX *ctx = HMAC_CTX_new();
|
||||||
|
HMAC_CTX_reset(ctx);
|
||||||
|
HMAC_Init_ex(ctx, key, key_len, EVP_sha256(), NULL);
|
||||||
|
HMAC_Update(ctx, (unsigned char*)data, data_len);
|
||||||
|
HMAC_Final(ctx, (unsigned char *)out.get(), &out_len);
|
||||||
|
HMAC_CTX_reset(ctx);
|
||||||
|
HMAC_CTX_free(ctx);
|
||||||
|
#else
|
||||||
HMAC_CTX ctx;
|
HMAC_CTX ctx;
|
||||||
HMAC_CTX_init(&ctx);
|
HMAC_CTX_init(&ctx);
|
||||||
HMAC_Init_ex(&ctx, key, key_len, EVP_sha256(), NULL);
|
HMAC_Init_ex(&ctx, key, key_len, EVP_sha256(), NULL);
|
||||||
HMAC_Update(&ctx, (unsigned char*)data, data_len);
|
HMAC_Update(&ctx, (unsigned char*)data, data_len);
|
||||||
HMAC_Final(&ctx, (unsigned char *)out.get(), &out_len);
|
HMAC_Final(&ctx, (unsigned char *)out.get(), &out_len);
|
||||||
HMAC_CTX_cleanup(&ctx);
|
HMAC_CTX_cleanup(&ctx);
|
||||||
|
#endif // defined(WIN32)
|
||||||
return string(out.get(),out_len);
|
return string(out.get(),out_len);
|
||||||
}
|
}
|
||||||
#endif //ENABLE_OPENSSL
|
#endif //ENABLE_OPENSSL
|
||||||
@ -159,7 +171,7 @@ void RtmpProtocol::sendRequest(int iCmd, const string& str) {
|
|||||||
void RtmpProtocol::sendRtmp(uint8_t ui8Type, uint32_t ui32StreamId,
|
void RtmpProtocol::sendRtmp(uint8_t ui8Type, uint32_t ui32StreamId,
|
||||||
const std::string& strBuf, uint32_t ui32TimeStamp, int iChunkId) {
|
const std::string& strBuf, uint32_t ui32TimeStamp, int iChunkId) {
|
||||||
if (iChunkId < 2 || iChunkId > 63) {
|
if (iChunkId < 2 || iChunkId > 63) {
|
||||||
auto strErr = StrPrinter << "不支持发送该类型的块流 ID:" << iChunkId << endl;
|
auto strErr = StrPrinter << "不支持发送该类型的块流 ID:" << iChunkId << endl;
|
||||||
throw std::runtime_error(strErr);
|
throw std::runtime_error(strErr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +287,7 @@ void RtmpProtocol::handle_C1_simple(){
|
|||||||
}
|
}
|
||||||
#ifdef ENABLE_OPENSSL
|
#ifdef ENABLE_OPENSSL
|
||||||
void RtmpProtocol::handle_C1_complex(){
|
void RtmpProtocol::handle_C1_complex(){
|
||||||
//参考自:http://blog.csdn.net/win_lin/article/details/13006803
|
//参考自:http://blog.csdn.net/win_lin/article/details/13006803
|
||||||
//skip c0,time,version
|
//skip c0,time,version
|
||||||
const char *c1_start = m_strRcvBuf.data() + 1;
|
const char *c1_start = m_strRcvBuf.data() + 1;
|
||||||
const char *schema_start = c1_start + 8;
|
const char *schema_start = c1_start + 8;
|
||||||
@ -318,6 +330,9 @@ void RtmpProtocol::handle_C1_complex(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(u_int8_t)
|
||||||
|
#define u_int8_t unsigned char
|
||||||
|
#endif // !defined(u_int8_t)
|
||||||
|
|
||||||
static u_int8_t FMSKey[] = {
|
static u_int8_t FMSKey[] = {
|
||||||
0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20,
|
0x47, 0x65, 0x6e, 0x75, 0x69, 0x6e, 0x65, 0x20,
|
||||||
@ -344,7 +359,7 @@ static u_int8_t FPKey[] = {
|
|||||||
void RtmpProtocol::check_C1_Digest(const string &digest,const string &data){
|
void RtmpProtocol::check_C1_Digest(const string &digest,const string &data){
|
||||||
auto sha256 = openssl_HMACsha256(FPKey,C1_FPKEY_SIZE,data.data(),data.size());
|
auto sha256 = openssl_HMACsha256(FPKey,C1_FPKEY_SIZE,data.data(),data.size());
|
||||||
if(sha256 != digest){
|
if(sha256 != digest){
|
||||||
throw std::runtime_error("digest不匹配");
|
throw std::runtime_error("digest mismatched");
|
||||||
}else{
|
}else{
|
||||||
InfoL << "check rtmp complex handshark success!";
|
InfoL << "check rtmp complex handshark success!";
|
||||||
}
|
}
|
||||||
@ -383,7 +398,7 @@ string RtmpProtocol::get_C1_key(const uint8_t *ptr){
|
|||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
void RtmpProtocol::send_complex_S0S1S2(int schemeType,const string &digest){
|
void RtmpProtocol::send_complex_S0S1S2(int schemeType,const string &digest){
|
||||||
//S1S2计算参考自:https://github.com/hitYangfei/golang/blob/master/rtmpserver.go
|
//S1S2计算参考自:https://github.com/hitYangfei/golang/blob/master/rtmpserver.go
|
||||||
//发送S0
|
//发送S0
|
||||||
char handshake_head = HANDSHAKE_PLAINTEXT;
|
char handshake_head = HANDSHAKE_PLAINTEXT;
|
||||||
onSendRawData(&handshake_head, 1);
|
onSendRawData(&handshake_head, 1);
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef SRC_RTMP_RTMPPROTOCOL_H_
|
#ifndef SRC_RTMP_RTMPPROTOCOL_H_
|
||||||
#define SRC_RTMP_RTMPPROTOCOL_H_
|
#define SRC_RTMP_RTMPPROTOCOL_H_
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -26,7 +26,7 @@ RtmpPusher::RtmpPusher(const char *strApp,const char *strStream) {
|
|||||||
}, []() {});
|
}, []() {});
|
||||||
auto src = RtmpMediaSource::find(strApp,strStream);
|
auto src = RtmpMediaSource::find(strApp,strStream);
|
||||||
if (!src) {
|
if (!src) {
|
||||||
auto strErr = StrPrinter << "媒体源:" << strApp << "/" << strStream << "不存在" << endl;
|
auto strErr = StrPrinter << "media source:" << strApp << "/" << strStream << "not found!" << endl;
|
||||||
throw std::runtime_error(strErr);
|
throw std::runtime_error(strErr);
|
||||||
}
|
}
|
||||||
m_pMediaSrc = src;
|
m_pMediaSrc = src;
|
||||||
@ -132,7 +132,7 @@ inline void RtmpPusher::send_connect() {
|
|||||||
auto level = val["level"].as_string();
|
auto level = val["level"].as_string();
|
||||||
auto code = val["code"].as_string();
|
auto code = val["code"].as_string();
|
||||||
if(level != "status"){
|
if(level != "status"){
|
||||||
throw std::runtime_error(StrPrinter <<"connect 失败:" << level << " " << code << endl);
|
throw std::runtime_error(StrPrinter <<"connect 失败:" << level << " " << code << endl);
|
||||||
}
|
}
|
||||||
send_createStream();
|
send_createStream();
|
||||||
});
|
});
|
||||||
@ -157,7 +157,7 @@ inline void RtmpPusher::send_publish() {
|
|||||||
auto level = val["level"].as_string();
|
auto level = val["level"].as_string();
|
||||||
auto code = val["code"].as_string();
|
auto code = val["code"].as_string();
|
||||||
if(level != "status") {
|
if(level != "status") {
|
||||||
throw std::runtime_error(StrPrinter <<"publish 失败:" << level << " " << code << endl);
|
throw std::runtime_error(StrPrinter <<"publish 失败:" << level << " " << code << endl);
|
||||||
}
|
}
|
||||||
//start send media
|
//start send media
|
||||||
send_metaData();
|
send_metaData();
|
||||||
@ -167,10 +167,10 @@ inline void RtmpPusher::send_publish() {
|
|||||||
inline void RtmpPusher::send_metaData(){
|
inline void RtmpPusher::send_metaData(){
|
||||||
auto src = m_pMediaSrc.lock();
|
auto src = m_pMediaSrc.lock();
|
||||||
if (!src) {
|
if (!src) {
|
||||||
throw std::runtime_error("媒体源已被释放");
|
throw std::runtime_error("the media source was released");
|
||||||
}
|
}
|
||||||
if (!src->ready()) {
|
if (!src->ready()) {
|
||||||
throw std::runtime_error("媒体源尚未准备就绪");
|
throw std::runtime_error("the media source is not ready");
|
||||||
}
|
}
|
||||||
|
|
||||||
AMFEncoder enc;
|
AMFEncoder enc;
|
||||||
@ -219,7 +219,7 @@ void RtmpPusher::onCmd_onStatus(AMFDecoder &dec) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(val.type() != AMF_OBJECT){
|
if(val.type() != AMF_OBJECT){
|
||||||
throw std::runtime_error("onStatus: 未找到结果对象");
|
throw std::runtime_error("onStatus:the result object was not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
|
lock_guard<recursive_mutex> lck(m_mtxOnStatusCB);
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef SRC_RTMP_RTMPSESSION_H_
|
#ifndef SRC_RTMP_RTMPSESSION_H_
|
||||||
#define SRC_RTMP_RTMPSESSION_H_
|
#define SRC_RTMP_RTMPSESSION_H_
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include "amf.h"
|
#include "amf.h"
|
||||||
#include "Rtmp.h"
|
#include "Rtmp.h"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include "amf.h"
|
#include "amf.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "Util/logger.h"
|
#include "Util/logger.h"
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <arpa/inet.h>
|
#include "Util/util.h"
|
||||||
|
|
||||||
|
using namespace ZL::Util;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Used to do unaligned loads on archs that don't support them. GCC can mostly
|
* Used to do unaligned loads on archs that don't support them. GCC can mostly
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
* Author: xzl
|
* Author: xzl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "RtpBroadCaster.h"
|
#include "RtpBroadCaster.h"
|
||||||
#include "Util/util.h"
|
#include "Util/util.h"
|
||||||
@ -65,7 +64,7 @@ RtpBroadCaster::~RtpBroadCaster() {
|
|||||||
RtpBroadCaster::RtpBroadCaster(const string &strLocalIp,const string &strApp,const string &strStream) {
|
RtpBroadCaster::RtpBroadCaster(const string &strLocalIp,const string &strApp,const string &strStream) {
|
||||||
auto src = RtspMediaSource::find(strApp, strStream);
|
auto src = RtspMediaSource::find(strApp, strStream);
|
||||||
if(!src){
|
if(!src){
|
||||||
auto strErr = StrPrinter << "未找到媒体源:" << strApp << " " << strStream << endl;
|
auto strErr = StrPrinter << "未找到媒体源:" << strApp << " " << strStream << endl;
|
||||||
throw std::runtime_error(strErr);
|
throw std::runtime_error(strErr);
|
||||||
}
|
}
|
||||||
m_multiAddr = MultiCastAddressMaker::Instance().obtain();
|
m_multiAddr = MultiCastAddressMaker::Instance().obtain();
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
#ifndef SRC_RTSP_RTPBROADCASTER_H_
|
#ifndef SRC_RTSP_RTPBROADCASTER_H_
|
||||||
#define SRC_RTSP_RTPBROADCASTER_H_
|
#define SRC_RTSP_RTPBROADCASTER_H_
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
@ -35,7 +35,7 @@ RtpParser::RtpParser(const string& sdp) {
|
|||||||
RtspTrack tmp[2];
|
RtspTrack tmp[2];
|
||||||
int cnt = parserSDP(sdp, tmp);
|
int cnt = parserSDP(sdp, tmp);
|
||||||
if (0 == cnt) {
|
if (0 == cnt) {
|
||||||
throw std::runtime_error("解析SDP失败!");
|
throw std::runtime_error("parse sdp failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < cnt; i++) {
|
for (int i = 0; i < cnt; i++) {
|
||||||
@ -129,7 +129,7 @@ inline bool RtpParser::inputVideo(const RtpPacket& rtppack,
|
|||||||
|
|
||||||
if (rtppack.sequence != (uint16_t)(m_h264frame.sequence + 1)) {
|
if (rtppack.sequence != (uint16_t)(m_h264frame.sequence + 1)) {
|
||||||
m_h264frame.data.clear();
|
m_h264frame.data.clear();
|
||||||
WarnL << "丢包,帧废弃:" << rtppack.sequence << "," << m_h264frame.sequence;
|
WarnL << "丢包,帧废弃:" << rtppack.sequence << "," << m_h264frame.sequence;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_h264frame.sequence = rtppack.sequence;
|
m_h264frame.sequence = rtppack.sequence;
|
||||||
@ -204,7 +204,7 @@ inline void RtpParser::onGetVideoTrack(const RtspTrack& video) {
|
|||||||
|
|
||||||
string strTmp((char *)SPS_BUF, SPS_LEN);
|
string strTmp((char *)SPS_BUF, SPS_LEN);
|
||||||
if (!getAVCInfo(strTmp, m_iVideoWidth, m_iVideoHeight, m_fVideoFps)) {
|
if (!getAVCInfo(strTmp, m_iVideoWidth, m_iVideoHeight, m_fVideoFps)) {
|
||||||
throw std::runtime_error("解析SPS失败!");
|
throw std::runtime_error("parse sdp failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
#include "RtspPlayer.h"
|
#include "RtspPlayer.h"
|
||||||
#include "Device/base64.h"
|
#include "Device/base64.h"
|
||||||
#include "H264/SPSParser.h"
|
#include "H264/SPSParser.h"
|
||||||
#include "Util/mini.h"
|
#include "Util/mini.h"
|
||||||
|
#include "Util/util.h"
|
||||||
#include "Network/sockutil.h"
|
#include "Network/sockutil.h"
|
||||||
|
|
||||||
using namespace ZL::Util;
|
using namespace ZL::Util;
|
||||||
@ -127,7 +127,7 @@ void RtspPlayer::onConnect(const SockException &err){
|
|||||||
teardown();
|
teardown();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//发送DESCRIBE命令后处理函数:HandleResDESCRIBE
|
//发送DESCRIBE命令后处理函数:HandleResDESCRIBE
|
||||||
m_onHandshake = std::bind(&RtspPlayer::HandleResDESCRIBE,this, placeholders::_1);
|
m_onHandshake = std::bind(&RtspPlayer::HandleResDESCRIBE,this, placeholders::_1);
|
||||||
write("DESCRIBE %s RTSP/1.0\r\n"
|
write("DESCRIBE %s RTSP/1.0\r\n"
|
||||||
"CSeq: %d\r\n"
|
"CSeq: %d\r\n"
|
||||||
@ -345,9 +345,7 @@ void RtspPlayer::HandleResSETUP(const Parser& parser, unsigned int uiTrackIndex)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(((struct sockaddr_in *)addr)->sin_addr.s_addr != srcIP) {
|
if(((struct sockaddr_in *)addr)->sin_addr.s_addr != srcIP) {
|
||||||
char strAddr[32] = {0};
|
WarnL << "收到请他地址的UDP数据:" << inet_ntoa(((struct sockaddr_in *) addr)->sin_addr);
|
||||||
inet_ntop(addr->sa_family,(&((struct sockaddr_in *) addr)->sin_addr),strAddr,sizeof(strAddr));
|
|
||||||
WarnL << "收到请他地址的UDP数据:" << strAddr;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strongSelf->HandleOneRtp(i,(unsigned char *)buf->data(),buf->size());
|
strongSelf->HandleOneRtp(i,(unsigned char *)buf->data(),buf->size());
|
||||||
@ -404,7 +402,7 @@ void RtspPlayer::pause(bool bPause) {
|
|||||||
sendPause(bPause,getProgressTime());
|
sendPause(bPause,getProgressTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
//注意:当字符串为空时,也会返回一个空字符串
|
//注意:当字符串为空时,也会返回一个空字符串
|
||||||
static void split(const string& s, const char *delim, vector<string> &ret) {
|
static void split(const string& s, const char *delim, vector<string> &ret) {
|
||||||
size_t last = 0;
|
size_t last = 0;
|
||||||
size_t index = s.find_first_of(delim, last);
|
size_t index = s.find_first_of(delim, last);
|
||||||
@ -573,7 +571,7 @@ inline bool RtspPlayer::HandleOneRtp(int iTrackidx, unsigned char *pucData, unsi
|
|||||||
WarnL << "ssrc错误";
|
WarnL << "ssrc错误";
|
||||||
if (m_aui32SsrcErrorCnt[iTrackidx]++ > 10) {
|
if (m_aui32SsrcErrorCnt[iTrackidx]++ > 10) {
|
||||||
track.ssrc = rtppt.ssrc;
|
track.ssrc = rtppt.ssrc;
|
||||||
WarnL << "ssrc更换!";
|
WarnL << "ssrc更换!";
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef SRC_RTSPPLAYER_RTSPPLAYER_H_TXT_
|
#ifndef SRC_RTSPPLAYER_RTSPPLAYER_H_TXT_
|
||||||
#define SRC_RTSPPLAYER_RTSPPLAYER_H_TXT_
|
#define SRC_RTSPPLAYER_RTSPPLAYER_H_TXT_
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "Rtsp.h"
|
#include "Rtsp.h"
|
||||||
@ -37,7 +36,7 @@ class RtspPlayer: public PlayerBase,public TcpClient {
|
|||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<RtspPlayer> Ptr;
|
typedef std::shared_ptr<RtspPlayer> Ptr;
|
||||||
//设置rtp传输类型,可选项有0(tcp,默认)、1(udp)、2(组播)
|
//设置rtp传输类型,可选项有0(tcp,默认)、1(udp)、2(组播)
|
||||||
//设置方法:player[RtspPlayer::kRtpType] = 0/1/2;
|
//设置方法:player[RtspPlayer::kRtpType] = 0/1/2;
|
||||||
static const char kRtpType[];
|
static const char kRtpType[];
|
||||||
|
|
||||||
RtspPlayer();
|
RtspPlayer();
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
* Created on: 2016年8月12日
|
* Created on: 2016年8月12日
|
||||||
* Author: xzl
|
* Author: xzl
|
||||||
*/
|
*/
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
#include "UDPServer.h"
|
#include "UDPServer.h"
|
||||||
@ -106,7 +105,7 @@ void RtspSession::onError(const SockException& err) {
|
|||||||
lock_guard<recursive_mutex> lock(g_mtxPostter);
|
lock_guard<recursive_mutex> lock(g_mtxPostter);
|
||||||
//为了保证脱离TCPServer后还能正常运作,需要保持本对象的强引用
|
//为了保证脱离TCPServer后还能正常运作,需要保持本对象的强引用
|
||||||
g_mapPostter.emplace(this, dynamic_pointer_cast<RtspSession>(shared_from_this()));
|
g_mapPostter.emplace(this, dynamic_pointer_cast<RtspSession>(shared_from_this()));
|
||||||
TraceL << "quickTime已经不再发送请求";
|
TraceL << "quickTime will not send request any more!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef SESSION_RTSPSESSION_H_
|
#ifndef SESSION_RTSPSESSION_H_
|
||||||
#define SESSION_RTSPSESSION_H_
|
#define SESSION_RTSPSESSION_H_
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -5,13 +5,7 @@
|
|||||||
* Author: xzl
|
* Author: xzl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <net/if.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include "Common/config.h"
|
#include "Common/config.h"
|
||||||
#include "Rtmp/Rtmp.h"
|
#include "Rtmp/Rtmp.h"
|
||||||
#include "RtspToRtmpMediaSource.h"
|
#include "RtspToRtmpMediaSource.h"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
* Author: xzl
|
* Author: xzl
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include "UDPServer.h"
|
#include "UDPServer.h"
|
||||||
#include "Util/TimeTicker.h"
|
#include "Util/TimeTicker.h"
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
#ifndef SRC_SHELL_CMD_H_
|
#ifndef SRC_SHELL_CMD_H_
|
||||||
#define SRC_SHELL_CMD_H_
|
#define SRC_SHELL_CMD_H_
|
||||||
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -69,7 +68,7 @@ public:
|
|||||||
typedef function< void(OutStream *stream, const unordered_multimap<char, string> &)> OptionCompleted;
|
typedef function< void(OutStream *stream, const unordered_multimap<char, string> &)> OptionCompleted;
|
||||||
OptionParser(const OptionCompleted &_cb) {
|
OptionParser(const OptionCompleted &_cb) {
|
||||||
onCompleted = _cb;
|
onCompleted = _cb;
|
||||||
helper = Option('h', "help", Option::ArgNone, "获取此帮助", [this](OutStream *stream,const char *arg)->bool {
|
helper = Option('h', "help", Option::ArgNone, "print this help", [this](OutStream *stream,const char *arg)->bool {
|
||||||
_StrPrinter printer;
|
_StrPrinter printer;
|
||||||
for (auto &pr : options) {
|
for (auto &pr : options) {
|
||||||
printer<<"\t-"<<pr.first<<"\t--"<<pr.second.longOpt<<"\t"<<pr.second.des<<"\r\n";
|
printer<<"\t-"<<pr.first<<"\t--"<<pr.second.longOpt<<"\t"<<pr.second.des<<"\r\n";
|
||||||
|
@ -39,9 +39,11 @@ add_executable(${TEST_EXE_NAME} ${TEST_SRC})
|
|||||||
|
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
target_link_libraries(${TEST_EXE_NAME} ${CMAKE_PROJECT_NAME}_static ${LINK_LIB_LIST})
|
target_link_libraries(${TEST_EXE_NAME} ${CMAKE_PROJECT_NAME}_static ${LINK_LIB_LIST})
|
||||||
else(ANDROID)
|
elseif(WIN32)
|
||||||
|
target_link_libraries(${TEST_EXE_NAME} ${CMAKE_PROJECT_NAME}_shared ${LINK_LIB_LIST})
|
||||||
|
else()
|
||||||
target_link_libraries(${TEST_EXE_NAME} ${CMAKE_PROJECT_NAME}_shared ${LINK_LIB_LIST} pthread)
|
target_link_libraries(${TEST_EXE_NAME} ${CMAKE_PROJECT_NAME}_shared ${LINK_LIB_LIST} pthread)
|
||||||
endif(ANDROID)
|
endif()
|
||||||
|
|
||||||
endforeach(TEST_SRC ${TEST_SRC_LIST})
|
endforeach(TEST_SRC ${TEST_SRC_LIST})
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -29,8 +28,8 @@ int main(int argc, char *argv[]){
|
|||||||
signal(SIGINT, programExit);
|
signal(SIGINT, programExit);
|
||||||
|
|
||||||
if(argc != 5){
|
if(argc != 5){
|
||||||
FatalL << "\r\n测试方法:./test_benchmark player_count play_interval rtxp_url rtp_type\r\n"
|
FatalL << "\r\n测试方法:./test_benchmark player_count play_interval rtxp_url rtp_type\r\n"
|
||||||
<< "例如你想每隔50毫秒启动共计100个播放器(tcp方式播放rtsp://127.0.0.1/live/0 )可以输入以下命令:\r\n"
|
<< "例如你想每隔50毫秒启动共计100个播放器(tcp方式播放rtsp://127.0.0.1/live/0 )可以输入以下命令:\r\n"
|
||||||
<< "./test_benchmark 100 50 rtsp://127.0.0.1/live/0 0\r\n"
|
<< "./test_benchmark 100 50 rtsp://127.0.0.1/live/0 0\r\n"
|
||||||
<<endl;
|
<<endl;
|
||||||
Logger::Destory();
|
Logger::Destory();
|
||||||
@ -59,7 +58,7 @@ int main(int argc, char *argv[]){
|
|||||||
});
|
});
|
||||||
|
|
||||||
AsyncTaskThread::Instance().DoTaskDelay(0, 1000, [&](){
|
AsyncTaskThread::Instance().DoTaskDelay(0, 1000, [&](){
|
||||||
InfoL << "存活播放器个数:" << alivePlayerCnt.load();
|
InfoL << "存活播放器个数:" << alivePlayerCnt.load();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
EventPoller::Instance().runLoop();
|
EventPoller::Instance().runLoop();
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Http/HttpDownloader.h"
|
#include "Http/HttpDownloader.h"
|
||||||
#include "Http/HttpRequester.h"
|
#include "Http/HttpRequester.h"
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "Util/logger.h"
|
#include "Util/logger.h"
|
||||||
#include "Util/onceToken.h"
|
#include "Util/onceToken.h"
|
||||||
@ -44,14 +43,14 @@ int main(int argc,char *argv[]){
|
|||||||
const_cast<RtmpPusher::Ptr &>(pusher).reset(new RtmpPusher(app,stream));
|
const_cast<RtmpPusher::Ptr &>(pusher).reset(new RtmpPusher(app,stream));
|
||||||
|
|
||||||
pusher->setOnShutdown([](const SockException &ex){
|
pusher->setOnShutdown([](const SockException &ex){
|
||||||
WarnL << "已断开与服务器连接:" << ex.getErrCode() << " " << ex.what();
|
WarnL << "已断开与服务器连接:" << ex.getErrCode() << " " << ex.what();
|
||||||
});
|
});
|
||||||
|
|
||||||
pusher->setOnPublished([](const SockException &ex){
|
pusher->setOnPublished([](const SockException &ex){
|
||||||
if(ex){
|
if(ex){
|
||||||
WarnL << "发布失败:" << ex.getErrCode() << " "<< ex.what();
|
WarnL << "发布失败:" << ex.getErrCode() << " "<< ex.what();
|
||||||
}else{
|
}else{
|
||||||
InfoL << "发布成功,请用播放器打开:rtmp://jizan.iok.la/live/test";
|
InfoL << "发布成功,请用播放器打开:rtmp://jizan.iok.la/live/test";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "Common/config.h"
|
||||||
#include "Rtsp/UDPServer.h"
|
#include "Rtsp/UDPServer.h"
|
||||||
#include "Rtsp/RtspSession.h"
|
#include "Rtsp/RtspSession.h"
|
||||||
#include "Rtmp/RtmpSession.h"
|
#include "Rtmp/RtmpSession.h"
|
||||||
@ -18,22 +19,24 @@
|
|||||||
#include "Http/HttpsSession.h"
|
#include "Http/HttpsSession.h"
|
||||||
#endif//ENABLE_OPENSSL
|
#endif//ENABLE_OPENSSL
|
||||||
|
|
||||||
|
#include "Util/File.h"
|
||||||
#include "Util/logger.h"
|
#include "Util/logger.h"
|
||||||
#include "Util/onceToken.h"
|
#include "Util/onceToken.h"
|
||||||
#include "Util/File.h"
|
|
||||||
#include "Network/TcpServer.h"
|
#include "Network/TcpServer.h"
|
||||||
#include "Poller/EventPoller.h"
|
#include "Poller/EventPoller.h"
|
||||||
#include "Thread/WorkThreadPool.h"
|
#include "Thread/WorkThreadPool.h"
|
||||||
#include "Device/PlayerProxy.h"
|
#include "Device/PlayerProxy.h"
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
#include "Shell/ShellSession.h"
|
#include "Shell/ShellSession.h"
|
||||||
#include "Common/config.h"
|
using namespace ZL::Shell;
|
||||||
#include <map>
|
#endif // !defined(_WIN32)
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace ZL::Util;
|
using namespace ZL::Util;
|
||||||
using namespace ZL::Http;
|
using namespace ZL::Http;
|
||||||
using namespace ZL::Rtsp;
|
using namespace ZL::Rtsp;
|
||||||
using namespace ZL::Rtmp;
|
using namespace ZL::Rtmp;
|
||||||
using namespace ZL::Shell;
|
|
||||||
using namespace ZL::Thread;
|
using namespace ZL::Thread;
|
||||||
using namespace ZL::Network;
|
using namespace ZL::Network;
|
||||||
using namespace ZL::DEV;
|
using namespace ZL::DEV;
|
||||||
@ -42,10 +45,11 @@ void programExit(int arg) {
|
|||||||
EventPoller::Instance().shutdown();
|
EventPoller::Instance().shutdown();
|
||||||
}
|
}
|
||||||
int main(int argc,char *argv[]){
|
int main(int argc,char *argv[]){
|
||||||
setExePath(argv[0]);
|
// setExePath(argv[0]);
|
||||||
signal(SIGINT, programExit);
|
signal(SIGINT, programExit);
|
||||||
Logger::Instance().add(std::make_shared<ConsoleChannel>("stdout", LTrace));
|
Logger::Instance().add(std::make_shared<ConsoleChannel>("stdout", LTrace));
|
||||||
Config::loaIniConfig();
|
Config::loaIniConfig();
|
||||||
|
DebugL << exePath();
|
||||||
//support rtmp and rtsp url
|
//support rtmp and rtsp url
|
||||||
//just support H264+AAC
|
//just support H264+AAC
|
||||||
auto urlList = {"rtmp://live.hkstv.hk.lxdns.com/live/hks",
|
auto urlList = {"rtmp://live.hkstv.hk.lxdns.com/live/hks",
|
||||||
@ -54,11 +58,11 @@ int main(int argc,char *argv[]){
|
|||||||
int i=0;
|
int i=0;
|
||||||
for(auto url : urlList){
|
for(auto url : urlList){
|
||||||
//PlayerProxy构造函数前两个参数分别为应用名(app),流id(streamId)
|
//PlayerProxy构造函数前两个参数分别为应用名(app),流id(streamId)
|
||||||
//比如说应用为live,流id为0,那么直播地址为:
|
//比如说应用为live,流id为0,那么直播地址为:
|
||||||
//http://127.0.0.1/live/0/hls.m3u8
|
//http://127.0.0.1/live/0/hls.m3u8
|
||||||
//rtsp://127.0.0.1/live/0
|
//rtsp://127.0.0.1/live/0
|
||||||
//rtmp://127.0.0.1/live/0
|
//rtmp://127.0.0.1/live/0
|
||||||
//录像地址为:
|
//录像地址为:
|
||||||
//http://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
//http://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
||||||
//rtsp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
//rtsp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
||||||
//rtmp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
//rtmp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4
|
||||||
@ -81,17 +85,20 @@ int main(int argc,char *argv[]){
|
|||||||
TcpServer<RtspSession>::Ptr rtspSrv(new TcpServer<RtspSession>());
|
TcpServer<RtspSession>::Ptr rtspSrv(new TcpServer<RtspSession>());
|
||||||
TcpServer<RtmpSession>::Ptr rtmpSrv(new TcpServer<RtmpSession>());
|
TcpServer<RtmpSession>::Ptr rtmpSrv(new TcpServer<RtmpSession>());
|
||||||
TcpServer<HttpSession>::Ptr httpSrv(new TcpServer<HttpSession>());
|
TcpServer<HttpSession>::Ptr httpSrv(new TcpServer<HttpSession>());
|
||||||
TcpServer<ShellSession>::Ptr shellSrv(new TcpServer<ShellSession>());
|
|
||||||
|
|
||||||
rtspSrv->start(mINI::Instance()[Config::Rtsp::kPort]);
|
rtspSrv->start(mINI::Instance()[Config::Rtsp::kPort]);
|
||||||
rtmpSrv->start(mINI::Instance()[Config::Rtmp::kPort]);
|
rtmpSrv->start(mINI::Instance()[Config::Rtmp::kPort]);
|
||||||
httpSrv->start(mINI::Instance()[Config::Http::kPort]);
|
httpSrv->start(mINI::Instance()[Config::Http::kPort]);
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
//简单的telnet服务器,可用于服务器调试,但是不能使用23端口
|
//简单的telnet服务器,可用于服务器调试,但是不能使用23端口
|
||||||
//测试方法:telnet 127.0.0.1 8023
|
//测试方法:telnet 127.0.0.1 8023
|
||||||
//输入用户名和密码登录(user:test,pwd:123456),输入help命令查看帮助
|
//输入用户名和密码登录(user:test,pwd:123456),输入help命令查看帮助
|
||||||
|
TcpServer<ShellSession>::Ptr shellSrv(new TcpServer<ShellSession>());
|
||||||
ShellSession::addUser("test","123456");
|
ShellSession::addUser("test","123456");
|
||||||
shellSrv->start(8023);
|
shellSrv->start(8023);
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
|
||||||
#ifdef ENABLE_OPENSSL
|
#ifdef ENABLE_OPENSSL
|
||||||
TcpServer<HttpsSession>::Ptr httpsSrv(new TcpServer<HttpsSession>());
|
TcpServer<HttpsSession>::Ptr httpsSrv(new TcpServer<HttpsSession>());
|
||||||
@ -103,7 +110,10 @@ int main(int argc,char *argv[]){
|
|||||||
rtspSrv.reset();
|
rtspSrv.reset();
|
||||||
rtmpSrv.reset();
|
rtmpSrv.reset();
|
||||||
httpSrv.reset();
|
httpSrv.reset();
|
||||||
|
|
||||||
|
#if !defined(_WIN32)
|
||||||
shellSrv.reset();
|
shellSrv.reset();
|
||||||
|
#endif // !defined(_WIN32)
|
||||||
|
|
||||||
#ifdef ENABLE_OPENSSL
|
#ifdef ENABLE_OPENSSL
|
||||||
httpsSrv.reset();
|
httpsSrv.reset();
|
||||||
|
Loading…
Reference in New Issue
Block a user