Справочник gRPC API для кадров и AI-метаданных
RUSEON Core предоставляет высокопроизводительный сервис gRPC (FrameService, порт по умолчанию 50051) на базе Protocol Buffers v3 (api/proto/frame.proto). Он позволяет модулям компьютерного зрения (YOLOv11, DeepStream, Python-скрипты) подписываться на сырые видеокадры и загружать координаты рамок детекций.
1. Спецификация Protobuf (frame.proto)
protobuf
syntax = "proto3";
package ruseon.core.frame;
option go_package = "github.com/RUSEGAL/ruseon-core/pkg/grpc/pb";
// FrameService предоставляет потоковый доступ к видеокадрам и принимает метаданные ИИ.
service FrameService {
// StreamFrames подписывается на поток камеры и отдает H.264/H.265 кадры.
rpc StreamFrames(StreamRequest) returns (stream FrameResponse) {}
// PushMetadata принимает непрерывный поток метаданных детекций от ИИ-модулей.
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", "car")
float confidence = 6; // Уверенность детекции (0.0 - 1.0)
}
message MetadataRequest {
string camera_id = 1;
int64 pts = 2; // PTS кадра, к которому относятся метаданные
repeated BoundingBox objects = 3; // Список обнаруженных объектов
}
message MetadataResponse {
bool success = 1;
string message = 2;
}
message StreamRequest {
string camera_id = 1;
}
message FrameResponse {
string codec = 1; // "H264" или "H265"
bool is_keyframe = 2; // true если это I-Frame (ключевой кадр)
int64 pts = 3; // Presentation Time Stamp (в миллисекундах)
bytes payload = 4; // Сырые байты кадра (NAL-юниты)
}2. Пример клиента на Python (Передача детекций ИИ)
Отправка детекций объектов из Python воркера YOLOv11 в RUSEON Core:
python
import grpc
import time
import frame_pb2
import frame_pb2_grpc
def generate_metadata():
while True:
req = frame_pb2.MetadataRequest(
camera_id="cam-01",
pts=int(time.time() * 1000),
objects=[
frame_pb2.BoundingBox(
x=0.25,
y=0.30,
width=0.40,
height=0.45,
label="person",
confidence=0.96
)
]
)
yield req
time.sleep(0.04) # 25 FPS
def run():
channel = grpc.insecure_channel('localhost:50051')
stub = frame_pb2_grpc.FrameServiceStub(channel)
response = stub.PushMetadata(generate_metadata())
print(f"Статус отправки метаданных: {response.success}, {response.message}")
if __name__ == '__main__':
run()