{"id":327565,"date":"2022-01-10T08:56:41","date_gmt":"2022-01-10T08:56:41","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=327565"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=327565","title":{"rendered":"<span>\u0423\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a IP \u043a\u0430\u043c\u0435\u0440\u0430\u043c, \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430 Python<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\" class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/bc1\/2f3\/435\/bc12f3435a23b0921fa46fc4c724c37d.jpg\" alt=\"\u0420\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043a\u0430\u043c\u0435\u0440\" title=\"\u0420\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043a\u0430\u043c\u0435\u0440\" width=\"1480\" height=\"834\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bc1\/2f3\/435\/bc12f3435a23b0921fa46fc4c724c37d.jpg\" data-blurred=\"true\"\/><figcaption>\u0420\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043a\u0430\u043c\u0435\u0440<\/figcaption><\/figure>\n<p>\u0423\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u0432 2021-\u043c \u0432\u0441\u0435 \u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0438\u0437\u0431\u0438\u0442\u0443\u044e \u0442\u0435\u043c\u0443. \u041e\u0434\u043d\u0430\u043a\u043e, \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0439\u0442\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043b\u0438\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043e\u0442 \u043f\u043e\u043a\u0443\u043f\u043a\u0438 \u043e\u0445\u0440\u0430\u043d\u043d\u044b\u0445 \u043a\u0430\u043c\u0435\u0440 \u0434\u043e \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043c\u043e\u0438, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u0445\u0438\u0442\u0440\u044b\u0435, \u0437\u0430\u0434\u0430\u0447\u0438. \u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043c\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u0434\u0430\u0447\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u043a \u043d\u0435\u043c\u0443. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043a\u043e\u043c\u0443-\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442.<\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u0438:  \u043c\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c IP \u043a\u0430\u043c\u0435\u0440\u044b Rubetek RV-3414 \u0438 Hikvision DS-2CD2023. \u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043d\u0438\u043c \u0441 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u0438 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0436\u0435\u0441\u0442\u043a\u0438\u0439 \u0434\u0438\u0441\u043a. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0438\u0434\u0435\u043e\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 \u0438 \u043c\u0435\u0434\u0438\u0430\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e Intel NUC \u043c\u043b\u0430\u0434\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437-\u0437\u0430 \u043d\u0438\u0437\u043a\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u044d\u043d\u0435\u0440\u0433\u0438\u0438, \u0447\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041e\u0431\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 RTSP \u2013 Real Time Streaming Protocol. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u043e \u0432\u0441\u0435\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443.<\/p>\n<h2>\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u0439<\/h2>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u0430\u043c\u0435\u0440, &#8212; \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b \u0438\u0445 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043f\u0440\u0438\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c. \u0418 \u0442\u0443\u0442 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043f\u043e\u043b\u043d\u043e\u0435 \u0441\u044e\u0440\u043f\u0440\u0438\u0437\u043e\u0432 \u0438 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432.<\/p>\n<p>Rubetek \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b \u043f\u0440\u043e\u043f\u0440\u0438\u0435\u0442\u0430\u0440\u043d\u044b\u0439 \u0441\u043e\u0444\u0442 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0430 (\u0438 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0433\u043b\u044e\u0447\u0438\u0442). \u041d\u043e \u043f\u0440\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043a \u043a\u0430\u043c\u0435\u0440\u0435 \u044d\u0442\u043e \u0447\u0443\u0434\u043e \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e (\u0443 \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u043d\u0430 \u0410\u043d\u0434\u0440\u043e\u0438\u0434\u0435). \u041b\u0430\u0434\u043d\u043e, \u043d\u0435 \u0431\u043e\u043b\u044c\u043d\u043e \u0442\u043e \u0438 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c, \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043e\u043e\u043f\u0430\u0440\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u0443\u044e \u043a\u0430\u043c\u0435\u0440\u0443 \u044f \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0441\u044f. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e \u043d\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d VLC \u2014 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>Hikvision \u043f\u043e\u0440\u0430\u0434\u043e\u0432\u0430\u043b \u043c\u0435\u043d\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c, \u0438 \u0443 \u043a\u0430\u043c\u0435\u0440\u044b \u0435\u0441\u0442\u044c \u0432\u0435\u0431 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 IP \u0430\u0434\u0440\u0435\u0441 \u0432 IE, Chrome \u0438\u043b\u0438 Firefox\u2019\u0435. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u044e \u0432 Windows 11:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/c74\/172\/f99\/c74172f996c554c0361c61a844da7ce7.jpg\" alt=\"Windows 11, Edge \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 IE\" title=\"Windows 11, Edge \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 IE\" width=\"1034\" height=\"736\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c74\/172\/f99\/c74172f996c554c0361c61a844da7ce7.jpg\" data-blurred=\"true\"\/><figcaption>Windows 11, Edge \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 IE<\/figcaption><\/figure>\n<p>\u0422\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c Edge \u0434\u043e IE. \u0421\u043c\u0435\u0448\u043d\u043e. \u0412 11-\u0439, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c, \u043d\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c IE, \u0437\u0430\u0442\u043e \u0435\u0441\u0442\u044c \u0440\u0435\u0436\u0438\u043c IE (\u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0435). \u0412\u043a\u043b\u044e\u0447\u0430\u044e \u2014 \u043d\u0435 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f. Chrome, FF \u2014 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, Linux \u2014 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435. \u0412\u0435\u0441\u0435\u043b\u043e. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e Win 7 \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u043a\u0443, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e \u043a\u0430\u043c\u0435\u0440\u0443. \u0411\u0435\u0437 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432. \u0421\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0440\u0430\u0434\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u0430\u043c\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u044b \u0443 \u043c\u0435\u043d\u044f \u043f\u0440\u0435\u0442\u0435\u043d\u0437\u0438\u0439 \u043d\u0435\u0442.<\/p>\n<h2>\u0423\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f<\/h2>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u041c\u043e\u0438 \u043a\u0430\u043c\u0435\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a \u0440\u043e\u0443\u0442\u0435\u0440\u0443 \u0441 \u00ab\u0441\u0435\u0440\u044b\u043c\u00bb IP \u0430\u0434\u0440\u0435\u0441\u043e\u043c, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0441\u044f \u0438\u0437\u0432\u043d\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 (\u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u043f\u043e\u043a\u0443\u043f\u043a\u0438 IP) \u2014 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c SSH \u0442\u0443\u043d\u043d\u0435\u043b\u044c \u0434\u043e \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441 \u00ab\u0431\u0435\u043b\u044b\u043c\u00bb IP:<\/p>\n<pre><code class=\"bash\">ssh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -R &lt;remote_port>:&lt;local_ip>:&lt;local_port> &lt;login>@&lt;remote_ip><\/code><\/pre>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438. \u0412\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 &lt;remote_ip>:&lt;remote_port> \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0431\u0440\u043e\u0448\u0435\u043d\u044b \u043d\u0430 &lt;local_ip>:&lt;local_port>, \u0442.\u00a0\u0435. \u043d\u0430 \u043a\u0430\u043c\u0435\u0440\u0443. \u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441\u043b\u0443\u0448\u0430\u043b \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u0440\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u00abGatewayPorts yes\u00bb \u0432 sshd_config. \u042d\u0442\u043e \u043d\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e, \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a \u043d\u0435 \u043d\u0430\u0434\u043e. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043b\u043e\u0433\u0438\u043d\/\u043f\u0430\u0440\u043e\u043b\u044c \u043e\u0442  \u043a\u0430\u043c\u0435\u0440\u044b \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0433\u0443\u043b\u044f\u0435\u0442 \u043f\u043e \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443 \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0432\u0438\u0434\u0435 \u0438 \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d.<\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u044d\u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <a href=\"https:\/\/github.com\/aler9\/rtsp-simple-server\" rel=\"noopener noreferrer nofollow\">rtsp-simple-server<\/a>. \u041e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 Go, \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u043c\u043e\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438. \u041d\u043e \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u044f\u0445.<\/p>\n<h2>\u0422\u0435\u0445\u0437\u0430\u0434\u0430\u043d\u0438\u0435<\/h2>\n<p>\u041e\u043f\u044b\u0442, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043f\u043e\u043c\u043e\u0433 \u043c\u043d\u0435 \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0431\u0443\u0434\u0443\u0449\u0435\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0443.<\/p>\n<ul>\n<li>\n<p>\u041d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438. \u041e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043a\u0430\u043c\u0435\u0440\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0436\u0435\u043b\u0435\u0437\u043e\u0431\u0435\u0442\u043e\u043d\u043d\u043e. \u041f\u043e \u043c\u043e\u0438\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f\u043c, \u043a\u0430\u043c\u0435\u0440\u044b \u0433\u043b\u044e\u0447\u0438\u0442 \u043f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 (\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u2014 \u044d\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u2014 \u0434\u0432\u0443\u0445). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u0435, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0438\u0437\u043a\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440. \u0414\u043b\u044f \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0439 Intel NUC \u043d\u0430\u0447\u043d\u0435\u0442 \u0435\u0441\u0442\u044c \u0431\u0430\u0442\u0430\u0440\u0435\u044e \u0431\u0435\u0441\u043f\u0435\u0440\u0435\u0431\u043e\u0439\u043d\u0438\u043a\u0430 \u0438 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e \u0448\u0443\u0440\u0448\u0430\u0442\u044c \u043e\u0445\u043b\u0430\u0436\u0434\u0430\u044e\u0449\u0435\u0439 \u0442\u0443\u0440\u0431\u0438\u043d\u043a\u043e\u0439.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441 IP \u043a\u0430\u043c\u0435\u0440 \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u043c\u0443 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0435\u0431 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0436\u0435\u0441\u0442\u043a\u0438\u0439 \u0434\u0438\u0441\u043a \u0441 \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u043e\u0439 \u043d\u0430 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b \u0438 \u0441\u0443\u0442\u043e\u0447\u043d\u043e\u0439 \u0440\u043e\u0442\u0430\u0446\u0438\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043a\u0430\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a \u043f\u043e\u0441\u043b\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440. \u0420\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0437-\u0437\u0430 \u043f\u0435\u0440\u0435\u0431\u043e\u044f \u043f\u0438\u0442\u0430\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e  \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0443 \u0432\u0441\u0435, \u0422\u0417 \u0435\u0441\u0442\u044c, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u044e \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<h2>\u0421\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c, \u043a\u0430\u043a VLC \u043e\u0431\u0449\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u0430\u043c\u0435\u0440\u0430\u043c\u0438. \u0412\u043a\u043b\u044e\u0447\u0430\u044e Wireshark \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c tcp.port == 554 \u0438 \u0432\u0438\u0436\u0443:<\/p>\n<details class=\"spoiler\">\n<summary>Rubetek<\/summary>\n<div class=\"spoiler__content\">\n<p>Ask: OPTIONS rtsp:\/\/192.168.0.114:554\/onvif1 RTSP\/1.0<br \/> CSeq: 2<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 2<br \/> Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER,USER_CMD_SET<\/p>\n<p>Ask: DESCRIBE rtsp:\/\/192.168.0.114:554\/onvif1 RTSP\/1.0<br \/> CSeq: 3<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Accept: application\/sdp<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 3<br \/> Content-Type: application\/sdp<br \/> Content-Length: 422<\/p>\n<p>v=0<br \/> o=- 1421069297525233 1 IN IP4 192.168.0.113<br \/> s=H.264 Video, RtspServer_0.0.0.2<br \/> t=0 0<br \/> a=tool:RtspServer_0.0.0.2<br \/> a=type:broadcast<br \/> a=control:*<br \/> a=range:npt=0-<br \/> m=video 0 RTP\/AVP 96<br \/> c=IN IP4 0.0.0.0<br \/> b=AS:500<br \/> a=rtpmap:96 H264\/90000<br \/> a=fmtp:96 packetization-mode=1;profile-level-id=42001F;sprop-parameter-sets=Z0IAH5WoFAFuQA==,aM48gA==<br \/> a=control:track1<br \/> m=audio 0 RTP\/AVP 8<br \/> a=control:track2<br \/> a=rtpmap:8 PCMA\/8000<\/p>\n<p>Ask: SETUP rtsp:\/\/192.168.0.114:554\/onvif1\/track1 RTSP\/1.0<br \/> CSeq: 4<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Transport: RTP\/AVP;unicast;client_port=45150-45151<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 4<br \/> Transport: RTP\/AVP;unicast;destination=192.168.0.165;source=192.168.0.113;client_port=45150-45151;server_port=7060-7061<br \/> Session: 7c2467db;timeout=60<\/p>\n<p>Ask: SETUP rtsp:\/\/192.168.0.114:554\/onvif1\/track2 RTSP\/1.0<br \/> CSeq: 5<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Transport: RTP\/AVP;unicast;client_port=35736-35737<br \/> Session: 7c2467db<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 5<br \/> Transport: RTP\/AVP;unicast;destination=192.168.0.165;source=192.168.0.113;client_port=35736-35737;server_port=7062-7063<br \/> Session: 7c2467db;timeout=60<\/p>\n<p>Ask: PLAY rtsp:\/\/192.168.0.114:554\/onvif1 RTSP\/1.0<br \/> CSeq: 6<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 7c2467db<br \/> Range: npt=0.000-<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 6<br \/> Range: npt=0.000-<br \/> Session: 7c2467db<br \/> RTP-Info: url=rtsp:192.168.0.113:554\/onvif1\/track1;seq=57651;rtptime=61388916750,url=rtsp:192.168.0.113:554\/onvif1\/track2;seq=58422;rtptime=5456792600<\/p>\n<p>*** \u0422\u0443\u0442 \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 ***<\/p>\n<p>Ask: TEARDOWN rtsp:\/\/192.168.0.114:554\/onvif1 RTSP\/1.0<br \/> CSeq: 7<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 7c2467db<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Hikvision<\/summary>\n<div class=\"spoiler__content\">\n<p>Ask: OPTIONS rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101 RTSP\/1.0<br \/> CSeq: 2<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 2<br \/> Public: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER<br \/> Date:  Mon, Nov 22 2021 09:57:17 GMT<\/p>\n<p>Ask: DESCRIBE rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101 RTSP\/1.0<br \/> CSeq: 3<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Accept: application\/sdp<\/p>\n<p>Reply: RTSP\/1.0 401 Unauthorized<br \/> CSeq: 3<br \/> WWW-Authenticate: Digest realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, stale=&#187;FALSE&#187;<br \/> Date:  Mon, Nov 22 2021 09:57:17 GMT<\/p>\n<p>Ask: DESCRIBE rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101 RTSP\/1.0<br \/> CSeq: 4<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101&#8243;, response=&#187;69ce13d857b38e6e68f7f5a4a85cd709&#8243;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Accept: application\/sdp<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 4<br \/> Content-Type: application\/sdp<br \/> Content-Base: rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/<br \/> Content-Length: 587<\/p>\n<p>v=0<br \/> o=- 1637575037561170 1637575037561170 IN IP4 192.168.0.110<br \/> s=Media Presentation<br \/> e=NONE<br \/> b=AS:5050<br \/> t=0 0<br \/> a=control:rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/<br \/> m=video 0 RTP\/AVP 96<br \/> c=IN IP4 0.0.0.0<br \/> b=AS:5000<br \/> a=recvonly<br \/> a=x-dimensions:1920,1080<br \/> a=control:rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/trackID=1<br \/> a=rtpmap:96 H265\/90000<br \/> a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwB7oAPAgBDljb5JMvTcBAQEAg==; sprop-pps=RAHA8vA8kAA=<br \/> a=Media_header:MEDIAINFO=494D4B48010300000400050000000000000000000000000081000000000000000000000000000000;<br \/> a=appversion:1.0<\/p>\n<p>Ask: SETUP rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/trackID=1 RTSP\/1.0<br \/> CSeq: 5<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/&#187;, response=&#187;2341d81156d9cee08db0004835486f51&#8243;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Transport: RTP\/AVP;unicast;client_port=59446-59447<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 5<br \/> Session:        695167870;timeout=60<br \/> Transport: RTP\/AVP;unicast;client_port=59446-59447;server_port=8302-8303;ssrc=568ed713;mode=&#187;play&#187;<br \/> Date:  Mon, Nov 22 2021 09:57:17 GMT<\/p>\n<p>Ask: PLAY rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/ RTSP\/1.0<br \/> CSeq: 6<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/&#187;, response=&#187;a2a71ba4866e2f77d14f7368f368da5f&#187;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 695167870<br \/> Range: npt=0.000-<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 6<br \/> Session:        695167870<br \/> RTP-Info: url=rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/trackID=1;seq=54784;rtptime=2171307498<br \/> Date:  Mon, Nov 22 2021 09:57:17 GMT<\/p>\n<p>Ask: GET_PARAMETER rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/ RTSP\/1.0<br \/> CSeq: 7<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/&#187;, response=&#187;192d15433a0964eb2782026d8e908ed3&#8243;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 695167870<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 7<br \/> Date:  Mon, Nov 22 2021 09:58:15 GMT<\/p>\n<p>Ask: GET_PARAMETER rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/ RTSP\/1.0<br \/> CSeq: 9<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/&#187;, response=&#187;192d15433a0964eb2782026d8e908ed3&#8243;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 695167870<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 9<br \/> Date:  Mon, Nov 22 2021 10:00:11 GMT<\/p>\n<p>*** \u0422\u0443\u0442 \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 ***<\/p>\n<p>Ask: TEARDOWN rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/ RTSP\/1.0<br \/> CSeq: 16<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/&#187;, response=&#187;e6ef5c8c7ab615db158e7e77c8f7b77a&#187;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session:<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 16<br \/> Session:        695167870<br \/> Date:  Mon, Nov 22 2021 10:06:25 GMT<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b RTSP, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u043f\u0438\u0441\u0430\u043d \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043d\u0435\u043c \u044f \u043d\u0435 \u0432\u0438\u0436\u0443 \u0441\u043c\u044b\u0441\u043b\u0430. \u0410 \u0432\u043e\u0442 \u043e \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u044f\u0445 \u0441\u0442\u043e\u0438\u0442 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u0443 \u0441\u043b\u043e\u0432.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043e\u0442\u0434\u0430\u0435\u0442 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u0432\u0441\u0435\u043c \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u043c, \u0432\u0442\u043e\u0440\u0430\u044f \u0436\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u0430\u0439\u0434\u0436\u0435\u0441\u0442-\u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (\u0441\u0442\u0440\u043e\u043a\u0430 WWW-Authenticate: Digest \u0432 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0435). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 DESCRIBE \u043e\u043d\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 401 Unauthorized, \u043d\u043e \u0434\u0430\u0435\u0442 \u043a\u043b\u044e\u0447\u0438 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f realm \u0438 nonce. \u0418\u043c\u0435\u044f \u044d\u0442\u0438 \u043a\u043b\u044e\u0447\u0438, \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 response, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f  \u0442\u0430\u043a:<\/p>\n<p><code>response = md5(md5(login:realm:password):nonce:md5(option:url),<\/code><\/p>\n<p>\u0433\u0434\u0435  login:password \u2014 \u043b\u043e\u0433\u0438\u043d\/\u043f\u0430\u0440\u043e\u043b\u044c \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b, option \u2014 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434.<\/p>\n<p>\u0415\u0449\u0435 \u043e\u0434\u043d\u043e \u0432\u0430\u0436\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0443 \u043f\u0435\u0440\u0432\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u044b \u043c\u0438\u043a\u0440\u043e\u0444\u043e\u043d\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043b\u0438\u0435\u043d\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 SETUP \u0434\u0432\u0430\u0436\u0434\u044b: \u0434\u043b\u044f \u0432\u0438\u0434\u0435\u043e (track1) \u0438 \u0437\u0432\u0443\u043a\u043e\u0432\u043e\u0439 \u0434\u043e\u0440\u043e\u0436\u043a\u0438 (track2).<br \/> \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0434\u043e\u0440\u043e\u0436\u043a\u0438 VLC \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442 client_port, \u043a\u0443\u0434\u0430 \u043a\u0430\u043c\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 UDP.<\/p>\n<h2>\u0421\u043a\u0440\u0438\u043f\u0442<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u041f\u0438\u0441\u0430\u0442\u044c \u044f \u0431\u0443\u0434\u0443 \u043d\u0430 \u00ab\u0447\u0438\u0441\u0442\u043e\u043c\u00bb Python 3.7+, \u0431\u0435\u0437 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432\u0441\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e, \u043d\u0435\u043f\u043b\u043e\u0445\u043e \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 asyncio.<\/p>\n<p>\u0418\u0434\u0435\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430: \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u0435, \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u0435\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0440\u043e\u0432\u043d\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043c\u0435\u043b\u043a\u0438\u0445 \u0434\u0435\u0442\u0430\u043b\u0435\u0439). \u0412\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u0434\u0430\u0432\u0430\u0442\u044c (\u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c) \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u043f\u043e \u043c\u0435\u0440\u0435 \u0438\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043b\u0438\u0441\u0442\u0438\u043d\u0433 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043e\u0431\u043b\u0435\u0433\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u041f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043d\u0430 <a href=\"https:\/\/github.com\/vladpen\/python-rtsp-server\" rel=\"noopener noreferrer nofollow\">Github<\/a>.<\/p>\n<details class=\"spoiler\">\n<summary>main.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import asyncio from config import Config from camera import Camera from client import Client   async def main():     for hash in Config.cameras.keys():         await Camera(hash).connect()      await Client.listen()   if __name__ == '__main__':     asyncio.run(main())<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u044f \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u044e \u0432\u0441\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u044e \u0441\u043b\u0443\u0448\u0430\u0442\u044c TCP \u043f\u043e\u0440\u0442 4554. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0436\u0438\u0437\u043d\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u2014 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432\u0435\u0434\u044c \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435 \u0431\u044b\u0442\u044c, \u0430 \u044d\u043b\u0435\u043a\u0442\u0440\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0430\u0434\u043e \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c:)<\/p>\n<details class=\"spoiler\">\n<summary>config.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import socket   class Config:     cameras = {         '\u0445\u0435\u0448\/\u043b\u044e\u0431\u0430\u044f-URL-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0430\u044f-\u0441\u0442\u0440\u043e\u043a\u0430': {             'path': '\u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043a \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443',             'url': 'rtsp:\/\/&lt;\u043b\u043e\u0433\u0438\u043d>:&lt;\u043f\u0430\u0440\u043e\u043b\u044c>@&lt;\u0445\u043e\u0441\u0442>:554\/&lt;uri>'},     }      rtsp_port = 4554     start_udp_port = 5550      local_ip = socket.gethostbyname(socket.gethostname())      # \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0447\u0438\u0441\u043b\u043e \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432     web_limit = 2      log_file = '\/var\/log\/python-rtsp-server.log'<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u0430\u043c\u0435\u0440\u0430\u043c \u044f \u0431\u0443\u0434\u0443 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0430\u043c \u0432\u0438\u0434\u0430 rtsp:\/\/&lt;\u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430>:&lt;\u043f\u043e\u0440\u0442>\/&lt;\u0445\u0435\u0448 \u043a\u0430\u043c\u0435\u0440\u044b>, \u0433\u0434\u0435 \u0445\u0435\u0448 \u043a\u0430\u043c\u0435\u0440\u044b \u2014 \u043b\u044e\u0431\u0430\u044f URL-\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u044b UTF. \u0425\u0435\u0448\u0438 \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u043a\u0430\u043c\u0435\u0440 \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u0441\u043b\u043e\u0432\u0430\u0440\u0435 cameras.<\/p>\n<details class=\"spoiler\">\n<summary>camera.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import asyncio import re import time from hashlib import md5 from shared import Shared from config import Config from log import Log   class Camera:     def __init__(self, hash):         self.hash = hash         self.url = self._parse_url(Config.cameras[hash]['url'])      async def connect(self):         \"\"\" \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c TCP \u0441\u043e\u043a\u0435\u0442 \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u0430\u043c\u0435\u0440\u0443         \"\"\"         self.udp_ports = self._get_self_udp_ports()         self.cseq = 1         self.realm, self.nonce = None, None          try:             self.reader, self.writer = await asyncio.open_connection(self.url['host'], self.url['tcp_port'])         except Exception as e:             print(f\"Can't connect to camera [{self.hash}]: {e}\")             return          await self._request('OPTIONS', self.url['url'])          reply, code = await self._request(             'DESCRIBE',             self.url['url'],             'User-Agent: python-rtsp-server',             'Accept: application\/sdp')          if code == 401:             self.realm, self.nonce = self._get_auth_params(reply)              reply, code = await self._request(                 'DESCRIBE',                 self.url['url'],                 'Accept: application\/sdp')          self.description = self._get_description(reply)          track_ids = self._get_track_ids(reply)          reply, code = await self._request(             'SETUP',             f'{self.url[\"url\"]}\/{track_ids[0]}',             ('Transport: RTP\/AVP;unicast;'                 f'client_port={self.udp_ports[\"track1\"][0]}-{self.udp_ports[\"track1\"][1]}'))          self.session_id = self._get_session_id(reply)          if len(track_ids) > 1:             reply, code = await self._request(                 'SETUP',                 f'{self.url[\"url\"]}\/{track_ids[1]}',                 ('Transport: RTP\/AVP;unicast;'                     f'client_port={self.udp_ports[\"track2\"][0]}-{self.udp_ports[\"track2\"][1]}'),                 f'Session: {self.session_id}')          reply, code = await self._request(             'PLAY',             self.url['url'],             f'Session: {self.session_id}',             'Range: npt=0.000-')          Shared.data[self.hash] = {             'description': self.description,             'rtp_info': self._get_rtp_info(reply),             # 'transports': {},             'clients': {}}          Log.add(f'Camera [{self.hash}] connected')          await self._listen()      async def _listen(self):         \"\"\" \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c UDP \u0441\u043e\u043a\u0435\u0442 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u044b         \"\"\"         await self._start_server('track1')          if self.description['audio']:             await self._start_server('track2')      async def _request(self, option, url, *lines):         \"\"\" \u0417\u0430\u043f\u0440\u043e\u0441 \u043a \u043a\u0430\u043c\u0435\u0440\u0435 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c OPTION \u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438.             \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u0438 \u0441\u0442\u0430\u0442\u0443\u0441         \"\"\"         command = f'{option} {url} RTSP\/1.0\\r\\n' \\             f'CSeq: {self.cseq}\\r\\n'          auth_line = self._get_auth_line(option)         if auth_line:             command += f'{auth_line}\\r\\n'          for row in lines:             if row:                 command += f'{row}\\r\\n'         command += '\\r\\n'          print(f'*** Ask:\\n{command}')         self.writer.write(command.encode())         reply = (await self.reader.read(4096)).decode()         print(f\"*** Reply:\\n{reply}\")         self.cseq += 1          res = re.match(r'RTSP\/1.0 (\\d{3}) ([^\\r\\n]+)', reply)         if not res:             print('Error: invalid reply\\n')             return reply, 0         return reply, int(res.group(1))      def _get_auth_params(self, reply):         \"\"\" \u0414\u043e\u0441\u0442\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b realm \u0438 nonce \u0434\u043b\u044f \"digest\" \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438         \"\"\"         realm_nonce = re.match(r'.+?\\nWWW-Authenticate:.+?realm=\"(.+?)\", ?nonce=\"(.+?)\"', reply, re.DOTALL)         if not realm_nonce:             raise RuntimeError('Invalid digest auth reply')          return realm_nonce.group(1), realm_nonce.group(2)      def _get_auth_line(self, option):         \"\"\" \u0421\u043e\u0431\u0440\u0430\u0442\u044c \"response\" \u0445\u0435\u0448 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438         \"\"\"         if not self.realm or not self.nonce:             return         ha1 = md5(f'{self.url[\"login\"]}:{self.realm}:{self.url[\"password\"]}'.encode('utf-8')).hexdigest()         ha2 = md5(f'{option}:{self.url[\"url\"]}'.encode('utf-8')).hexdigest()         response = md5(f'{ha1}:{self.nonce}:{ha2}'.encode('utf-8')).hexdigest()         line = f'Authorization: Digest username=\"{self.url[\"login\"]}\", ' \\             f'realm=\"{self.realm}\" nonce=\"{self.nonce}\", uri=\"{self.url[\"url\"]}\", response=\"{response}\"'         return line      def _get_description(self, reply):         \"\"\" \u0414\u043e\u0441\u0442\u0430\u0442\u044c SDP (Session Description Protocol) \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430         \"\"\"         blocks = reply.split('\\r\\n\\r\\n', 2)         if len(blocks) &lt; 2:             raise RuntimeError('Invalid DESCRIBE reply')          sdp = blocks[1].strip()          details = {'video': {}, 'audio': {}}          res = re.match(r'.+?\\nm=video (.+?)\\r\\n', sdp, re.DOTALL)         if res:             details['video'] = {'media': res.group(1), 'bandwidth': '', 'rtpmap': '', 'format': ''}              res = re.match(r'.+?\\nm=video .+?\\nb=([^\\r\\n]+)', sdp, re.DOTALL)             if res:                 details['video']['bandwidth'] = res.group(1)              res = re.match(r'.+?\\nm=video .+?\\na=rtpmap:([^\\r\\n]+)', sdp, re.DOTALL)             if res:                 details['video']['rtpmap'] = res.group(1)              res = re.match(r'.+?\\nm=video .+?\\na=fmtp:([^\\r\\n]+)', sdp, re.DOTALL)             if res:                 details['video']['format'] = res.group(1)          res = re.match(r'.+?\\nm=audio (.+?)\\r\\n', sdp, re.DOTALL)         if res:             details['audio'] = {'media': res.group(1), 'rtpmap': ''}              res = re.match(r'.+?\\nm=audio .+?\\na=rtpmap:([^\\r\\n]+)', sdp, re.DOTALL)             if res:                 details['audio']['rtpmap'] = res.group(1)          return details      def _get_rtp_info(self, reply):         \"\"\" \u0414\u043e\u0441\u0442\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \"RTP-Info\" \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430         \"\"\"         res = re.match(r'.+?\\r\\n(RTP-Info: .+?)\\r\\n', reply, re.DOTALL)         if not res:             raise RuntimeError('Invalid RTP-Info')         rtp_info = res.group(1)          seq = re.findall(r';seq=(\\d+)', rtp_info)         rtptime = re.findall(r';rtptime=(\\d+)', rtp_info)         if not seq or not rtptime:             raise RuntimeError('Invalid RTP-Info')          return {'seq': seq, 'rtptime': rtptime, 'starttime': time.time()}      def _get_track_ids(self, reply):         \"\"\" \u0414\u043e\u0441\u0442\u0430\u0442\u044c ID \u0434\u043e\u0440\u043e\u0436\u0435\u043a \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430         \"\"\"         track_ids = re.findall(r'\\na=control:.*?(track.*?\\d)', reply, re.DOTALL)         if not track_ids:             raise RuntimeError('Invalid track ID in reply')         return track_ids      def _get_session_id(self, reply):         \"\"\" \u0414\u043e\u0441\u0442\u0430\u0442\u044c ID \u0441\u0435\u0441\u0441\u0438\u0438 \u0438\u0437 \u043e\u0442\u0432\u0435\u0442\u0430         \"\"\"         res = re.match(r'.+?\\nSession: *([^;]+)', reply, re.DOTALL)         if not res:             raise RuntimeError('Invalid session ID')         return res.group(1)      def _get_self_udp_ports(self):         \"\"\" \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 UDP \u043f\u043e\u0440\u0442         \"\"\"         start_port = Config.start_udp_port         idx = list(Config.cameras.keys()).index(self.hash) * 4         return {             'track1': [start_port + idx, start_port + idx + 1],             'track2': [start_port + idx + 2, start_port + idx + 3]}      def _parse_url(self, url):         \"\"\" \u0420\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c url \u043a\u0430\u043c\u0435\u0440\u044b \u043d\u0430 \u0447\u0430\u0441\u0442\u0438         \"\"\"         parsed_url = re.match(r'(rtsps?):\/\/(.+?):([^@]+)@(.+?):(\\d+)(.+)', url)         if not parsed_url or len(parsed_url.groups()) != 6:             raise RuntimeError('Invalid rtsp url')         return {             'login': parsed_url.group(2),             'password': parsed_url.group(3),             'host': parsed_url.group(4),             'tcp_port': int(parsed_url.group(5)),             'url': url.replace(f'{parsed_url.group(2)}:{parsed_url.group(3)}@', '')}      async def _start_server(self, track_id):         \"\"\" \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c UDP \u0441\u0435\u0440\u0432\u0435\u0440         \"\"\"         loop = asyncio.get_running_loop()          await loop.create_datagram_endpoint(             lambda: CameraUdpProtocol(self.hash, track_id),             local_addr=('0.0.0.0', self.udp_ports[track_id][0]))   class CameraUdpProtocol(asyncio.DatagramProtocol):     \"\"\" \u042d\u0442\u043e\u0442 \u043a\u043e\u043b\u0431\u044d\u043a \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043a \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u0435     \"\"\"     def __init__(self, hash, track_id):         self.hash = hash         self.track_id = track_id      def connection_made(self, transport):         self.transport = transport      def datagram_received(self, data, addr):         if not Shared.data[self.hash]['clients']:             return          for _sid, client in Shared.data[self.hash]['clients'].items():             self.transport.sendto(data, (client['host'], client['ports'][self.track_id][0]))<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u0430\u043c\u0435\u0440\u044b. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 Camera.connect \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 RTSP, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u0432 \u043b\u0438\u0441\u0442\u0438\u043d\u0433\u0430\u0445 \u0432\u044b\u0448\u0435. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u044b \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b PLAY \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0435\u0440 asyncio.create_datagram_endpoint(), \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043a\u043e\u043b\u0431\u044d\u043a\u0435 CameraUdpProtocol.<\/p>\n<details class=\"spoiler\">\n<summary>client.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\"># https:\/\/docs.python.org\/3\/library\/asyncio-protocol.html  import asyncio import re import string import time from random import choices, randrange from config import Config from shared import Shared from log import Log   class Client:     def __init__(self):         self.camera_hash = None         self.udp_ports = {}      @staticmethod     async def listen():         \"\"\" \u0421\u043b\u0443\u0448\u0430\u0435\u043c \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432         \"\"\"         host = '0.0.0.0'         print(f'*** Start listening {host}:{Config.rtsp_port} ***\\n')          loop = asyncio.get_running_loop()         server = await loop.create_server(             lambda: ClientTcpProtocol(),             host, Config.rtsp_port)          async with server:             await server.serve_forever()      def handle_request(self, transport, host, data):         \"\"\" \u041e\u0431\u0449\u044f\u0435\u043c\u0441\u044f \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 RTSP         \"\"\"         ask, option = self._request(data)         session_id = self._get_session_id(ask)          if option == 'OPTIONS':             self._response(                 transport,                 'Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY')          if option == 'DESCRIBE':             sdp = self._get_description()             self._response(                 transport,                 'Content-Type: application\/sdp',                 f'Content-Length: {len(sdp) + 2}',                 '',                 sdp)          elif option == 'SETUP':             udp_ports = self._get_ports(ask)             track_id = 'track1' if not self.udp_ports else 'track2'             self.udp_ports[track_id] = udp_ports             self._response(                 transport,                 f'Transport: RTP\/AVP;unicast;client_port={udp_ports[0]}-{udp_ports[1]};server_port=5998-5999',                 f'Session: {session_id};timeout=60')          elif option == 'PLAY':             self._response(                 transport,                 f'Session: {session_id}',                 self._get_rtp_info())              # if session_id not in Shared.data[self.camera_hash]['clients']:             Shared.data[self.camera_hash]['clients'][session_id] = {                 'host': host, 'ports': self.udp_ports, 'transport': transport}              self._check_web_limit(host)              Log.add(f'Play [{self.camera_hash}] [{session_id}] [{host}]')          elif option == 'TEARDOWN':             self._response(transport, f'Session: {session_id}')          return self.camera_hash, session_id      def _get_rtp_info(self):         \"\"\" \u0421\u0442\u0440\u043e\u0438\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \"RTP-Info\" \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0438\u0437\u043c\u0435\u043d\u0438\u0432 \u0432\u0440\u0435\u043c\u044f rtptime \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430.             \u041f\u043e \u0445\u043e\u0440\u043e\u0448\u0435\u043c\u0443, \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u0443, \u043d\u043e \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 TCP (interleaved) \u0438\u043c \u044d\u0442\u043e \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f.         \"\"\"         rtp_info = Shared.data[self.camera_hash]['rtp_info']          print(rtp_info)          delta = time.time() - rtp_info['starttime']         rtptime = int(rtp_info[\"rtptime\"][0]) + int(delta * 90000)         # 90000 is clock frequency in SDP a=rtpmap:96 H26*\/90000          res = f'RTP-Info: url=rtsp:\/\/{Config.local_ip}:{Config.rtsp_port}\/track1;' \\             f'seq={rtp_info[\"seq\"][0]};rtptime={rtptime}'          if len(rtp_info['seq']) &lt; 2:             return res          rtptime = int(rtp_info[\"rtptime\"][1]) + int(delta * 8000)         # 90000 is clock frequency in SDP a=rtpmap:8 PCMA\/8000          res += f',url=rtsp:\/\/{Config.local_ip}:{Config.rtsp_port}\/track2;' \\             f'seq={rtp_info[\"seq\"][1]};rtptime={rtptime}'          return res      def _request(self, data):         \"\"\" \u0420\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c \u043e\u0442\u0432\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u0430         \"\"\"         try:             ask = data.decode()         except Exception:             raise RuntimeError(f\"can't decode this ask:\\n{data}\")          print(f'*** Ask:\\n{ask}')         # res = re.match(r'(.+?) rtsps?:\/\/.+?:\\d+\/(.+?)(\/track.*?)? .+?\\r\\n', ask)         res = re.match(r'(.+?) rtsps?:\/\/.+?:\\d+\/?(.*?) .+?\\r\\n', ask)         if not res:             raise RuntimeError('invalid ask')          self.cseq = self._get_cseq(ask)          if not self.camera_hash:             hash = res.group(2)             if hash not in Config.cameras:                 raise RuntimeError('invalid camera hash')             if hash not in Shared.data:                 raise RuntimeError('camera is offline')             self.camera_hash = hash          return ask, res.group(1)      def _response(self, transport, *lines):         \"\"\" \u041e\u0442\u0434\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0443 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438         \"\"\"         reply = 'RTSP\/1.0 200 OK\\r\\n' \\             f'CSeq: {self.cseq}\\r\\n'          for row in lines:             reply += f'{row}\\r\\n'         reply += '\\r\\n'          transport.write(reply.encode())          print(f'*** Reply:\\n{reply}')      def _get_cseq(self, ask):         \"\"\" \u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430         \"\"\"         res = re.match(r'.+?\\r\\nCSeq: (\\d+)', ask, re.DOTALL)         if not res:             raise RuntimeError('invalid incoming CSeq')         return int(res.group(1))      def _get_session_id(self, ask):         \"\"\" ID \u0441\u0435\u0441\u0441\u0438\u0438 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430         \"\"\"         res = re.match(r'.+?\\nSession: *([^;\\r\\n]+)', ask, re.DOTALL)         if res:             return res.group(1).strip()          return ''.join(choices(string.ascii_lowercase + string.digits, k=9))      def _get_ports(self, ask):         \"\"\" \u041d\u043e\u043c\u0435\u0440\u0430 \u043f\u043e\u0440\u0442\u043e\u0432 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430         \"\"\"         res = re.match(r'.+?\\nTransport:[^\\n]+client_port=(\\d+)-(\\d+)', ask, re.DOTALL)         if not res:             raise RuntimeError('invalid transport ports')         return [int(res.group(1)), int(res.group(2))]      def _get_description(self):         \"\"\" \u0411\u043b\u043e\u043a SDP \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430         \"\"\"         sdp = Shared.data[self.camera_hash]['description']         res = 'v=0\\r\\n' \\             f'o=- {randrange(100000, 999999)} {randrange(1, 10)} IN IP4 {Config.local_ip}\\r\\n' \\             's=python-rtsp-server\\r\\n' \\             't=0 0'          if not sdp['video']:             return res         res += f'\\r\\nm=video {sdp[\"video\"][\"media\"]}\\r\\n' \\             'c=IN IP4 0.0.0.0\\r\\n' \\             f'b={sdp[\"video\"][\"bandwidth\"]}\\r\\n' \\             f'a=rtpmap:{sdp[\"video\"][\"rtpmap\"]}\\r\\n' \\             f'a=fmtp:{sdp[\"video\"][\"format\"]}\\r\\n' \\             'a=control:track1'          if not sdp['audio']:             return res         res += f'\\r\\nm=audio {sdp[\"audio\"][\"media\"]}\\r\\n' \\             f'a=rtpmap:{sdp[\"audio\"][\"rtpmap\"]}\\r\\n' \\             'a=control:track2'         return res      def _check_web_limit(self, host):         \"\"\" \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u043c \u0432\u0435\u0431 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 - \u0431\u0435\u0437 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439.         \"\"\"         if not Config.web_limit or self._get_client_type(host) == 'local':             return         web_sessions = []         for session_id, data in Shared.data[self.camera_hash]['clients'].items():             if self._get_client_type(data['host']) == 'web':                 web_sessions.append(session_id)         if len(web_sessions) > Config.web_limit:             ws = web_sessions[:-Config.web_limit]             for session_id in ws:                 print('Web limit exceeded, cloce old connection\\n')                 Shared.data[self.camera_hash]['clients'][session_id]['transport'].close()                 # Shared.data item will be deleted by ClientTcpProtocol.connection_lost callback      def _get_client_type(self, host):         \"\"\" \u0425\u0435\u043b\u043f\u0435\u0440 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f.             \u0415\u0441\u043b\u0438 IP \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u043c \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0442\u043e \u044d\u0442\u043e \u0432\u0435\u0431 \u043a\u043b\u0438\u0435\u043d\u0442 \u0437\u0430 ssh \u0442\u0443\u043d\u043d\u0435\u043b\u0435\u043c         \"\"\"         if host == '127.0.0.1' \\             or host == 'localhost' \\                 or (host.startswith('192.168.') and host != Config.local_ip):             return 'local'         return 'web'   class ClientTcpProtocol(asyncio.Protocol):     \"\"\" \u042d\u0442\u043e\u0442 \u043a\u043e\u043b\u0431\u044d\u043a \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430     \"\"\"     def __init__(self):         self.client = Client()         self.camera_hash, self.session_id = None, None         # self.event = event      def connection_made(self, transport):         peername = transport.get_extra_info('peername')         self.transport = transport         self.host = peername[0]         print(f'*** New connection from {peername[0]}:{peername[1]} ***\\n\\n')      def data_received(self, data):         try:             self.camera_hash, self.session_id = self.client.handle_request(self.transport, self.host, data)         except Exception as e:             print(f'Error in clent request handler: {e}\\n\\n')             self.transport.close()      def connection_lost(self, exc):         if not self.session_id or self.session_id not in Shared.data[self.camera_hash]['clients']:             return         del(Shared.data[self.camera_hash]['clients'][self.session_id])         Log.add(f'Close [{self.camera_hash}] [{self.session_id}] [{self.host}]')<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432. Metod Client.handle_request \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u043e \u0436\u0435, \u0447\u0442\u043e \u0438  Camera.connect, \u043d\u043e \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043f\u0440\u0438\u043a\u0438\u043d\u0443\u0432\u0448\u0438\u0441\u044c \u043a\u0430\u043c\u0435\u0440\u043e\u0439. \u0417\u0430 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u0430 4554 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 asyncio.create_server (\u043e\u0434\u0438\u043d \u043d\u0430 \u0432\u0441\u0435\u0445) \u0438 \u0435\u0433\u043e \u043a\u043e\u043b\u0431\u044d\u043a ClientTcpProtocol (\u043f\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0443 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430).<\/p>\n<details class=\"spoiler\">\n<summary>shared.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">class Shared:     \"\"\" \u0412\u0441\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 (tasks) \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0449\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442     \"\"\"     data = {}<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442 Sared.data \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u0437\u0430\u0434\u0430\u0447\u0430\u043c\u0438 (tasks) \u0438 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0430\u043c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>log.py<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import time from config import Config   class Log:     @staticmethod     def add(info):         print(f'*** {info} ***\\n\\n')         try:             with open(Config.log_file, 'a') as f:                 f.write(f'{time.strftime(\"%Y-%m-%d %H:%M:%S\")} {info}\\n')         except Exception as e:             print(f'Log error: {e}\\n\\n')             pass<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u0430 \u0437\u0430\u043e\u0434\u043d\u043e \u0438 \u0437\u0430 \u0432\u044b\u0432\u043e\u0434 \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.<\/p>\n<h2>\u0422\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u00ab\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439\u00bb Python \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0441\u043e\u043a\u043e\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u043c\u0443 \u043c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u043e\u043c\u0443 Go? \u041d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430\u0445 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f  \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0448\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0438 rtsp-simple-server. \u0423\u0441\u043b\u043e\u0432\u0438\u044f \u0440\u0430\u0432\u043d\u044b\u0435, \u043e\u0434\u043d\u0430 \u043a\u0430\u043c\u0435\u0440\u0430 \u0438 10 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0442\u0435\u0441\u0442\u0435. \u0421\u0435\u0440\u0432\u0435\u0440 \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442 \u0438 \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u0432\u043e\u0442 \u043c\u043e\u0439 \u0434\u0435\u0441\u043a\u0442\u043e\u043f \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0434\u0438\u043a\u043e \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u043e\u043a\u043e\u043d. \u0412\u044b\u043f\u0430\u0434\u0435\u043d\u0438\u0439 \u043a\u0430\u0434\u0440\u043e\u0432 \u043d\u0430 \u0433\u043b\u0430\u0437 \u043d\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0432 \u043e\u0431\u043e\u0438\u0445 \u0442\u0435\u0441\u0442\u0430\u0445.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/47e\/305\/7e6\/47e3057e6f7115fa2571872125ca9cbc.jpg\" alt=\"Python\" title=\"Python\" width=\"1426\" height=\"478\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/47e\/305\/7e6\/47e3057e6f7115fa2571872125ca9cbc.jpg\" data-blurred=\"true\"\/><figcaption>Python<\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/723\/176\/3ca\/7231763caa2282c53ad57d81987a60fc.jpg\" alt=\"Go\" title=\"Go\" width=\"1426\" height=\"478\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/723\/176\/3ca\/7231763caa2282c53ad57d81987a60fc.jpg\" data-blurred=\"true\"\/><figcaption>Go<\/figcaption><\/figure>\n<p>\u0421\u0443\u0434\u0438\u0442\u0435 \u0441\u0430\u043c\u0438. \u041d\u0430 \u043c\u043e\u0439 \u0432\u043a\u0443\u0441, \u043d\u0435\u043f\u043b\u043e\u0445\u043e. \u0415\u0441\u0442\u044c \u0441\u043c\u044b\u0441\u043b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0438 \u0434\u043e\u0432\u0435\u0441\u0442\u0438 \u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043a\u043e\u043d\u0446\u0430.<\/p>\n<h2>\u0427\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435?<\/h2>\n<p>\u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0436\u0438\u0437\u043d\u0438, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0432\u0441\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u0447\u0435\u043c \u0432 \u0442\u0435\u043e\u0440\u0438\u0438. \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c UDP \u043f\u0430\u043a\u0435\u0442\u044b \u0447\u0435\u0440\u0435\u0437 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0439 \u0432\u044b\u0448\u0435 SSH \u0442\u0443\u043d\u043d\u0435\u043b\u044c \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u0414\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435, \u0433\u043e\u043d\u044f\u0442\u044c UDP \u043f\u043e \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043c\u043d\u0435 \u043d\u0435 \u0441\u0430\u043c\u043e\u0439 \u043b\u0443\u0447\u0448\u0435\u0439 \u0438\u0434\u0435\u0435\u0439. \u0417\u043d\u0430\u0447\u0438\u0442, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0447\u0435\u0440\u0435\u0437 TCP.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u0438\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f\u043c \u043c\u043e\u0435\u0433\u043e WireShark\u2019\u0430, \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u0432 \u043e\u0431\u0449\u0435\u043d\u0438\u0438 VLC \u0441 \u043a\u0430\u043c\u0435\u0440\u0430\u043c\u0438 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 TCP (\u0441 \u043a\u043b\u044e\u0447\u043e\u043c \u2014rtsp-tcp) \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u0441\u0442\u0440\u043e\u043a\u0438<\/p>\n<blockquote>\n<p>Transport: RTP\/AVP\/TCP;unicast;interleaved=0-1<\/p>\n<\/blockquote>\n<p>\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 SETUP. \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u0437\u0434\u0435\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 TCP, \u0430 \u0432\u043c\u0435\u0441\u0442\u043e \u043f\u043e\u0440\u0442\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043d\u0430\u043b\u044b \u0447\u0435\u0440\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f interleaved=0-1 (\u0434\u043b\u044f \u0437\u0432\u0443\u043a\u043e\u0432\u043e\u0439 \u0434\u043e\u0440\u043e\u0436\u043a\u0438 interleaved=2-3). \u0412\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u043e\u0442\u043e\u043a \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d \u0432 \u0442\u043e\u0442 \u0436\u0435 TCP \u043f\u043e\u0440\u0442, \u0444\u0440\u0435\u0439\u043c\u044b \u0441 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441\u043e \u0437\u043d\u0430\u043a\u0430 \u0434\u043e\u043b\u043b\u0430\u0440\u0430, \u0437\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043d\u043e\u043c\u0435\u0440 \u043a\u0430\u043d\u0430\u043b\u0430. \u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0432 \u0447\u0435\u0445\u0430\u0440\u0434\u0443 \u043d\u0430 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0441\u043e\u043a\u0435\u0442\u0435, \u0441\u043b\u0443\u0448\u0430\u044e\u0449\u0438\u043c TCP \u043f\u043e\u0440\u0442.<\/p>\n<p>\u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0430 <a href=\"https:\/\/github.com\/vladpen\/python-rtsp-server\" rel=\"noopener noreferrer nofollow\">Github<\/a> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0447\u0435\u0440\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u0434\u0435\u0442\u0430\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u0430\u043c.<\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0432 \u0422\u0417 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432\u0438\u0434\u0435\u043e\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u0438 watchdog \u043a \u043d\u0435\u043c\u0443 \u2014 \u0432\u0441\u0435 \u044d\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 storage.py \u0438 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043e\u0431\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f.<\/p>\n<h2>\u0420\u0435\u0437\u044e\u043c\u0435<\/h2>\n<p>\u041f\u043e\u0445\u043e\u0436\u0435, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0432\u0441\u0435\u043c \u0437\u0430\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c. \u0412\u043e \u0432\u0441\u044f\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u044d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 \u0441\u0432\u043e\u0438\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u0445 \u0431\u0435\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043f\u0440\u0430\u0432\u0434\u0430, \u0432 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0435 \u0433\u043e\u0442\u043e\u0432 \u043a \u043f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u043e\u0439 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u0442\u044c \u043e\u0442\u043f\u0440\u0430\u0432\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0438 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u043c\u0430\u0441\u0441\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0442\u0435\u043c, \u043a\u0442\u043e \u0437\u0430\u0445\u043e\u0447\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u043d\u0430\u0434 \u0441\u0432\u043e\u0438\u043c\u0438 \u043a\u0430\u043c\u0435\u0440\u0430\u043c\u0438 \u0432\u0438\u0434\u0435\u043e\u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e\u043f\u0440\u043e\u0441\u044b, \u043f\u043e\u0436\u0435\u043b\u0430\u043d\u0438\u044f \u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u0430\u044f \u043a\u0440\u0438\u0442\u0438\u043a\u0430 \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442\u0441\u044f!<\/p>\n<\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/597363\/\"> https:\/\/habr.com\/ru\/post\/597363\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\" class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption>\u0420\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043a\u0430\u043c\u0435\u0440<\/figcaption><\/figure>\n<p>\u0423\u0434\u0438\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e \u0432 2021-\u043c \u0432\u0441\u0435 \u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u0438\u0437\u0431\u0438\u0442\u0443\u044e \u0442\u0435\u043c\u0443. \u041e\u0434\u043d\u0430\u043a\u043e, \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0439\u0442\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043b\u0438\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043e\u0442 \u043f\u043e\u043a\u0443\u043f\u043a\u0438 \u043e\u0445\u0440\u0430\u043d\u043d\u044b\u0445 \u043a\u0430\u043c\u0435\u0440 \u0434\u043e \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u043c\u043e\u0438, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u0445\u0438\u0442\u0440\u044b\u0435, \u0437\u0430\u0434\u0430\u0447\u0438. \u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0441\u043a\u0440\u0438\u043f\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043c\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0443\u0434\u0430\u0447\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f \u043a \u043d\u0435\u043c\u0443. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043a\u043e\u043c\u0443-\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442.<\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u0438:  \u043c\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u043b\u0438\u0441\u044c IP \u043a\u0430\u043c\u0435\u0440\u044b Rubetek RV-3414 \u0438 Hikvision DS-2CD2023. \u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043d\u0438\u043c \u0441 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u0438 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0436\u0435\u0441\u0442\u043a\u0438\u0439 \u0434\u0438\u0441\u043a. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u0438\u0434\u0435\u043e\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 \u0438 \u043c\u0435\u0434\u0438\u0430\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e Intel NUC \u043c\u043b\u0430\u0434\u0448\u0435\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0438\u0437-\u0437\u0430 \u043d\u0438\u0437\u043a\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u044f \u044d\u043d\u0435\u0440\u0433\u0438\u0438, \u0447\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0430\u0432\u0442\u043e\u043d\u043e\u043c\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041e\u0431\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 RTSP \u2013 Real Time Streaming Protocol. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u043e \u0432\u0441\u0435\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443.<\/p>\n<h2>\u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u0439<\/h2>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043a\u0430\u043c\u0435\u0440, &#8212; \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b \u0438\u0445 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043f\u0440\u0438\u043b\u0430\u0433\u0430\u0435\u043c\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c. \u0418 \u0442\u0443\u0442 \u043d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0438\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u043f\u043e\u043b\u043d\u043e\u0435 \u0441\u044e\u0440\u043f\u0440\u0438\u0437\u043e\u0432 \u0438 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043e\u0432.<\/p>\n<p>Rubetek \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b \u043f\u0440\u043e\u043f\u0440\u0438\u0435\u0442\u0430\u0440\u043d\u044b\u0439 \u0441\u043e\u0444\u0442 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0430 (\u0438 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0433\u043b\u044e\u0447\u0438\u0442). \u041d\u043e \u043f\u0440\u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043a \u043a\u0430\u043c\u0435\u0440\u0435 \u044d\u0442\u043e \u0447\u0443\u0434\u043e \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u043e\u0442\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e (\u0443 \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u043d\u0430 \u0410\u043d\u0434\u0440\u043e\u0438\u0434\u0435). \u041b\u0430\u0434\u043d\u043e, \u043d\u0435 \u0431\u043e\u043b\u044c\u043d\u043e \u0442\u043e \u0438 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c, \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043e\u043e\u043f\u0430\u0440\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u0443\u044e \u043a\u0430\u043c\u0435\u0440\u0443 \u044f \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0441\u044f. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e \u043d\u0430 \u0442\u0435\u043b\u0435\u0444\u043e\u043d VLC \u2014 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>Hikvision \u043f\u043e\u0440\u0430\u0434\u043e\u0432\u0430\u043b \u043c\u0435\u043d\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0442\u044c, \u0438 \u0443 \u043a\u0430\u043c\u0435\u0440\u044b \u0435\u0441\u0442\u044c \u0432\u0435\u0431 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \u0418\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 IP \u0430\u0434\u0440\u0435\u0441 \u0432 IE, Chrome \u0438\u043b\u0438 Firefox\u2019\u0435. \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u044e \u0432 Windows 11:<\/p>\n<figure class=\"full-width\"><figcaption>Windows 11, Edge \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 IE<\/figcaption><\/figure>\n<p>\u0422\u0440\u0435\u0431\u0443\u0435\u0442 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c Edge \u0434\u043e IE. \u0421\u043c\u0435\u0448\u043d\u043e. \u0412 11-\u0439, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u043c \u0434\u0430\u043d\u043d\u044b\u043c, \u043d\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c IE, \u0437\u0430\u0442\u043e \u0435\u0441\u0442\u044c \u0440\u0435\u0436\u0438\u043c IE (\u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0435). \u0412\u043a\u043b\u044e\u0447\u0430\u044e \u2014 \u043d\u0435 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f. Chrome, FF \u2014 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, Linux \u2014 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435. \u0412\u0435\u0441\u0435\u043b\u043e. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e Win 7 \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u043a\u0443, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e \u043a\u0430\u043c\u0435\u0440\u0443. \u0411\u0435\u0437 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u0432. \u0421\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0440\u0430\u0434\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u0430\u043c\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u044b \u0443 \u043c\u0435\u043d\u044f \u043f\u0440\u0435\u0442\u0435\u043d\u0437\u0438\u0439 \u043d\u0435\u0442.<\/p>\n<h2>\u0423\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f<\/h2>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0432\u0438\u0434\u0435\u043e\u043f\u043e\u0442\u043e\u043a\u043e\u0432. \u041c\u043e\u0438 \u043a\u0430\u043c\u0435\u0440\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a \u0440\u043e\u0443\u0442\u0435\u0440\u0443 \u0441 \u00ab\u0441\u0435\u0440\u044b\u043c\u00bb IP \u0430\u0434\u0440\u0435\u0441\u043e\u043c, \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0441\u044f \u0438\u0437\u0432\u043d\u0435 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u044d\u0442\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 (\u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u044f \u043f\u043e\u043a\u0443\u043f\u043a\u0438 IP) \u2014 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c SSH \u0442\u0443\u043d\u043d\u0435\u043b\u044c \u0434\u043e \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0441 \u00ab\u0431\u0435\u043b\u044b\u043c\u00bb IP:<\/p>\n<pre><code class=\"bash\">ssh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -R &lt;remote_port>:&lt;local_ip>:&lt;local_port> &lt;login>@&lt;remote_ip><\/code><\/pre>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438. \u0412\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430 &lt;remote_ip>:&lt;remote_port> \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0431\u0440\u043e\u0448\u0435\u043d\u044b \u043d\u0430 &lt;local_ip>:&lt;local_port>, \u0442.\u00a0\u0435. \u043d\u0430 \u043a\u0430\u043c\u0435\u0440\u0443. \u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441\u043b\u0443\u0448\u0430\u043b \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u0440\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u00abGatewayPorts yes\u00bb \u0432 sshd_config. \u042d\u0442\u043e \u043d\u0435 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e, \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a \u043d\u0435 \u043d\u0430\u0434\u043e. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043b\u043e\u0433\u0438\u043d\/\u043f\u0430\u0440\u043e\u043b\u044c \u043e\u0442  \u043a\u0430\u043c\u0435\u0440\u044b \u0432 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0433\u0443\u043b\u044f\u0435\u0442 \u043f\u043e \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443 \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0432\u0438\u0434\u0435 \u0438 \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d.<\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u044d\u0442\u043e\u0442 \u0441\u043b\u0443\u0447\u0430\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <a href=\"https:\/\/github.com\/aler9\/rtsp-simple-server\" rel=\"noopener noreferrer nofollow\">rtsp-simple-server<\/a>. \u041e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u043d\u0430 Go, \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u043c\u043e\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438. \u041d\u043e \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0434\u0435\u0442\u0430\u043b\u044f\u0445.<\/p>\n<h2>\u0422\u0435\u0445\u0437\u0430\u0434\u0430\u043d\u0438\u0435<\/h2>\n<p>\u041e\u043f\u044b\u0442, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430, \u043f\u043e\u043c\u043e\u0433 \u043c\u043d\u0435 \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0431\u0443\u0434\u0443\u0449\u0435\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0443.<\/p>\n<ul>\n<li>\n<p>\u041d\u0430\u0434\u0435\u0436\u043d\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438. \u041e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043a\u0430\u043c\u0435\u0440\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0436\u0435\u043b\u0435\u0437\u043e\u0431\u0435\u0442\u043e\u043d\u043d\u043e. \u041f\u043e \u043c\u043e\u0438\u043c \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f\u043c, \u043a\u0430\u043c\u0435\u0440\u044b \u0433\u043b\u044e\u0447\u0438\u0442 \u043f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 (\u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u2014 \u044d\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u2014 \u0434\u0432\u0443\u0445). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u043d\u0443\u0436\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043a\u0430\u0436\u0434\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u0435, \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0438\u0437\u043a\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043d\u0430 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440. \u0414\u043b\u044f \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0439 Intel NUC \u043d\u0430\u0447\u043d\u0435\u0442 \u0435\u0441\u0442\u044c \u0431\u0430\u0442\u0430\u0440\u0435\u044e \u0431\u0435\u0441\u043f\u0435\u0440\u0435\u0431\u043e\u0439\u043d\u0438\u043a\u0430 \u0438 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e \u0448\u0443\u0440\u0448\u0430\u0442\u044c \u043e\u0445\u043b\u0430\u0436\u0434\u0430\u044e\u0449\u0435\u0439 \u0442\u0443\u0440\u0431\u0438\u043d\u043a\u043e\u0439.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0441 IP \u043a\u0430\u043c\u0435\u0440 \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u043c\u0443 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438 \u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u0435\u0431 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0436\u0435\u0441\u0442\u043a\u0438\u0439 \u0434\u0438\u0441\u043a \u0441 \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u043e\u0439 \u043d\u0430 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b \u0438 \u0441\u0443\u0442\u043e\u0447\u043d\u043e\u0439 \u0440\u043e\u0442\u0430\u0446\u0438\u0435\u0439.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0441 \u043a\u0430\u043c\u0435\u0440\u0430\u043c\u0438 \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u043d\u0430 \u0434\u0438\u0441\u043a \u043f\u043e\u0441\u043b\u0435 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440. \u0420\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u0437-\u0437\u0430 \u043f\u0435\u0440\u0435\u0431\u043e\u044f \u043f\u0438\u0442\u0430\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043d\u0443\u0436\u043d\u043e  \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0443 \u0432\u0441\u0435, \u0422\u0417 \u0435\u0441\u0442\u044c, \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u044e \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<h2>\u0421\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445<\/h2>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0432\u0437\u0433\u043b\u044f\u043d\u0443\u0442\u044c, \u043a\u0430\u043a VLC \u043e\u0431\u0449\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u0430\u043c\u0435\u0440\u0430\u043c\u0438. \u0412\u043a\u043b\u044e\u0447\u0430\u044e Wireshark \u0441 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c tcp.port == 554 \u0438 \u0432\u0438\u0436\u0443:<\/p>\n<details class=\"spoiler\">\n<summary>Rubetek<\/summary>\n<div class=\"spoiler__content\">\n<p>Ask: OPTIONS rtsp:\/\/192.168.0.114:554\/onvif1 RTSP\/1.0<br \/> CSeq: 2<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 2<br \/> Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, GET_PARAMETER, SET_PARAMETER,USER_CMD_SET<\/p>\n<p>Ask: DESCRIBE rtsp:\/\/192.168.0.114:554\/onvif1 RTSP\/1.0<br \/> CSeq: 3<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Accept: application\/sdp<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 3<br \/> Content-Type: application\/sdp<br \/> Content-Length: 422<\/p>\n<p>v=0<br \/> o=- 1421069297525233 1 IN IP4 192.168.0.113<br \/> s=H.264 Video, RtspServer_0.0.0.2<br \/> t=0 0<br \/> a=tool:RtspServer_0.0.0.2<br \/> a=type:broadcast<br \/> a=control:*<br \/> a=range:npt=0-<br \/> m=video 0 RTP\/AVP 96<br \/> c=IN IP4 0.0.0.0<br \/> b=AS:500<br \/> a=rtpmap:96 H264\/90000<br \/> a=fmtp:96 packetization-mode=1;profile-level-id=42001F;sprop-parameter-sets=Z0IAH5WoFAFuQA==,aM48gA==<br \/> a=control:track1<br \/> m=audio 0 RTP\/AVP 8<br \/> a=control:track2<br \/> a=rtpmap:8 PCMA\/8000<\/p>\n<p>Ask: SETUP rtsp:\/\/192.168.0.114:554\/onvif1\/track1 RTSP\/1.0<br \/> CSeq: 4<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Transport: RTP\/AVP;unicast;client_port=45150-45151<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 4<br \/> Transport: RTP\/AVP;unicast;destination=192.168.0.165;source=192.168.0.113;client_port=45150-45151;server_port=7060-7061<br \/> Session: 7c2467db;timeout=60<\/p>\n<p>Ask: SETUP rtsp:\/\/192.168.0.114:554\/onvif1\/track2 RTSP\/1.0<br \/> CSeq: 5<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Transport: RTP\/AVP;unicast;client_port=35736-35737<br \/> Session: 7c2467db<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 5<br \/> Transport: RTP\/AVP;unicast;destination=192.168.0.165;source=192.168.0.113;client_port=35736-35737;server_port=7062-7063<br \/> Session: 7c2467db;timeout=60<\/p>\n<p>Ask: PLAY rtsp:\/\/192.168.0.114:554\/onvif1 RTSP\/1.0<br \/> CSeq: 6<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 7c2467db<br \/> Range: npt=0.000-<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 6<br \/> Range: npt=0.000-<br \/> Session: 7c2467db<br \/> RTP-Info: url=rtsp:192.168.0.113:554\/onvif1\/track1;seq=57651;rtptime=61388916750,url=rtsp:192.168.0.113:554\/onvif1\/track2;seq=58422;rtptime=5456792600<\/p>\n<p>*** \u0422\u0443\u0442 \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u0440\u0442 ***<\/p>\n<p>Ask: TEARDOWN rtsp:\/\/192.168.0.114:554\/onvif1 RTSP\/1.0<br \/> CSeq: 7<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 7c2467db<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>Hikvision<\/summary>\n<div class=\"spoiler__content\">\n<p>Ask: OPTIONS rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101 RTSP\/1.0<br \/> CSeq: 2<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 2<br \/> Public: OPTIONS, DESCRIBE, PLAY, PAUSE, SETUP, TEARDOWN, SET_PARAMETER, GET_PARAMETER<br \/> Date:  Mon, Nov 22 2021 09:57:17 GMT<\/p>\n<p>Ask: DESCRIBE rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101 RTSP\/1.0<br \/> CSeq: 3<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Accept: application\/sdp<\/p>\n<p>Reply: RTSP\/1.0 401 Unauthorized<br \/> CSeq: 3<br \/> WWW-Authenticate: Digest realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, stale=&#187;FALSE&#187;<br \/> Date:  Mon, Nov 22 2021 09:57:17 GMT<\/p>\n<p>Ask: DESCRIBE rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101 RTSP\/1.0<br \/> CSeq: 4<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101&#8243;, response=&#187;69ce13d857b38e6e68f7f5a4a85cd709&#8243;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Accept: application\/sdp<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 4<br \/> Content-Type: application\/sdp<br \/> Content-Base: rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/<br \/> Content-Length: 587<\/p>\n<p>v=0<br \/> o=- 1637575037561170 1637575037561170 IN IP4 192.168.0.110<br \/> s=Media Presentation<br \/> e=NONE<br \/> b=AS:5050<br \/> t=0 0<br \/> a=control:rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/<br \/> m=video 0 RTP\/AVP 96<br \/> c=IN IP4 0.0.0.0<br \/> b=AS:5000<br \/> a=recvonly<br \/> a=x-dimensions:1920,1080<br \/> a=control:rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/trackID=1<br \/> a=rtpmap:96 H265\/90000<br \/> a=fmtp:96 sprop-sps=QgEBAWAAAAMAsAAAAwAAAwB7oAPAgBDljb5JMvTcBAQEAg==; sprop-pps=RAHA8vA8kAA=<br \/> a=Media_header:MEDIAINFO=494D4B48010300000400050000000000000000000000000081000000000000000000000000000000;<br \/> a=appversion:1.0<\/p>\n<p>Ask: SETUP rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/trackID=1 RTSP\/1.0<br \/> CSeq: 5<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/&#187;, response=&#187;2341d81156d9cee08db0004835486f51&#8243;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Transport: RTP\/AVP;unicast;client_port=59446-59447<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 5<br \/> Session:        695167870;timeout=60<br \/> Transport: RTP\/AVP;unicast;client_port=59446-59447;server_port=8302-8303;ssrc=568ed713;mode=&#187;play&#187;<br \/> Date:  Mon, Nov 22 2021 09:57:17 GMT<\/p>\n<p>Ask: PLAY rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/ RTSP\/1.0<br \/> CSeq: 6<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/&#187;, response=&#187;a2a71ba4866e2f77d14f7368f368da5f&#187;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 695167870<br \/> Range: npt=0.000-<\/p>\n<p>Reply: RTSP\/1.0 200 OK<br \/> CSeq: 6<br \/> Session:        695167870<br \/> RTP-Info: url=rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/trackID=1;seq=54784;rtptime=2171307498<br \/> Date:  Mon, Nov 22 2021 09:57:17 GMT<\/p>\n<p>Ask: GET_PARAMETER rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/ RTSP\/1.0<br \/> CSeq: 7<br \/> Authorization: Digest username=&#187;login&#187;, realm=&#187;IP Camera(G2669)&#187;, nonce=&#187;17215f510ab5085c7aef996a1d42769f&#187;, uri=&#187;rtsp:\/\/192.168.0.110:554\/ISAPI\/Streaming\/Channels\/101\/&#187;, response=&#187;192d15433a0964eb2782026d8e908ed3&#8243;<br \/> User-Agent: LibVLC\/3.0.16 (LIVE555 Streaming Media v2021.08.24)<br \/> Session: 695167870<\/p>\n<p>Reply: RTSP\/1.0 <\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-327565","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/327565","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=327565"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/327565\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=327565"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=327565"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=327565"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}