obs-studio 断线重连
来源:互联网 发布:阿里云服务器动态ip 编辑:程序博客网 时间:2024/05/22 04:49
obs发送逻辑在rtmp-stream.c文件中
static void *send_thread(void *data){struct rtmp_stream *stream = data;os_set_thread_name("rtmp-stream: send_thread");while (os_sem_wait(stream->send_sem) == 0) {struct encoder_packet packet;if (stopping(stream) && stream->stop_ts == 0) {break;}if (!get_next_packet(stream, &packet))continue;if (stopping(stream)) {if (can_shutdown_stream(stream, &packet)) {obs_free_encoder_packet(&packet);break;}}if (!stream->sent_headers) {if (!send_headers(stream)) {os_atomic_set_bool(&stream->disconnected, true);break;}}if (send_packet(stream, &packet, false, packet.track_idx) < 0) {os_atomic_set_bool(&stream->disconnected, true);break;}}if (disconnected(stream)) {info("Disconnected from %s", stream->path.array);} else {info("User stopped the stream");}RTMP_Close(&stream->rtmp);if (!stopping(stream)) {pthread_detach(stream->send_thread);obs_output_signal_stop(stream->output, OBS_OUTPUT_DISCONNECTED);} else {obs_output_end_data_capture(stream->output);}free_packets(stream);os_event_reset(stream->stop_event);os_atomic_set_bool(&stream->active, false);stream->sent_headers = false;return NULL;}当send_packet发送失败时,退出while循环,此时触发OBS_OUTPUT_DISCONNECTED
消息,状态栏提示Disconnected
然后 obs_output_signal_stop进行重连
void obs_output_signal_stop(obs_output_t *output, int code){if (!obs_output_valid(output, "obs_output_signal_stop"))return;output->stop_code = code;if (can_reconnect(output, code)) {if (delay_active(output))os_atomic_inc_long(&output->delay_restart_refs);obs_output_end_data_capture_internal(output, false);output_reconnect(output);} else {if (delay_active(output))os_atomic_set_bool(&output->delay_active, false);obs_output_end_data_capture(output);}}
output_reconnect 中创建重连线程reconnect_thread
static void output_reconnect(struct obs_output *output){int ret;if (!reconnecting(output)) {output->reconnect_retry_cur_sec = output->reconnect_retry_sec;output->reconnect_retries = 0;}if (output->reconnect_retries >= output->reconnect_retry_max) {output->stop_code = OBS_OUTPUT_DISCONNECTED;os_atomic_set_bool(&output->reconnecting, false);if (delay_active(output))os_atomic_set_bool(&output->delay_active, false);obs_output_end_data_capture(output);return;}if (!reconnecting(output)) {os_atomic_set_bool(&output->reconnecting, true);os_event_reset(output->reconnect_stop_event);}if (output->reconnect_retries) {output->reconnect_retry_cur_sec *= 2;if (output->reconnect_retry_cur_sec > MAX_RETRY_SEC)output->reconnect_retry_cur_sec = MAX_RETRY_SEC;}output->reconnect_retries++;output->stop_code = OBS_OUTPUT_DISCONNECTED;ret = pthread_create(&output->reconnect_thread, NULL,&reconnect_thread, output);if (ret < 0) {blog(LOG_WARNING, "Failed to create reconnect thread");os_atomic_set_bool(&output->reconnecting, false);} else {blog(LOG_INFO, "Output '%s': Reconnecting in %d seconds..",output->context.name,output->reconnect_retry_sec);signal_reconnect(output);}}
static void *reconnect_thread(void *param){struct obs_output *output = param;unsigned long ms = output->reconnect_retry_cur_sec * 1000;output->reconnect_thread_active = true;if (os_event_timedwait(output->reconnect_stop_event, ms) == ETIMEDOUT)obs_output_actual_start(output);if (os_event_try(output->reconnect_stop_event) == EAGAIN)pthread_detach(output->reconnect_thread);elseos_atomic_set_bool(&output->reconnecting, false);output->reconnect_thread_active = false;return NULL;}
bool obs_output_actual_start(obs_output_t *output){bool success = false;os_event_wait(output->stopping_event);output->stop_code = 0;if (output->context.data)success = output->info.start(output->context.data);if (success && output->video) {output->starting_frame_count =video_output_get_total_frames(output->video);output->starting_skipped_frame_count =video_output_get_skipped_frames(output->video);output->starting_drawn_count = obs->video.total_frames;output->starting_lagged_count = obs->video.lagged_frames;}if (os_atomic_load_long(&output->delay_restart_refs))os_atomic_dec_long(&output->delay_restart_refs);return success;}
success = output->info.start(output->context.data); 此时函数指针start 为rtmp_stream_start
static bool rtmp_stream_start(void *data){struct rtmp_stream *stream = data;if (!obs_output_can_begin_data_capture(stream->output, 0))return false;if (!obs_output_initialize_encoders(stream->output, 0))return false;os_atomic_set_bool(&stream->connecting, true);return pthread_create(&stream->connect_thread, NULL, connect_thread,stream) == 0;}
创建连接线程connect_thread
static void *connect_thread(void *data){struct rtmp_stream *stream = data;int ret;os_set_thread_name("rtmp-stream: connect_thread");if (!init_connect(stream)) {obs_output_signal_stop(stream->output, OBS_OUTPUT_BAD_PATH);return NULL;}ret = try_connect(stream);if (ret != OBS_OUTPUT_SUCCESS) {obs_output_signal_stop(stream->output, ret);info("Connection to %s failed: %d", stream->path.array, ret);}if (!stopping(stream))pthread_detach(stream->connect_thread);os_atomic_set_bool(&stream->connecting, false);return NULL;}
连接线程中调用try_connect,再调用RTMP_Connect进行重新连接
for (size_t idx = 1;; idx++) {obs_encoder_t *encoder = obs_output_get_audio_encoder(stream->output, idx);const char *encoder_name;if (!encoder)break;encoder_name = obs_encoder_get_name(encoder);RTMP_AddStream(&stream->rtmp, encoder_name);}stream->rtmp.m_outChunkSize = 4096;stream->rtmp.m_bSendChunkSizeInfo = true;stream->rtmp.m_bUseNagle = true;#ifdef _WIN32win32_log_interface_type(stream);#endifif (!RTMP_Connect(&stream->rtmp, NULL))return OBS_OUTPUT_CONNECT_FAILED;if (!RTMP_ConnectStream(&stream->rtmp, 0))return OBS_OUTPUT_INVALID_STREAM;info("Connection to %s successful", stream->path.array);return init_send(stream);}
阅读全文
0 0
- obs-studio 断线重连
- Mina 断线重连
- activemq断线重连
- Mina 断线重连
- Mina 断线重连
- websocket 断线重连
- Netty断线重连
- Mina 断线重连
- MINA断线重连
- 数据库断线重连
- 断线重连总结
- Mina 断线重连
- 断线重连机制
- Mina 断线重连
- Mina 断线重连机制
- Mina断线重连问题
- C# + Socket断线重连
- httpClient断线重连机制
- Cookie 保存用户的信息
- Linux 查看登录信息(w/who/last/lastlog)
- 一个基于Rxjava2+MVP的自定义文本阅读器
- Oracle 数据库一些常见的优化
- 增长黑客-之“bug营销”范例及设想思考!
- obs-studio 断线重连
- linux下PXE和KickStart实现Linux下的无人值守安装
- eclipse下新建jsp页面失败,提示错误。
- 小米5调试出现DELETE_FAILED_INTERNAL_ERROR错误
- CSU 1642 Problem B
- CodeForces 813A|813B|813C|813D
- Linux 下配置静态ip地址
- Java 类加载机制详解
- [Leetcode] 200. Number of Islands 解题报告