mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-07 12:18:12 +08:00
Add async init SDL audio device for player to prevent blocking main poller(#4773)
This commit is contained in:
@@ -93,37 +93,52 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
if (audioTrack) {
|
||||
auto decoder = std::make_shared<FFmpegDecoder>(audioTrack);
|
||||
auto audio_player = std::make_shared<AudioPlayer>();
|
||||
// FFmpeg解码时已经统一转换为16位整型pcm
|
||||
audio_player->setup(audioTrack->getAudioSampleRate(), audioTrack->getAudioChannel(), AUDIO_S16);
|
||||
FFmpegSwr::Ptr swr;
|
||||
try {
|
||||
auto decoder = std::make_shared<FFmpegDecoder>(audioTrack);
|
||||
auto audio_player = std::make_shared<AudioPlayer>();
|
||||
// FFmpeg解码时已经统一转换为16位整型pcm
|
||||
audio_player->setup(audioTrack->getAudioSampleRate(), audioTrack->getAudioChannel(), AUDIO_S16);
|
||||
FFmpegSwr::Ptr swr;
|
||||
|
||||
decoder->setOnDecode([audio_player, swr](const FFmpegFrame::Ptr &frame) mutable {
|
||||
if (!swr) {
|
||||
# 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);
|
||||
decoder->setOnDecode([audio_player, swr](const FFmpegFrame::Ptr &frame) mutable {
|
||||
if (!swr) {
|
||||
#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);
|
||||
#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);
|
||||
#endif
|
||||
}
|
||||
auto pcm = swr->inputFrame(frame);
|
||||
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]));
|
||||
});
|
||||
audioTrack->addDelegate([decoder](const Frame::Ptr &frame) { return decoder->inputFrame(frame, false, true); });
|
||||
}
|
||||
auto pcm = swr->inputFrame(frame);
|
||||
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]));
|
||||
});
|
||||
audioTrack->addDelegate([decoder](const Frame::Ptr &frame) { return decoder->inputFrame(frame, false, true); });
|
||||
} catch (const std::exception &ex) {
|
||||
WarnL << "audio output disabled: " << ex.what();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player->setOnShutdown([](const SockException &ex) { WarnL << "play shutdown: " << ex.what(); });
|
||||
// 不等待track ready再回调播放成功事件,这样可以加快秒开速度
|
||||
(*player)[Client::kWaitTrackReady] = false;
|
||||
(*player)[Client::kPlayTrack] = 0;
|
||||
if (argc > 2) {
|
||||
(*player)[Client::kRtpType] = atoi(argv[2]);
|
||||
}
|
||||
if (argc > 3) {
|
||||
(*player)[Client::kPlayTrack] = atoi(argv[3]);
|
||||
}
|
||||
|
||||
// 提前触发 SDL 音频设备异步初始化(后台线程)
|
||||
// 某些平台在无音频设备时 SDL_OpenAudioDevice 会长时间阻塞
|
||||
// (如 Windows WASAPI 约 16 秒),提前启动确保 play 回调时已就绪
|
||||
try {
|
||||
SDLAudioDevice::Instance();
|
||||
} catch (const std::exception &ex) {
|
||||
WarnL << "SDL audio device pre-init failed: " << ex.what();
|
||||
}
|
||||
|
||||
player->play(argv[1]);
|
||||
SDLDisplayerHelper::Instance().runLoop();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user