Пайплайн AI-метаданных и gRPC-интеграция
RUSEON Core предоставляет высокопроизводительный пайплайн AI-метаданных для объединения модулей компьютерного зрения (YOLOv11, TensorRT, OpenVINO) с видеоплеерами со сверхнизкой задержкой (< 50 мс) без перекодирования видео.
1. Спецификация gRPC Protobuf
Интерфейс описан в api/proto/frame.proto:
protobuf
syntax = "proto3";
package ruseon.core.frame;
option go_package = "github.com/RUSEGAL/ruseon-core/pkg/grpc/pb";
service FrameService {
rpc StreamFrames(StreamRequest) returns (stream FrameResponse) {}
rpc PushMetadata(stream MetadataRequest) returns (MetadataResponse) {}
}
message BoundingBox {
float x = 1; // Координата X левого верхнего угла (0.0 - 1.0)
float y = 2; // Координата Y левого верхнего угла (0.0 - 1.0)
float width = 3; // Ширина рамки (0.0 - 1.0)
float height = 4; // Высота рамки (0.0 - 1.0)
string label = 5; // Класс объекта (например, "person")
float confidence = 6; // Уверенность детекции (0.0 - 1.0)
}
message MetadataRequest {
string camera_id = 1;
int64 pts = 2;
repeated BoundingBox objects = 3;
}2. Раздача метаданных клиентам
- WebRTC DataChannel (
< 50 мс):- Метаданные отправляются по каналу SCTP DataChannel (
label: "metadata"). - Браузер принимает JSON и накладывает рамки на Canvas слой плеера.
- Метаданные отправляются по каналу SCTP DataChannel (
- Дорожка субтитров HLS WebVTT (
GET /stream/hls/:id/subs.m3u8):- Упаковываются в WebVTT метки (
.vtt), выровненные по таймштампам видео.
- Упаковываются в WebVTT метки (
3. Пример клиента на Python
python
import grpc
import time
import frame_pb2
import frame_pb2_grpc
def run_ai_worker():
channel = grpc.insecure_channel('localhost:50051')
stub = frame_pb2_grpc.FrameServiceStub(channel)
def generate_requests():
while True:
req = frame_pb2.MetadataRequest(
camera_id="cam-01",
pts=int(time.time() * 1000),
objects=[
frame_pb2.BoundingBox(
x=0.20,
y=0.15,
width=0.35,
height=0.60,
label="person",
confidence=0.95
)
]
)
yield req
time.sleep(0.04) # 25 FPS
response = stub.PushMetadata(generate_requests())
print(f"Статус загрузки: {response.success}")
if __name__ == "__main__":
run_ai_worker()