@@ -52,7 +52,7 @@ def __init__(self, parent=None):
5252 super ().__init__ (parent )
5353 self .setWindowTitle ("Connect to IP Camera" )
5454 self .setModal (True )
55- self .resize (400 , 250 )
55+ self .resize (420 , 320 )
5656
5757 self .setup_ui ()
5858
@@ -122,7 +122,21 @@ def setup_quick_connect_form(self, layout):
122122 self .path_edit .setText ("/video_feed" )
123123 self .path_edit .textChanged .connect (self .update_url_preview )
124124 form_layout .addRow ("Stream Path:" , self .path_edit )
125-
125+
126+ # RTSP credentials (username / password)
127+ self .rtsp_username_label = QLabel ("Username (RTSP):" )
128+ self .rtsp_username_edit = QLineEdit ()
129+ self .rtsp_username_edit .setPlaceholderText ("Leave blank if not required" )
130+ self .rtsp_username_edit .textChanged .connect (self .update_url_preview )
131+ form_layout .addRow (self .rtsp_username_label , self .rtsp_username_edit )
132+
133+ self .rtsp_password_label = QLabel ("Password (RTSP):" )
134+ self .rtsp_password_edit = QLineEdit ()
135+ self .rtsp_password_edit .setPlaceholderText ("Leave blank if not required" )
136+ self .rtsp_password_edit .setEchoMode (QLineEdit .Password )
137+ self .rtsp_password_edit .textChanged .connect (self .update_url_preview )
138+ form_layout .addRow (self .rtsp_password_label , self .rtsp_password_edit )
139+
126140 # URL preview
127141 self .url_preview = QLabel ()
128142 self .url_preview .setStyleSheet ("""
@@ -138,21 +152,27 @@ def setup_quick_connect_form(self, layout):
138152
139153 layout .addLayout (form_layout )
140154
141- # Update preview initially
155+ # Update preview initially (also sets visibility of credential fields)
142156 self .on_protocol_changed ()
143157 self .update_url_preview ()
144158
145159 def on_protocol_changed (self ):
146160 """Handle protocol change"""
147161 is_rtsp = "RTSP" in self .stream_protocol_combo .currentText ()
148-
162+
149163 if is_rtsp :
150164 self .port_spinbox .setValue (554 ) # Default RTSP port
151165 self .path_edit .setText ("/stream" )
152166 else :
153167 self .port_spinbox .setValue (5000 ) # Default HTTP port
154168 self .path_edit .setText ("/video_feed" )
155-
169+
170+ # Show/hide credential fields based on protocol
171+ self .rtsp_username_label .setVisible (is_rtsp )
172+ self .rtsp_username_edit .setVisible (is_rtsp )
173+ self .rtsp_password_label .setVisible (is_rtsp )
174+ self .rtsp_password_edit .setVisible (is_rtsp )
175+
156176 self .update_url_preview ()
157177
158178
@@ -161,17 +181,26 @@ def update_url_preview(self):
161181 ip = self .ip_edit .text () or "0.0.0.0"
162182 port = self .port_spinbox .value ()
163183 path = self .path_edit .text () or "/"
164-
184+
165185 if not path .startswith ('/' ):
166186 path = '/' + path
167-
187+
168188 is_rtsp = "RTSP" in self .stream_protocol_combo .currentText ()
169-
189+
170190 if is_rtsp :
171- url = f"rtsp://{ ip } :{ port } { path } "
191+ username = self .rtsp_username_edit .text ().strip ()
192+ password = self .rtsp_password_edit .text ()
193+ if username :
194+ # Embed credentials in the URL: rtsp://user:pass@host:port/path
195+ from urllib .parse import quote
196+ encoded_user = quote (username , safe = '' )
197+ encoded_pass = quote (password , safe = '' )
198+ url = f"rtsp://{ encoded_user } :{ encoded_pass } @{ ip } :{ port } { path } "
199+ else :
200+ url = f"rtsp://{ ip } :{ port } { path } "
172201 else :
173202 url = f"http://{ ip } :{ port } { path } "
174-
203+
175204 self .url_preview .setText (url )
176205
177206 def get_current_url (self ):
0 commit comments