netprotomvds 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,38 @@
1
+ Metadata-Version: 2.4
2
+ Name: netprotomvds
3
+ Version: 0.1.0
4
+ Summary: Network Protocol Multithreaded Video Data Share: быстрая передача видео по UDP.
5
+ Author-email: CharmLxt <reception.mailspypi@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/CharmLxt/netprotomvds
8
+ Project-URL: Source, https://github.com/CharmLxt/netprotomvds
9
+ Project-URL: Tracker, https://github.com/CharmLxt/netprotomvds/issues
10
+ Keywords: udp,video,streaming,networking,multithreading
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Multimedia :: Video
15
+ Classifier: Topic :: System :: Networking
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: numpy>=1.21.0
19
+ Requires-Dist: 9was9>=0.2.0
20
+
21
+ netprotomvds. Версия 0.1.0. Автор CharmLxt (PyPI: CharmLxt, email: reception.mailspypi@gmail.com). Ссылка на GitHub: https://github.com/CharmLxt/netprotomvds.
22
+
23
+
24
+
25
+ netprotomvds (Network Protocol Multithreaded Video Data Share) — это специализированная библиотека для сверхбыстрой передачи видеопотока или изображений по сети с использованием протокола UDP. Она создавалась специально для проекта Monogrammer, но может использоваться в любых задачах, где нужна трансляция экрана или видеозвонки (например, удаленный рабочий стол, стриминг игр или камеры).
26
+
27
+
28
+
29
+ В основе библиотеки лежит идея, что для видео надежность TCP не так важна, как скорость. Если один пакет с частью картинки потерялся в сети, мы просто отбрасываем весь этот кадр и показываем следующий. Из-за этого нет задержек на повторную отправку (как в TCP), и картинка движется максимально плавно. Библиотека автоматически нарезает большие кадры на маленькие пакеты, подходящие под размер MTU, отправляет их и собирает обратно на другом конце.
30
+
31
+
32
+
33
+ В версии 0.1.0 реализован базовый каркас. Модуль packet отвечает за нарезку и склейку данных с порядковыми номерами. VideoServer и VideoClient используют многопоточность (модуль threading) для фоновой отправки и приема, чтобы не блокировать основной интерфейс программы. Для сжатия данных используется стандартный zlib (чтобы не тащить тяжелые зависимости, но в будущем мы добавим JPEG через C#-мост Sowanna). Также встроен Jitter Buffer, который сглаживает неровности сети, храня пару последних кадров.
34
+
35
+
36
+
37
+ Установка: pip install netprotomvds. Зависимости: numpy и 9was9 (для быстрой математики, если понадобится обработка изображений). Библиотека кроссплатформенная, работает везде, где есть сокеты и Python 3.8+. Связь с автором: reception.mailspypi@gmail.com.
38
+
@@ -0,0 +1,18 @@
1
+ netprotomvds. Версия 0.1.0. Автор CharmLxt (PyPI: CharmLxt, email: reception.mailspypi@gmail.com). Ссылка на GitHub: https://github.com/CharmLxt/netprotomvds.
2
+
3
+
4
+
5
+ netprotomvds (Network Protocol Multithreaded Video Data Share) — это специализированная библиотека для сверхбыстрой передачи видеопотока или изображений по сети с использованием протокола UDP. Она создавалась специально для проекта Monogrammer, но может использоваться в любых задачах, где нужна трансляция экрана или видеозвонки (например, удаленный рабочий стол, стриминг игр или камеры).
6
+
7
+
8
+
9
+ В основе библиотеки лежит идея, что для видео надежность TCP не так важна, как скорость. Если один пакет с частью картинки потерялся в сети, мы просто отбрасываем весь этот кадр и показываем следующий. Из-за этого нет задержек на повторную отправку (как в TCP), и картинка движется максимально плавно. Библиотека автоматически нарезает большие кадры на маленькие пакеты, подходящие под размер MTU, отправляет их и собирает обратно на другом конце.
10
+
11
+
12
+
13
+ В версии 0.1.0 реализован базовый каркас. Модуль packet отвечает за нарезку и склейку данных с порядковыми номерами. VideoServer и VideoClient используют многопоточность (модуль threading) для фоновой отправки и приема, чтобы не блокировать основной интерфейс программы. Для сжатия данных используется стандартный zlib (чтобы не тащить тяжелые зависимости, но в будущем мы добавим JPEG через C#-мост Sowanna). Также встроен Jitter Buffer, который сглаживает неровности сети, храня пару последних кадров.
14
+
15
+
16
+
17
+ Установка: pip install netprotomvds. Зависимости: numpy и 9was9 (для быстрой математики, если понадобится обработка изображений). Библиотека кроссплатформенная, работает везде, где есть сокеты и Python 3.8+. Связь с автором: reception.mailspypi@gmail.com.
18
+
@@ -0,0 +1,11 @@
1
+ """netprotomvds — быстрая передача видео по UDP."""
2
+ from .version import __version__
3
+ from .packet import split_frame, reassemble_frame
4
+ from .server import VideoServer
5
+ from .client import VideoClient
6
+
7
+ __all__ = [
8
+ "__version__",
9
+ "split_frame", "reassemble_frame",
10
+ "VideoServer", "VideoClient",
11
+ ]
@@ -0,0 +1,76 @@
1
+ """Клиентская часть (Контроллер). Принимает кадры."""
2
+ import socket
3
+ import struct
4
+ import threading
5
+ import queue
6
+ import time
7
+ from .packet import reassemble_frame, HEADER_FORMAT, HEADER_SIZE
8
+
9
+ class VideoClient:
10
+ def __init__(self, server_ip, server_port=8081, buffer_size=3):
11
+ self.server_addr = (server_ip, server_port)
12
+ self.buffer_size = buffer_size
13
+
14
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
15
+ self.sock.bind(("0.0.0.0", 0)) # Слушаем на случайном порту
16
+
17
+ self._running = False
18
+ self._thread = None
19
+ self._recv_queue = queue.Queue()
20
+ self._frame_buffer = []
21
+ self._lock = threading.Lock()
22
+
23
+ def start(self):
24
+ self._running = True
25
+ self._thread = threading.Thread(target=self._listen_loop, daemon=True)
26
+ self._thread.start()
27
+ print(f"[VideoClient] Слушаю {self.server_addr}...")
28
+
29
+ def stop(self):
30
+ self._running = False
31
+ if self._thread:
32
+ self._thread.join(timeout=1.0)
33
+ self.sock.close()
34
+
35
+ def _listen_loop(self):
36
+ current_frame_id = None
37
+ current_packets = []
38
+ expected_chunks = 0
39
+
40
+ while self._running:
41
+ try:
42
+ data, addr = self.sock.recvfrom(2048)
43
+ if len(data) < HEADER_SIZE:
44
+ continue
45
+
46
+ frame_id, total_chunks, chunk_idx = struct.unpack(HEADER_FORMAT, data[:HEADER_SIZE])
47
+
48
+ # Если пришел новый кадр — сбрасываем старый (потеряли кусок)
49
+ if current_frame_id != frame_id:
50
+ current_frame_id = frame_id
51
+ current_packets = [None] * total_chunks
52
+ expected_chunks = total_chunks
53
+
54
+ current_packets[chunk_idx] = data
55
+
56
+ # Если собрали все чанки
57
+ if all(p is not None for p in current_packets):
58
+ frame_data = reassemble_frame(current_packets)
59
+
60
+ with self._lock:
61
+ self._frame_buffer.append(frame_data)
62
+ if len(self._frame_buffer) > self.buffer_size:
63
+ self._frame_buffer.pop(0) # Удаляем старый (Jitter Buffer)
64
+
65
+ current_frame_id = None
66
+ current_packets = []
67
+ except Exception as e:
68
+ if self._running:
69
+ print(f"[VideoClient] Ошибка приема: {e}")
70
+
71
+ def get_latest_frame(self):
72
+ """Возвращает самый свежий собранный кадр (bytes)."""
73
+ with self._lock:
74
+ if self._frame_buffer:
75
+ return self._frame_buffer[-1]
76
+ return None
@@ -0,0 +1,56 @@
1
+ """Нарезка и сборка пакетов для UDP-видеопотока."""
2
+ import struct
3
+ import zlib
4
+
5
+ HEADER_FORMAT = "<IHH" # packet_id (4), total_chunks (2), chunk_index (2)
6
+ HEADER_SIZE = struct.calcsize(HEADER_FORMAT)
7
+ MAX_PAYLOAD_SIZE = 1400 # Безопасный размер для прохождения через NAT
8
+
9
+ def compress_data(data: bytes) -> bytes:
10
+ """Сжимает данные, чтобы уменьшить трафик."""
11
+ return zlib.compress(data, level=1) # level=1 самый быстрый
12
+
13
+ def decompress_data(data: bytes) -> bytes:
14
+ """Распаковывает данные."""
15
+ return zlib.decompress(data)
16
+
17
+ def split_frame(frame_id: int, data: bytes, compressed: bool = True) -> list:
18
+ """Нарезает кадр на список пакетов."""
19
+ if compressed:
20
+ payload = compress_data(data)
21
+ else:
22
+ payload = data
23
+
24
+ total_size = len(payload)
25
+ total_chunks = (total_size + MAX_PAYLOAD_SIZE - 1) // MAX_PAYLOAD_SIZE
26
+ if total_chunks > 65535:
27
+ raise ValueError("Кадр слишком большой (больше 65535 чанков)")
28
+
29
+ packets = []
30
+ for i in range(total_chunks):
31
+ start = i * MAX_PAYLOAD_SIZE
32
+ end = start + MAX_PAYLOAD_SIZE
33
+ chunk = payload[start:end]
34
+
35
+ # Header: frame_id, total_chunks, chunk_index
36
+ header = struct.pack(HEADER_FORMAT, frame_id, total_chunks, i)
37
+ packets.append(header + chunk)
38
+
39
+ return packets
40
+
41
+ def reassemble_frame(packets: list) -> bytes:
42
+ """Собирает кадр из списка пакетов.
43
+ Ожидает, что список уже отсортирован по chunk_index и полный.
44
+ """
45
+ if not packets:
46
+ return b""
47
+
48
+ # Извлекаем заголовок из первого пакета, чтобы узнать, сжат ли он
49
+ header = packets[0][:HEADER_SIZE]
50
+ frame_id, total_chunks, _ = struct.unpack(HEADER_FORMAT, header)
51
+
52
+ payload = bytearray()
53
+ for pkt in packets:
54
+ payload.extend(pkt[HEADER_SIZE:])
55
+
56
+ return decompress_data(bytes(payload))
@@ -0,0 +1,46 @@
1
+ """Серверная часть (Агент). Отправляет кадры."""
2
+ import socket
3
+ import threading
4
+ import time
5
+ from .packet import split_frame
6
+
7
+ class VideoServer:
8
+ def __init__(self, host="0.0.0.0", port=8081):
9
+ self.host = host
10
+ self.port = port
11
+ self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
12
+ self.sock.bind((self.host, self.port))
13
+
14
+ self.target_addr = None
15
+ self._running = False
16
+ self._frame_id = 0
17
+ self._lock = threading.Lock()
18
+
19
+ def set_target(self, ip, port):
20
+ """Устанавливает адрес клиента (Controller)."""
21
+ self.target_addr = (ip, port)
22
+
23
+ def start(self):
24
+ self._running = True
25
+ print(f"[VideoServer] UDP-сервер запущен на {self.host}:{self.port}")
26
+
27
+ def stop(self):
28
+ self._running = False
29
+ self.sock.close()
30
+ print("[VideoServer] Остановлен.")
31
+
32
+ def send_frame(self, image_bytes):
33
+ """Нарезает и отправляет один кадр."""
34
+ if not self.target_addr or not self._running:
35
+ return
36
+
37
+ with self._lock:
38
+ self._frame_id = (self._frame_id + 1) & 0xFFFFFFFF
39
+
40
+ packets = split_frame(self._frame_id, image_bytes, compressed=True)
41
+ for pkt in packets:
42
+ try:
43
+ self.sock.sendto(pkt, self.target_addr)
44
+ except Exception as e:
45
+ print(f"[VideoServer] Ошибка отправки: {e}")
46
+ break
@@ -0,0 +1,35 @@
1
+ import time
2
+ import threading
3
+ from netprotomvds import VideoServer, VideoClient
4
+
5
+ # 1. Настраиваем сервер
6
+ server = VideoServer(host="127.0.0.1", port=8081)
7
+ server.start()
8
+
9
+ # 2. Настраиваем клиент
10
+ client = VideoClient(server_ip="127.0.0.1", server_port=8081)
11
+ client.start()
12
+
13
+ # Говорим серверу, куда слать видео (в тесте шлем сами себе)
14
+ time.sleep(0.5) # Ждем старта
15
+ # Узнаем порт, на который клиент сел
16
+ client_port = client.sock.getsockname()[1]
17
+ server.set_target("127.0.0.1", client_port)
18
+
19
+ print("Начинаем передачу...")
20
+ for i in range(5):
21
+ test_data = f"Это тестовый кадр номер {i}".encode("utf-8") * 100 # ~3 КБ
22
+ server.send_frame(test_data)
23
+ time.sleep(0.2)
24
+
25
+ time.sleep(0.5) # Ждем, пока долетит
26
+ frame = client.get_latest_frame()
27
+
28
+ if frame:
29
+ print(f"Успех! Получен кадр размером {len(frame)} байт.")
30
+ print(f"Начало данных: {frame[:50].decode('utf-8')}...")
31
+ else:
32
+ print("Ошибка: кадр не получен.")
33
+
34
+ server.stop()
35
+ client.stop()
@@ -0,0 +1 @@
1
+ __version__ = "0.1.0"
@@ -0,0 +1,38 @@
1
+ Metadata-Version: 2.4
2
+ Name: netprotomvds
3
+ Version: 0.1.0
4
+ Summary: Network Protocol Multithreaded Video Data Share: быстрая передача видео по UDP.
5
+ Author-email: CharmLxt <reception.mailspypi@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/CharmLxt/netprotomvds
8
+ Project-URL: Source, https://github.com/CharmLxt/netprotomvds
9
+ Project-URL: Tracker, https://github.com/CharmLxt/netprotomvds/issues
10
+ Keywords: udp,video,streaming,networking,multithreading
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Multimedia :: Video
15
+ Classifier: Topic :: System :: Networking
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: numpy>=1.21.0
19
+ Requires-Dist: 9was9>=0.2.0
20
+
21
+ netprotomvds. Версия 0.1.0. Автор CharmLxt (PyPI: CharmLxt, email: reception.mailspypi@gmail.com). Ссылка на GitHub: https://github.com/CharmLxt/netprotomvds.
22
+
23
+
24
+
25
+ netprotomvds (Network Protocol Multithreaded Video Data Share) — это специализированная библиотека для сверхбыстрой передачи видеопотока или изображений по сети с использованием протокола UDP. Она создавалась специально для проекта Monogrammer, но может использоваться в любых задачах, где нужна трансляция экрана или видеозвонки (например, удаленный рабочий стол, стриминг игр или камеры).
26
+
27
+
28
+
29
+ В основе библиотеки лежит идея, что для видео надежность TCP не так важна, как скорость. Если один пакет с частью картинки потерялся в сети, мы просто отбрасываем весь этот кадр и показываем следующий. Из-за этого нет задержек на повторную отправку (как в TCP), и картинка движется максимально плавно. Библиотека автоматически нарезает большие кадры на маленькие пакеты, подходящие под размер MTU, отправляет их и собирает обратно на другом конце.
30
+
31
+
32
+
33
+ В версии 0.1.0 реализован базовый каркас. Модуль packet отвечает за нарезку и склейку данных с порядковыми номерами. VideoServer и VideoClient используют многопоточность (модуль threading) для фоновой отправки и приема, чтобы не блокировать основной интерфейс программы. Для сжатия данных используется стандартный zlib (чтобы не тащить тяжелые зависимости, но в будущем мы добавим JPEG через C#-мост Sowanna). Также встроен Jitter Buffer, который сглаживает неровности сети, храня пару последних кадров.
34
+
35
+
36
+
37
+ Установка: pip install netprotomvds. Зависимости: numpy и 9was9 (для быстрой математики, если понадобится обработка изображений). Библиотека кроссплатформенная, работает везде, где есть сокеты и Python 3.8+. Связь с автором: reception.mailspypi@gmail.com.
38
+
@@ -0,0 +1,13 @@
1
+ README.md
2
+ pyproject.toml
3
+ netprotomvds/__init__.py
4
+ netprotomvds/client.py
5
+ netprotomvds/packet.py
6
+ netprotomvds/server.py
7
+ netprotomvds/test_stream.py
8
+ netprotomvds/version.py
9
+ netprotomvds.egg-info/PKG-INFO
10
+ netprotomvds.egg-info/SOURCES.txt
11
+ netprotomvds.egg-info/dependency_links.txt
12
+ netprotomvds.egg-info/requires.txt
13
+ netprotomvds.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ numpy>=1.21.0
2
+ 9was9>=0.2.0
@@ -0,0 +1 @@
1
+ netprotomvds
@@ -0,0 +1,32 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "netprotomvds"
7
+ version = "0.1.0"
8
+ description = "Network Protocol Multithreaded Video Data Share: быстрая передача видео по UDP."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = "MIT"
12
+ authors = [{ name = "CharmLxt", email = "reception.mailspypi@gmail.com" }]
13
+ keywords = ["udp", "video", "streaming", "networking", "multithreading"]
14
+ dependencies = [
15
+ "numpy>=1.21.0",
16
+ "9was9>=0.2.0"
17
+ ]
18
+ classifiers = [
19
+ "Development Status :: 3 - Alpha",
20
+ "Intended Audience :: Developers",
21
+ "Programming Language :: Python :: 3",
22
+ "Topic :: Multimedia :: Video",
23
+ "Topic :: System :: Networking",
24
+ ]
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/CharmLxt/netprotomvds"
28
+ Source = "https://github.com/CharmLxt/netprotomvds"
29
+ Tracker = "https://github.com/CharmLxt/netprotomvds/issues"
30
+
31
+ [tool.setuptools.packages.find]
32
+ include = ["netprotomvds*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+