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);}
 
原创粉丝点击