# c4ipcam
Простая Python библиотека для передачи видео потока с камеры по сети с поддержкой аутентификации и сжатия. Позволяет легко создать сервер для трансляции видео с камеры и клиент для получения видео потока.
[](https://badge.fury.io/py/c4ipcam)
[](https://pypi.org/project/c4ipcam/)
[](https://github.com/rtcctc/c4ipcam/blob/main/LICENSE)
## Особенности
- Простая клиент-серверная архитектура
- Поддержка нескольких клиентов одновременно
- **Аутентификация по паролю** для безопасности
- **JPEG сжатие** для быстрой передачи данных
- **Настраиваемое разрешение** и качество видео
- Буферизация кадров для плавного воспроизведения
- Автоматическое переподключение и обработка ошибок
- Поддержка различных источников видео (веб-камера, IP-камера, видеофайлы)
- Многопоточная архитектура для оптимальной производительности
## Установка
```bash
pip install c4ipcam
```
Библиотека автоматически установит все необходимые зависимости, включая OpenCV.
## Быстрый старт
### Запуск сервера
```bash
# Запуск с параметрами по умолчанию (localhost:8000, камера 0)
c4ipcam
# Запуск с пользовательскими параметрами
c4ipcam --host 0.0.0.0 --port 9999 --camera 0
# Запуск с аутентификацией и настройками качества
c4ipcam --host 0.0.0.0 --port 9999 --password mypassword --width 1280 --height 720 --quality 85 --fps 25
```
### Подключение клиента
```python
from c4ipcam import CameraClient
import cv2
# Создание клиента
cap = CameraClient("localhost", 9999, password="mypassword")
# Подключение к серверу
if not cap.connect():
print("Ошибка подключения к серверу")
exit()
# Получение и отображение кадров
while cap.is_connected():
ret, frame = cap.read()
if not ret:
print("Ошибка получения кадра")
break
cv2.imshow('Camera Feed', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Освобождение ресурсов
cap.disconnect()
cv2.destroyAllWindows()
```
## API Documentation
### CameraServer
Класс для создания сервера, который транслирует видео поток с камеры.
#### Конструктор
```python
CameraServer(host='0.0.0.0', port=9999, camera_id=0, password="",
width=640, height=480, compression_quality=85, fps=30)
```
**Параметры:**
- `host` (str): IP-адрес для привязки сервера (по умолчанию '0.0.0.0')
- `port` (int): Порт для прослушивания (по умолчанию 9999)
- `camera_id` (int): ID камеры или путь к видеофайлу (по умолчанию 0)
- `password` (str): Пароль для аутентификации клиентов (по умолчанию пустой)
- `width` (int): Ширина кадра в пикселях (по умолчанию 640)
- `height` (int): Высота кадра в пикселях (по умолчанию 480)
- `compression_quality` (int): Качество JPEG сжатия 1-100% (по умолчанию 85)
- `fps` (int): Целевая частота кадров (по умолчанию 30)
#### Методы
##### `start_server()`
Запускает сервер и начинает трансляцию видео потока.
```python
server = CameraServer(password="mypass", width=1280, height=720)
server.start_server() # Блокирующий вызов
```
##### `cleanup()`
Освобождает ресурсы и останавливает сервер.
```python
server.cleanup()
```
### CameraClient
Класс для подключения к серверу и получения видео потока.
#### Конструктор
```python
CameraClient(server_host, server_port, password="", compression_quality=85)
```
**Параметры:**
- `server_host` (str): IP-адрес сервера
- `server_port` (int): Порт сервера
- `password` (str): Пароль для аутентификации (по умолчанию пустой)
- `compression_quality` (int): Качество сжатия для передачи (по умолчанию 85)
#### Методы
##### `connect()`
Устанавливает соединение с сервером и проходит аутентификацию.
**Возвращает:** `bool` - True при успешном подключении, False при ошибке
```python
client = CameraClient("192.168.1.100", 9999, password="mypass")
if client.connect():
print("Успешно подключен!")
else:
print("Ошибка подключения:", client.get_connection_error())
```
##### `read(timeout=None)`
Получает следующий кадр из очереди.
**Параметры:**
- `timeout` (float, optional): Максимальное время ожидания кадра в секундах
**Возвращает:** `[bool, numpy.ndarray]` - статус и кадр
```python
ret, frame = client.read(timeout=1.0)
if ret:
cv2.imshow('Frame', frame)
```
##### `get_latest_frame()`
Возвращает последний полученный кадр без удаления из очереди.
**Возвращает:** `numpy.ndarray` или `None`
```python
frame = client.get_latest_frame()
if frame is not None:
cv2.imshow('Latest Frame', frame)
```
##### `is_connected()`
Проверяет статус соединения.
**Возвращает:** `bool`
```python
if client.is_connected():
print("Соединение активно")
```
##### `get_connection_error()`
Возвращает последнюю ошибку соединения.
**Возвращает:** `str` или `None`
```python
error = client.get_connection_error()
if error:
print(f"Ошибка: {error}")
```
##### `disconnect()`
Закрывает соединение и освобождает ресурсы.
```python
client.disconnect()
```
##### `cleanup()`
Альтернативный метод для освобождения ресурсов.
```python
client.cleanup()
```
## Примеры использования
### Запуск сервера
Основной способ запуска сервера - через консольную команду:
```bash
# Базовый запуск с веб-камерой
c4ipcam
# Настройка хоста и порта
c4ipcam --host 0.0.0.0 --port 9999
# Использование конкретной камеры
c4ipcam --camera 1
# Полная настройка с аутентификацией
c4ipcam --host 0.0.0.0 --port 9999 --password secure123 --width 1920 --height 1080 --quality 90 --fps 15
```
**Параметры командной строки:**
- `--host` - IP-адрес сервера (по умолчанию localhost)
- `--port` - Порт сервера (по умолчанию 8000)
- `--camera` - ID камеры (по умолчанию 0)
- `--password` - Пароль для аутентификации (по умолчанию пустой)
- `--width` - Ширина кадра в пикселях (по умолчанию 640)
- `--height` - Высота кадра в пикселях (по умолчанию 480)
- `--quality` - Качество JPEG сжатия 1-100% (по умолчанию 85)
- `--fps` - Целевая частота кадров (по умолчанию 30)
### Клиент с обработкой ошибок
```python
from c4ipcam import CameraClient
import cv2
import time
def main():
client = CameraClient("localhost", 9999, password="secure123")
# Попытка подключения с повторами
max_retries = 5
for attempt in range(max_retries):
if client.connect():
print("Успешно подключен к серверу")
break
else:
print(f"Попытка {attempt + 1}/{max_retries} не удалась: {client.get_connection_error()}")
if attempt < max_retries - 1:
time.sleep(2)
else:
print("Не удалось подключиться к серверу")
return
try:
while client.is_connected():
ret, frame = client.read(timeout=1.0)
if not ret:
print("Таймаут или ошибка получения кадра")
continue
# Обработка кадра
cv2.imshow('Camera Feed', frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
elif key == ord('s'):
# Сохранение кадра
cv2.imwrite(f'frame_{int(time.time())}.jpg', frame)
print("Кадр сохранен")
except KeyboardInterrupt:
print("Прерывание пользователем")
finally:
client.disconnect()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
```
### Программное использование сервера (опционально)
Если нужно интегрировать сервер в другое приложение:
```python
from c4ipcam import CameraServer
server = CameraServer(
host='0.0.0.0',
port=9999,
camera_id=0,
password="secure123",
width=1280,
height=720,
compression_quality=85,
fps=25
)
try:
server.start_server()
except KeyboardInterrupt:
server.cleanup()
```
### Настройки для разных сценариев
```python
# Высокое качество для анализа
hq_client = CameraClient("server_ip", 9999, password="pass", compression_quality=95)
# Быстрая передача для превью
fast_client = CameraClient("server_ip", 9999, password="pass", compression_quality=60)
```
## Устранение неполадок
### Сервер не запускается
1. Проверьте, что порт не занят другим приложением
2. Убедитесь, что камера доступна и не используется другим приложением
3. Проверьте права доступа к камере
4. Убедитесь, что указанное разрешение поддерживается камерой
### Клиент не может подключиться
1. Убедитесь, что сервер запущен и прослушивает правильный порт
2. Проверьте правильность пароля (если используется аутентификация)
3. Проверьте сетевое соединение между клиентом и сервером
4. Убедитесь, что брандмауэр не блокирует соединение
### Низкое качество или задержка видео
1. Уменьшите разрешение камеры на сервере (`--width`, `--height`)
2. Снизьте качество сжатия (`--quality`)
3. Уменьшите частоту кадров (`--fps`)
4. Увеличьте размер буфера на клиенте
5. Используйте более быстрое сетевое соединение
### Ошибки при получении кадров
1. Проверьте стабильность сетевого соединения
2. Увеличьте таймаут при чтении кадров
3. Добавьте логику переподключения в клиенте
4. Проверьте правильность аутентификации
### Ошибки аутентификации
1. Убедитесь, что пароль указан правильно на сервере и клиенте
2. Проверьте, что пароли совпадают точно (учитывается регистр)
3. Если пароль не нужен, оставьте поле пустым на обеих сторонах
## Зависимости
- Python 3.6+
- opencv-python>=4.11.0.86 (автоматически устанавливается)
- numpy>=1.21.0 (автоматически устанавливается)
Все зависимости устанавливаются автоматически при установке библиотеки через pip.
## Лицензия
Этот проект распространяется под лицензией MIT.
## Поддержка
- **GitHub**: [https://github.com/rtcctc/c4ipcam](https://github.com/rtcctc/c4ipcam)
- **PyPI**: [https://pypi.org/project/c4ipcam/](https://pypi.org/project/c4ipcam/)
- **Автор**: 4edbark (vangogprogprog@gmail.com)
При возникновении вопросов или проблем создайте issue в репозитории проекта на GitHub.
Raw data
{
"_id": null,
"home_page": "https://github.com/rtcctc/c4ipcam",
"name": "c4ipcam",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "opencv, ip camera, streaming, video, computer vision, authentication",
"author": "4edbark",
"author_email": "vangogprogprog@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/3f/f5/f24a066a960d48e397c1d27ccbb82af72532ee643af19b8a3c4798aadf69/c4ipcam-0.0.2.tar.gz",
"platform": null,
"description": "# c4ipcam\r\n\r\n\u041f\u0440\u043e\u0441\u0442\u0430\u044f Python \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a\u0430 \u0441 \u043a\u0430\u043c\u0435\u0440\u044b \u043f\u043e \u0441\u0435\u0442\u0438 \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u0441\u0436\u0430\u0442\u0438\u044f. \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043b\u0435\u0433\u043a\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438 \u0432\u0438\u0434\u0435\u043e \u0441 \u043a\u0430\u043c\u0435\u0440\u044b \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a\u0430.\r\n\r\n[](https://badge.fury.io/py/c4ipcam)\r\n[](https://pypi.org/project/c4ipcam/)\r\n[](https://github.com/rtcctc/c4ipcam/blob/main/LICENSE)\r\n\r\n## \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438\r\n\r\n- \u041f\u0440\u043e\u0441\u0442\u0430\u044f \u043a\u043b\u0438\u0435\u043d\u0442-\u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430\r\n- \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\r\n- **\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e \u043f\u0430\u0440\u043e\u043b\u044e** \u0434\u043b\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438\r\n- **JPEG \u0441\u0436\u0430\u0442\u0438\u0435** \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445\r\n- **\u041d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435** \u0438 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u0438\u0434\u0435\u043e\r\n- \u0411\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u0430\u0434\u0440\u043e\u0432 \u0434\u043b\u044f \u043f\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f\r\n- \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a\r\n- \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0432\u0438\u0434\u0435\u043e (\u0432\u0435\u0431-\u043a\u0430\u043c\u0435\u0440\u0430, IP-\u043a\u0430\u043c\u0435\u0440\u0430, \u0432\u0438\u0434\u0435\u043e\u0444\u0430\u0439\u043b\u044b)\r\n- \u041c\u043d\u043e\u0433\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u0430\u044f \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0434\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438\r\n\r\n## \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430\r\n\r\n```bash\r\npip install c4ipcam\r\n```\r\n\r\n\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f OpenCV.\r\n\r\n## \u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u0441\u0442\u0430\u0440\u0442\r\n\r\n### \u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430\r\n\r\n```bash\r\n# \u0417\u0430\u043f\u0443\u0441\u043a \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (localhost:8000, \u043a\u0430\u043c\u0435\u0440\u0430 0)\r\nc4ipcam\r\n\r\n# \u0417\u0430\u043f\u0443\u0441\u043a \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438\r\nc4ipcam --host 0.0.0.0 --port 9999 --camera 0\r\n\r\n# \u0417\u0430\u043f\u0443\u0441\u043a \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430\r\nc4ipcam --host 0.0.0.0 --port 9999 --password mypassword --width 1280 --height 720 --quality 85 --fps 25\r\n```\r\n\r\n### \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\r\n\r\n```python\r\nfrom c4ipcam import CameraClient\r\nimport cv2\r\n\r\n# \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\r\ncap = CameraClient(\"localhost\", 9999, password=\"mypassword\")\r\n\r\n# \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443\r\nif not cap.connect():\r\n print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443\")\r\n exit()\r\n\r\n# \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u0434\u0440\u043e\u0432\r\nwhile cap.is_connected():\r\n ret, frame = cap.read()\r\n \r\n if not ret:\r\n print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u0430\u0434\u0440\u0430\")\r\n break\r\n \r\n cv2.imshow('Camera Feed', frame)\r\n \r\n if cv2.waitKey(1) & 0xFF == ord('q'):\r\n break\r\n\r\n# \u041e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432\r\ncap.disconnect()\r\ncv2.destroyAllWindows()\r\n```\r\n\r\n## API Documentation\r\n\r\n### CameraServer\r\n\r\n\u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0440\u0443\u0435\u0442 \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a \u0441 \u043a\u0430\u043c\u0435\u0440\u044b.\r\n\r\n#### \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\r\n\r\n```python\r\nCameraServer(host='0.0.0.0', port=9999, camera_id=0, password=\"\", \r\n width=640, height=480, compression_quality=85, fps=30)\r\n```\r\n\r\n**\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:**\r\n- `host` (str): IP-\u0430\u0434\u0440\u0435\u0441 \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e '0.0.0.0')\r\n- `port` (int): \u041f\u043e\u0440\u0442 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u043d\u0438\u044f (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 9999)\r\n- `camera_id` (int): ID \u043a\u0430\u043c\u0435\u0440\u044b \u0438\u043b\u0438 \u043f\u0443\u0442\u044c \u043a \u0432\u0438\u0434\u0435\u043e\u0444\u0430\u0439\u043b\u0443 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 0)\r\n- `password` (str): \u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0443\u0441\u0442\u043e\u0439)\r\n- `width` (int): \u0428\u0438\u0440\u0438\u043d\u0430 \u043a\u0430\u0434\u0440\u0430 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 640)\r\n- `height` (int): \u0412\u044b\u0441\u043e\u0442\u0430 \u043a\u0430\u0434\u0440\u0430 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 480)\r\n- `compression_quality` (int): \u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e JPEG \u0441\u0436\u0430\u0442\u0438\u044f 1-100% (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 85)\r\n- `fps` (int): \u0426\u0435\u043b\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u043a\u0430\u0434\u0440\u043e\u0432 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 30)\r\n\r\n#### \u041c\u0435\u0442\u043e\u0434\u044b\r\n\r\n##### `start_server()`\r\n\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u044e \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a\u0430.\r\n\r\n```python\r\nserver = CameraServer(password=\"mypass\", width=1280, height=720)\r\nserver.start_server() # \u0411\u043b\u043e\u043a\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0432\u044b\u0437\u043e\u0432\r\n```\r\n\r\n##### `cleanup()`\r\n\u041e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u0438 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440.\r\n\r\n```python\r\nserver.cleanup()\r\n```\r\n\r\n### CameraClient\r\n\r\n\u041a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0435\u043e \u043f\u043e\u0442\u043e\u043a\u0430.\r\n\r\n#### \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\r\n\r\n```python\r\nCameraClient(server_host, server_port, password=\"\", compression_quality=85)\r\n```\r\n\r\n**\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:**\r\n- `server_host` (str): IP-\u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\r\n- `server_port` (int): \u041f\u043e\u0440\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430\r\n- `password` (str): \u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0443\u0441\u0442\u043e\u0439)\r\n- `compression_quality` (int): \u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0436\u0430\u0442\u0438\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 85)\r\n\r\n#### \u041c\u0435\u0442\u043e\u0434\u044b\r\n\r\n##### `connect()`\r\n\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0438 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e.\r\n\r\n**\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442:** `bool` - True \u043f\u0440\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, False \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435\r\n\r\n```python\r\nclient = CameraClient(\"192.168.1.100\", 9999, password=\"mypass\")\r\nif client.connect():\r\n print(\"\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d!\")\r\nelse:\r\n print(\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f:\", client.get_connection_error())\r\n```\r\n\r\n##### `read(timeout=None)`\r\n\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u0430\u0434\u0440 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.\r\n\r\n**\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:**\r\n- `timeout` (float, optional): \u041c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043a\u0430\u0434\u0440\u0430 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445\r\n\r\n**\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442:** `[bool, numpy.ndarray]` - \u0441\u0442\u0430\u0442\u0443\u0441 \u0438 \u043a\u0430\u0434\u0440\r\n\r\n```python\r\nret, frame = client.read(timeout=1.0)\r\nif ret:\r\n cv2.imshow('Frame', frame)\r\n```\r\n\r\n##### `get_latest_frame()`\r\n\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u0430\u0434\u0440 \u0431\u0435\u0437 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438.\r\n\r\n**\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442:** `numpy.ndarray` \u0438\u043b\u0438 `None`\r\n\r\n```python\r\nframe = client.get_latest_frame()\r\nif frame is not None:\r\n cv2.imshow('Latest Frame', frame)\r\n```\r\n\r\n##### `is_connected()`\r\n\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0442\u0430\u0442\u0443\u0441 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.\r\n\r\n**\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442:** `bool`\r\n\r\n```python\r\nif client.is_connected():\r\n print(\"\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\")\r\n```\r\n\r\n##### `get_connection_error()`\r\n\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043e\u0448\u0438\u0431\u043a\u0443 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.\r\n\r\n**\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442:** `str` \u0438\u043b\u0438 `None`\r\n\r\n```python\r\nerror = client.get_connection_error()\r\nif error:\r\n print(f\"\u041e\u0448\u0438\u0431\u043a\u0430: {error}\")\r\n```\r\n\r\n##### `disconnect()`\r\n\u0417\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0435\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u044b.\r\n\r\n```python\r\nclient.disconnect()\r\n```\r\n\r\n##### `cleanup()`\r\n\u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.\r\n\r\n```python\r\nclient.cleanup()\r\n```\r\n\r\n## \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f\r\n\r\n### \u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430\r\n\r\n\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 - \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443:\r\n\r\n```bash\r\n# \u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441 \u0432\u0435\u0431-\u043a\u0430\u043c\u0435\u0440\u043e\u0439\r\nc4ipcam\r\n\r\n# \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0445\u043e\u0441\u0442\u0430 \u0438 \u043f\u043e\u0440\u0442\u0430\r\nc4ipcam --host 0.0.0.0 --port 9999\r\n\r\n# \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043a\u0430\u043c\u0435\u0440\u044b\r\nc4ipcam --camera 1\r\n\r\n# \u041f\u043e\u043b\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439\r\nc4ipcam --host 0.0.0.0 --port 9999 --password secure123 --width 1920 --height 1080 --quality 90 --fps 15\r\n```\r\n\r\n**\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438:**\r\n- `--host` - IP-\u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e localhost)\r\n- `--port` - \u041f\u043e\u0440\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 8000)\r\n- `--camera` - ID \u043a\u0430\u043c\u0435\u0440\u044b (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 0)\r\n- `--password` - \u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0443\u0441\u0442\u043e\u0439)\r\n- `--width` - \u0428\u0438\u0440\u0438\u043d\u0430 \u043a\u0430\u0434\u0440\u0430 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 640)\r\n- `--height` - \u0412\u044b\u0441\u043e\u0442\u0430 \u043a\u0430\u0434\u0440\u0430 \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 480)\r\n- `--quality` - \u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e JPEG \u0441\u0436\u0430\u0442\u0438\u044f 1-100% (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 85)\r\n- `--fps` - \u0426\u0435\u043b\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u043e\u0442\u0430 \u043a\u0430\u0434\u0440\u043e\u0432 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 30)\r\n\r\n### \u041a\u043b\u0438\u0435\u043d\u0442 \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043e\u043a\r\n\r\n```python\r\nfrom c4ipcam import CameraClient\r\nimport cv2\r\nimport time\r\n\r\ndef main():\r\n client = CameraClient(\"localhost\", 9999, password=\"secure123\")\r\n \r\n # \u041f\u043e\u043f\u044b\u0442\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u0432\u0442\u043e\u0440\u0430\u043c\u0438\r\n max_retries = 5\r\n for attempt in range(max_retries):\r\n if client.connect():\r\n print(\"\u0423\u0441\u043f\u0435\u0448\u043d\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443\")\r\n break\r\n else:\r\n print(f\"\u041f\u043e\u043f\u044b\u0442\u043a\u0430 {attempt + 1}/{max_retries} \u043d\u0435 \u0443\u0434\u0430\u043b\u0430\u0441\u044c: {client.get_connection_error()}\")\r\n if attempt < max_retries - 1:\r\n time.sleep(2)\r\n else:\r\n print(\"\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443\")\r\n return\r\n \r\n try:\r\n while client.is_connected():\r\n ret, frame = client.read(timeout=1.0)\r\n \r\n if not ret:\r\n print(\"\u0422\u0430\u0439\u043c\u0430\u0443\u0442 \u0438\u043b\u0438 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u0430\u0434\u0440\u0430\")\r\n continue\r\n \r\n # \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043a\u0430\u0434\u0440\u0430\r\n cv2.imshow('Camera Feed', frame)\r\n \r\n key = cv2.waitKey(1) & 0xFF\r\n if key == ord('q'):\r\n break\r\n elif key == ord('s'):\r\n # \u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043a\u0430\u0434\u0440\u0430\r\n cv2.imwrite(f'frame_{int(time.time())}.jpg', frame)\r\n print(\"\u041a\u0430\u0434\u0440 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\")\r\n \r\n except KeyboardInterrupt:\r\n print(\"\u041f\u0440\u0435\u0440\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c\")\r\n finally:\r\n client.disconnect()\r\n cv2.destroyAllWindows()\r\n\r\nif __name__ == \"__main__\":\r\n main()\r\n```\r\n\r\n### \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e)\r\n\r\n\u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:\r\n\r\n```python\r\nfrom c4ipcam import CameraServer\r\n\r\nserver = CameraServer(\r\n host='0.0.0.0', \r\n port=9999, \r\n camera_id=0,\r\n password=\"secure123\",\r\n width=1280,\r\n height=720,\r\n compression_quality=85,\r\n fps=25\r\n)\r\ntry:\r\n server.start_server()\r\nexcept KeyboardInterrupt:\r\n server.cleanup()\r\n```\r\n\r\n### \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432\r\n\r\n```python\r\n# \u0412\u044b\u0441\u043e\u043a\u043e\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430\r\nhq_client = CameraClient(\"server_ip\", 9999, password=\"pass\", compression_quality=95)\r\n\r\n# \u0411\u044b\u0441\u0442\u0440\u0430\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u043f\u0440\u0435\u0432\u044c\u044e\r\nfast_client = CameraClient(\"server_ip\", 9999, password=\"pass\", compression_quality=60)\r\n```\r\n\r\n## \u0423\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u043f\u043e\u043b\u0430\u0434\u043e\u043a\r\n\r\n### \u0421\u0435\u0440\u0432\u0435\u0440 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f\r\n\r\n1. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0447\u0442\u043e \u043f\u043e\u0440\u0442 \u043d\u0435 \u0437\u0430\u043d\u044f\u0442 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c\r\n2. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u043a\u0430\u043c\u0435\u0440\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0438 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c\r\n3. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u0440\u0430\u0432\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043a\u0430\u043c\u0435\u0440\u0435\r\n4. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043c\u0435\u0440\u043e\u0439\r\n\r\n### \u041a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f\r\n\r\n1. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440 \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0438 \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0440\u0442\r\n2. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044f (\u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f)\r\n3. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c\r\n4. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0431\u0440\u0430\u043d\u0434\u043c\u0430\u0443\u044d\u0440 \u043d\u0435 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435\r\n\r\n### \u041d\u0438\u0437\u043a\u043e\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u043b\u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0432\u0438\u0434\u0435\u043e\r\n\r\n1. \u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (`--width`, `--height`)\r\n2. \u0421\u043d\u0438\u0437\u044c\u0442\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u043e \u0441\u0436\u0430\u0442\u0438\u044f (`--quality`)\r\n3. \u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u0435 \u0447\u0430\u0441\u0442\u043e\u0442\u0443 \u043a\u0430\u0434\u0440\u043e\u0432 (`--fps`)\r\n4. \u0423\u0432\u0435\u043b\u0438\u0447\u044c\u0442\u0435 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0444\u0435\u0440\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435\r\n5. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435\r\n\r\n### \u041e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043a\u0430\u0434\u0440\u043e\u0432\r\n\r\n1. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f\r\n2. \u0423\u0432\u0435\u043b\u0438\u0447\u044c\u0442\u0435 \u0442\u0430\u0439\u043c\u0430\u0443\u0442 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u043a\u0430\u0434\u0440\u043e\u0432\r\n3. \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u0435\u0440\u0435\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0435\r\n4. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438\r\n\r\n### \u041e\u0448\u0438\u0431\u043a\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438\r\n\r\n1. \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u043f\u0430\u0440\u043e\u043b\u044c \u0443\u043a\u0430\u0437\u0430\u043d \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0435\r\n2. \u041f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435, \u0447\u0442\u043e \u043f\u0430\u0440\u043e\u043b\u0438 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 \u0442\u043e\u0447\u043d\u043e (\u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0433\u0438\u0441\u0442\u0440)\r\n3. \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043e\u043b\u0435 \u043f\u0443\u0441\u0442\u044b\u043c \u043d\u0430 \u043e\u0431\u0435\u0438\u0445 \u0441\u0442\u043e\u0440\u043e\u043d\u0430\u0445\r\n\r\n## \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438\r\n\r\n- Python 3.6+\r\n- opencv-python>=4.11.0.86 (\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f)\r\n- numpy>=1.21.0 (\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f)\r\n\r\n\u0412\u0441\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 pip.\r\n\r\n## \u041b\u0438\u0446\u0435\u043d\u0437\u0438\u044f\r\n\r\n\u042d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u0441\u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0435\u0439 MIT.\r\n\r\n## \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430\r\n\r\n- **GitHub**: [https://github.com/rtcctc/c4ipcam](https://github.com/rtcctc/c4ipcam)\r\n- **PyPI**: [https://pypi.org/project/c4ipcam/](https://pypi.org/project/c4ipcam/)\r\n- **\u0410\u0432\u0442\u043e\u0440**: 4edbark (vangogprogprog@gmail.com)\r\n\r\n\u041f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u0432 \u0438\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 issue \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 GitHub.\r\n",
"bugtrack_url": null,
"license": null,
"summary": "Simple IP camera streaming module with authentication and compression for OpenCV applications.",
"version": "0.0.2",
"project_urls": {
"Bug Reports": "https://github.com/rtcctc/c4ipcam/issues",
"Documentation": "https://github.com/rtcctc/c4ipcam#readme",
"GitHub": "https://github.com/rtcctc/c4ipcam",
"Homepage": "https://github.com/rtcctc/c4ipcam"
},
"split_keywords": [
"opencv",
" ip camera",
" streaming",
" video",
" computer vision",
" authentication"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "2ce5f055f0d86d075a14394d7dbdbc3bbfa5f242fad8e50b3efb5078d4f5c5b5",
"md5": "557b5feed6b69e3c6fb6efac4f679c29",
"sha256": "2de0feac9cc6eaa9b8787ff9dd130d00fc2670a019572bbf4ea176c83a0e15d2"
},
"downloads": -1,
"filename": "c4ipcam-0.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "557b5feed6b69e3c6fb6efac4f679c29",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 10763,
"upload_time": "2025-08-06T06:26:41",
"upload_time_iso_8601": "2025-08-06T06:26:41.015362Z",
"url": "https://files.pythonhosted.org/packages/2c/e5/f055f0d86d075a14394d7dbdbc3bbfa5f242fad8e50b3efb5078d4f5c5b5/c4ipcam-0.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "3ff5f24a066a960d48e397c1d27ccbb82af72532ee643af19b8a3c4798aadf69",
"md5": "8a63b81ac6025bf7176365604e3de842",
"sha256": "c4835b789355c83d21c669d8407dfc015140b0afb4557ff499307897809503e0"
},
"downloads": -1,
"filename": "c4ipcam-0.0.2.tar.gz",
"has_sig": false,
"md5_digest": "8a63b81ac6025bf7176365604e3de842",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 14453,
"upload_time": "2025-08-06T06:26:42",
"upload_time_iso_8601": "2025-08-06T06:26:42.342895Z",
"url": "https://files.pythonhosted.org/packages/3f/f5/f24a066a960d48e397c1d27ccbb82af72532ee643af19b8a3c4798aadf69/c4ipcam-0.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-06 06:26:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rtcctc",
"github_project": "c4ipcam",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "c4ipcam"
}