mirror of
https://gitee.com/xia-chu/ZLMediaKit.git
synced 2026-05-24 02:27:49 +08:00
Compare commits
5 Commits
97d2a1fb08
...
588d9de2b2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
588d9de2b2 | ||
|
|
697992201f | ||
|
|
7828c03d16 | ||
|
|
797d8bf00f | ||
|
|
e0eec8e4f6 |
9
.github/workflows/macos.yml
vendored
9
.github/workflows/macos.yml
vendored
@ -18,10 +18,15 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
vcpkgDirectory: '${{github.workspace}}/vcpkg'
|
vcpkgDirectory: '${{github.workspace}}/vcpkg'
|
||||||
vcpkgTriplet: arm64-osx
|
vcpkgTriplet: arm64-osx
|
||||||
# 2024.06.01
|
# 2025.07.11
|
||||||
vcpkgGitCommitId: '47364fbc300756f64f7876b549d9422d5f3ec0d3'
|
vcpkgGitCommitId: 'efcfaaf60d7ec57a159fc3110403d939bfb69729'
|
||||||
vcpkgArguments: 'openssl libsrtp[openssl] usrsctp'
|
vcpkgArguments: 'openssl libsrtp[openssl] usrsctp'
|
||||||
|
|
||||||
|
- name: 安装指定 CMake
|
||||||
|
uses: jwlawson/actions-setup-cmake@v2
|
||||||
|
with:
|
||||||
|
cmake-version: '3.30.5'
|
||||||
|
|
||||||
- name: 编译
|
- name: 编译
|
||||||
uses: lukka/run-cmake@v3
|
uses: lukka/run-cmake@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 0658496d5fc7d238f41e10ea4d0a10113a8eed84
|
Subproject commit 447e3b85f312f0558027d1f41c4334516c6ef643
|
||||||
@ -60,6 +60,8 @@ option(ENABLE_WEPOLL "Enable wepoll" ON)
|
|||||||
option(ENABLE_VIDEOSTACK "Enable video stack" OFF)
|
option(ENABLE_VIDEOSTACK "Enable video stack" OFF)
|
||||||
option(DISABLE_REPORT "Disable report to report.zlmediakit.com" OFF)
|
option(DISABLE_REPORT "Disable report to report.zlmediakit.com" OFF)
|
||||||
option(USE_SOLUTION_FOLDERS "Enable solution dir supported" ON)
|
option(USE_SOLUTION_FOLDERS "Enable solution dir supported" ON)
|
||||||
|
option(ENABLE_OBJCOPY "Enable use objcopy to generate debug info file" ON)
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# 设置socket默认缓冲区大小为256k.如果设置为0则不设置socket的默认缓冲区大小,使用系统内核默认值(设置为0仅对linux有效)
|
# 设置socket默认缓冲区大小为256k.如果设置为0则不设置socket的默认缓冲区大小,使用系统内核默认值(设置为0仅对linux有效)
|
||||||
# Set the default buffer size of the socket to 256k. If set to 0, the default buffer size of the socket will not be set,
|
# Set the default buffer size of the socket to 256k. If set to 0, the default buffer size of the socket will not be set,
|
||||||
@ -199,10 +201,8 @@ if(UNIX)
|
|||||||
set(COMPILE_OPTIONS_DEFAULT ${COMPILE_OPTIONS_DEFAULT} "-g3")
|
set(COMPILE_OPTIONS_DEFAULT ${COMPILE_OPTIONS_DEFAULT} "-g3")
|
||||||
else()
|
else()
|
||||||
find_program(OBJCOPY_FOUND objcopy)
|
find_program(OBJCOPY_FOUND objcopy)
|
||||||
if (OBJCOPY_FOUND)
|
if (OBJCOPY_FOUND AND ENABLE_OBJCOPY)
|
||||||
set(COMPILE_OPTIONS_DEFAULT ${COMPILE_OPTIONS_DEFAULT} "-g3")
|
set(COMPILE_OPTIONS_DEFAULT ${COMPILE_OPTIONS_DEFAULT} "-g3")
|
||||||
else()
|
|
||||||
set(COMPILE_OPTIONS_DEFAULT ${COMPILE_OPTIONS_DEFAULT} "-g0")
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
|
|||||||
@ -84,7 +84,8 @@ if(MSVC)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
#relase 类型时额外输出debug调试信息
|
#relase 类型时额外输出debug调试信息
|
||||||
if(UNIX)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
|
||||||
|
if(UNIX AND ENABLE_OBJCOPY)
|
||||||
if("${CMAKE_BUILD_TYPE_LOWER}" STREQUAL "release")
|
if("${CMAKE_BUILD_TYPE_LOWER}" STREQUAL "release")
|
||||||
find_program(OBJCOPY_FOUND objcopy)
|
find_program(OBJCOPY_FOUND objcopy)
|
||||||
if (OBJCOPY_FOUND)
|
if (OBJCOPY_FOUND)
|
||||||
|
|||||||
@ -391,7 +391,7 @@ Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) {
|
|||||||
// If there is no sps/pps in the sdp, then it may be possible to recover the sps/pps in the subsequent rtp
|
// If there is no sps/pps in the sdp, then it may be possible to recover the sps/pps in the subsequent rtp
|
||||||
return std::make_shared<H264Track>();
|
return std::make_shared<H264Track>();
|
||||||
}
|
}
|
||||||
return std::make_shared<H264Track>(sps, pps, 0, 0);
|
return std::make_shared<H264Track>(sps, pps, prefixSize(sps.data(), sps.size()), prefixSize(pps.data(), pps.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
|
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
|
||||||
|
|||||||
@ -392,7 +392,10 @@ Track::Ptr getTrackBySdp(const SdpTrack::Ptr &track) {
|
|||||||
// If there is no sps/pps in the sdp, then it may be possible to recover sps/pps from the subsequent rtp
|
// If there is no sps/pps in the sdp, then it may be possible to recover sps/pps from the subsequent rtp
|
||||||
return std::make_shared<H265Track>();
|
return std::make_shared<H265Track>();
|
||||||
}
|
}
|
||||||
return std::make_shared<H265Track>(vps, sps, pps, 0, 0, 0);
|
return std::make_shared<H265Track>(vps, sps, pps,
|
||||||
|
prefixSize(vps.data(), vps.size()),
|
||||||
|
prefixSize(sps.data(), sps.size()),
|
||||||
|
prefixSize(pps.data(), pps.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
|
RtpCodec::Ptr getRtpEncoderByCodecId(uint8_t pt) {
|
||||||
|
|||||||
@ -18,7 +18,10 @@ using namespace toolkit;
|
|||||||
INSTANCE_IMP(SDLAudioDevice);
|
INSTANCE_IMP(SDLAudioDevice);
|
||||||
|
|
||||||
SDLAudioDevice::~SDLAudioDevice() {
|
SDLAudioDevice::~SDLAudioDevice() {
|
||||||
SDL_CloseAudio();
|
if (_device) {
|
||||||
|
SDL_CloseAudioDevice(_device);
|
||||||
|
_device = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SDLAudioDevice::SDLAudioDevice() {
|
SDLAudioDevice::SDLAudioDevice() {
|
||||||
@ -33,9 +36,13 @@ SDLAudioDevice::SDLAudioDevice() {
|
|||||||
SDLAudioDevice *_this = (SDLAudioDevice *) userdata;
|
SDLAudioDevice *_this = (SDLAudioDevice *) userdata;
|
||||||
_this->onReqPCM((char *) stream, len);
|
_this->onReqPCM((char *) stream, len);
|
||||||
};
|
};
|
||||||
if (SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &_audio_config, SDL_AUDIO_ALLOW_ANY_CHANGE) < 0) {
|
|
||||||
throw std::runtime_error("SDL_OpenAudioDevice failed");
|
_device = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &_audio_config, 0);
|
||||||
}
|
if (_device <= 0)
|
||||||
|
_device = SDL_OpenAudioDevice(NULL, 0, &wanted_spec, &_audio_config, SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||||
|
if (_device <= 0) {
|
||||||
|
throw std::runtime_error("SDL_OpenAudioDevice failed");
|
||||||
|
}
|
||||||
|
|
||||||
InfoL << "actual audioSpec, " << "freq:" << _audio_config.freq
|
InfoL << "actual audioSpec, " << "freq:" << _audio_config.freq
|
||||||
<< ", format:" << hex << _audio_config.format << dec
|
<< ", format:" << hex << _audio_config.format << dec
|
||||||
@ -51,7 +58,7 @@ SDLAudioDevice::SDLAudioDevice() {
|
|||||||
void SDLAudioDevice::addChannel(AudioSRC *chn) {
|
void SDLAudioDevice::addChannel(AudioSRC *chn) {
|
||||||
lock_guard<recursive_mutex> lck(_channel_mtx);
|
lock_guard<recursive_mutex> lck(_channel_mtx);
|
||||||
if (_channels.empty()) {
|
if (_channels.empty()) {
|
||||||
SDL_PauseAudio(0);
|
SDL_PauseAudioDevice(_device, false);
|
||||||
}
|
}
|
||||||
chn->setOutputAudioConfig(_audio_config);
|
chn->setOutputAudioConfig(_audio_config);
|
||||||
_channels.emplace(chn);
|
_channels.emplace(chn);
|
||||||
@ -61,7 +68,7 @@ void SDLAudioDevice::delChannel(AudioSRC *chn) {
|
|||||||
lock_guard<recursive_mutex> lck(_channel_mtx);
|
lock_guard<recursive_mutex> lck(_channel_mtx);
|
||||||
_channels.erase(chn);
|
_channels.erase(chn);
|
||||||
if (_channels.empty()) {
|
if (_channels.empty()) {
|
||||||
SDL_PauseAudio(true);
|
SDL_PauseAudioDevice(_device, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,7 @@ private:
|
|||||||
void onReqPCM(char *stream, int len);
|
void onReqPCM(char *stream, int len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SDL_AudioDeviceID _device;
|
||||||
std::shared_ptr<char> _play_buf;
|
std::shared_ptr<char> _play_buf;
|
||||||
SDL_AudioSpec _audio_config;
|
SDL_AudioSpec _audio_config;
|
||||||
std::recursive_mutex _channel_mtx;
|
std::recursive_mutex _channel_mtx;
|
||||||
|
|||||||
@ -41,6 +41,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstanc, LPSTR lpCmdLine,
|
|||||||
freopen_s(&stream, "CON", "r", stdin);//重定向输入流
|
freopen_s(&stream, "CON", "r", stdin);//重定向输入流
|
||||||
freopen_s(&stream, "CON", "w", stdout);//重定向输入流
|
freopen_s(&stream, "CON", "w", stdout);//重定向输入流
|
||||||
|
|
||||||
|
// 清除流缓冲区, 在win11上还是无法输出文字,需要在加入如下代码
|
||||||
|
std::cin.clear();
|
||||||
|
std::cout.clear();
|
||||||
|
|
||||||
//3. 如果我们需要用到控制台窗口句柄,可以调用FindWindow取得:
|
//3. 如果我们需要用到控制台窗口句柄,可以调用FindWindow取得:
|
||||||
HWND _consoleHwnd;
|
HWND _consoleHwnd;
|
||||||
SetConsoleTitleA("test_player");//设置窗口名
|
SetConsoleTitleA("test_player");//设置窗口名
|
||||||
@ -56,8 +60,8 @@ int main(int argc, char *argv[]) {
|
|||||||
Logger::Instance().add(std::make_shared<ConsoleChannel>());
|
Logger::Instance().add(std::make_shared<ConsoleChannel>());
|
||||||
Logger::Instance().setWriter(std::make_shared<AsyncLogWriter>());
|
Logger::Instance().setWriter(std::make_shared<AsyncLogWriter>());
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 2) {
|
||||||
ErrorL << "\r\n测试方法:./test_player rtxp_url rtp_type\r\n"
|
ErrorL << "\r\n测试方法:./test_player rtxp_url [rtp_type] [play_track]\r\n"
|
||||||
<< "例如:./test_player rtsp://admin:123456@127.0.0.1/live/0 0\r\n";
|
<< "例如:./test_player rtsp://admin:123456@127.0.0.1/live/0 0\r\n";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -96,18 +100,15 @@ int main(int argc, char *argv[]) {
|
|||||||
FFmpegSwr::Ptr swr;
|
FFmpegSwr::Ptr swr;
|
||||||
|
|
||||||
decoder->setOnDecode([audio_player, swr](const FFmpegFrame::Ptr &frame) mutable {
|
decoder->setOnDecode([audio_player, swr](const FFmpegFrame::Ptr &frame) mutable {
|
||||||
int chs = 0;
|
|
||||||
if (!swr) {
|
if (!swr) {
|
||||||
# if LIBAVCODEC_VERSION_INT >= FF_CODEC_VER_7_1
|
# if LIBAVCODEC_VERSION_INT >= FF_CODEC_VER_7_1
|
||||||
swr = std::make_shared<FFmpegSwr>(AV_SAMPLE_FMT_S16, &(frame->get()->ch_layout), frame->get()->sample_rate);
|
swr = std::make_shared<FFmpegSwr>(AV_SAMPLE_FMT_S16, &(frame->get()->ch_layout), frame->get()->sample_rate);
|
||||||
chs = (&frame->get()->ch_layout)->nb_channels;
|
|
||||||
#else
|
#else
|
||||||
swr = std::make_shared<FFmpegSwr>(AV_SAMPLE_FMT_S16, frame->get()->channels, frame->get()->channel_layout, frame->get()->sample_rate);
|
swr = std::make_shared<FFmpegSwr>(AV_SAMPLE_FMT_S16, frame->get()->channels, frame->get()->channel_layout, frame->get()->sample_rate);
|
||||||
chs = frame->get()->channels;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
auto pcm = swr->inputFrame(frame);
|
auto pcm = swr->inputFrame(frame);
|
||||||
auto len = pcm->get()->nb_samples * chs * av_get_bytes_per_sample((enum AVSampleFormat)pcm->get()->format);
|
auto len = pcm->get()->nb_samples * pcm->getChannels() * av_get_bytes_per_sample((enum AVSampleFormat)pcm->get()->format);
|
||||||
audio_player->playPCM((const char *)(pcm->get()->data[0]), MIN(len, frame->get()->linesize[0]));
|
audio_player->playPCM((const char *)(pcm->get()->data[0]), MIN(len, frame->get()->linesize[0]));
|
||||||
});
|
});
|
||||||
audioTrack->addDelegate([decoder](const Frame::Ptr &frame) { return decoder->inputFrame(frame, false, true); });
|
audioTrack->addDelegate([decoder](const Frame::Ptr &frame) { return decoder->inputFrame(frame, false, true); });
|
||||||
@ -115,10 +116,11 @@ int main(int argc, char *argv[]) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
player->setOnShutdown([](const SockException &ex) { WarnL << "play shutdown: " << ex.what(); });
|
player->setOnShutdown([](const SockException &ex) { WarnL << "play shutdown: " << ex.what(); });
|
||||||
|
|
||||||
(*player)[Client::kRtpType] = atoi(argv[2]);
|
|
||||||
// 不等待track ready再回调播放成功事件,这样可以加快秒开速度
|
// 不等待track ready再回调播放成功事件,这样可以加快秒开速度
|
||||||
(*player)[Client::kWaitTrackReady] = false;
|
(*player)[Client::kWaitTrackReady] = false;
|
||||||
|
if (argc > 2) {
|
||||||
|
(*player)[Client::kRtpType] = atoi(argv[2]);
|
||||||
|
}
|
||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
(*player)[Client::kPlayTrack] = atoi(argv[3]);
|
(*player)[Client::kPlayTrack] = atoi(argv[3]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,7 +69,7 @@ install(TARGETS MediaServer DESTINATION ${INSTALL_PATH_RUNTIME})
|
|||||||
|
|
||||||
#relase 类型时额外输出debug调试信息
|
#relase 类型时额外输出debug调试信息
|
||||||
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
|
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
|
||||||
if(UNIX)
|
if(UNIX AND ENABLE_OBJCOPY)
|
||||||
if("${CMAKE_BUILD_TYPE_LOWER}" STREQUAL "release")
|
if("${CMAKE_BUILD_TYPE_LOWER}" STREQUAL "release")
|
||||||
find_program(OBJCOPY_FOUND objcopy)
|
find_program(OBJCOPY_FOUND objcopy)
|
||||||
if (OBJCOPY_FOUND)
|
if (OBJCOPY_FOUND)
|
||||||
|
|||||||
@ -247,6 +247,15 @@ void FFmpegFrame::fillPicture(AVPixelFormat target_format, int target_width, int
|
|||||||
av_image_fill_arrays(_frame->data, _frame->linesize, (uint8_t *) _data, target_format, target_width, target_height, 32);
|
av_image_fill_arrays(_frame->data, _frame->linesize, (uint8_t *) _data, target_format, target_width, target_height, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FFmpegFrame::getChannels() const {
|
||||||
|
if (!_frame) return 0;
|
||||||
|
#if LIBAVCODEC_VERSION_INT >= FF_CODEC_VER_7_1
|
||||||
|
return _frame->ch_layout.nb_channels;
|
||||||
|
#else
|
||||||
|
return _frame->channels;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<bool decoder = true>
|
template<bool decoder = true>
|
||||||
|
|||||||
@ -44,6 +44,7 @@ public:
|
|||||||
|
|
||||||
AVFrame *get() const;
|
AVFrame *get() const;
|
||||||
void fillPicture(AVPixelFormat target_format, int target_width, int target_height);
|
void fillPicture(AVPixelFormat target_format, int target_width, int target_height);
|
||||||
|
int getChannels() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char *_data = nullptr;
|
char *_data = nullptr;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user