Как кодировать и декодировать видеокадры в виде строк для отправки / получения через AWS API веб-сокета, интегрированного в AWS лямбда-функцию с использованием Python? - PullRequest
0 голосов
/ 18 апреля 2020

У меня есть развернутый AWS шлюз API веб-сокета, интегрированный в лямбда-функцию AWS, с базовым сценарием использования приложения чата между клиентами. В настоящее время клиенты подключаются к веб-сокету с помощью clientid и отправляют сообщение в функцию Lambda в виде json объектного API.

Lambda просто маршрутизирует полученное сообщение назначенному клиенту, что прекрасно работает для отправка строковых сообщений, однако я хочу отправлять видео в реальном времени от одного клиента к другому с помощью той же службы, поэтому я попытался кодировать видеокадры в строки base64 и отправить через API. Я много пытался отправить живое видео, но я не могу ничего получить на другом клиенте.

Ниже приводится развернутая функция Lambda:

import json
import boto3
import botocore
from datetime import datetime
from aws_requests_auth.aws_auth import AWSRequestsAuth
import requests
from boto3.dynamodb.conditions import Key, Attr
from decimal import Decimal
import os

def applambda(event, context):

    connectionId=event["requestContext"]["connectionId"]
    body=json.loads(event["body"])
    ReceiverID=body["ReceiverID"]
    Msg=body["Msg"]
    MessageDateTime=str(datetime.now().timestamp())
    dynamoConnections=boto3.resource('dynamodb').Table("OnlineConnection")
    resultU=dynamoConnections.scan(FilterExpression=Key('ClientID').eq(ReceiverID))

    if resultU["Items"] is not None and len(resultU["Items"])==1:

        ReceiverConnectionID=resultU["Items"][0]["token"]
        resultX=dynamoConnections.scan(FilterExpression=Key("token").eq(connectionId))

        if resultX["Items"] is not None and len(resultX["Items"])==1:

            SenderID=resultX["Items"][0]["ClientID"]
            jsonObjtoSend={"MessageID":MessageDateTime,"Message":Msg,"SenderID":SenderID}
            sendDirectMessage(ReceiverConnectionID,jsonObjtoSend)
            return {"statusCode":200,"body":"Message Delivered"}

        else:

            return {"statusCode":200,"body":"Error Occurred"}
    else:

        return {"statusCode":200,"body":"User not Online"}

def sendDirectMessage(token, jsonobj):

    access_key=os.environ['access_key']
    secret_key=os.environ['secret_key']
    auth=AWSRequestsAuth(aws_access_key=access_key,
                        aws_secret_access_key=secret_key,aws_host='<ws host>-east-1.amazonaws.com',
                        aws_region='us-east-1',aws_service='execute-api'
                        )
    url='<AWS http url>'+token.replace("=","")+"%3D"
    req=requests.post(url,auth=auth,data=str(jsonobj))
    print(req.text)

Ниже указан мой client_stream .py файл, который передает данные по API,

import json
import pprint
import base64
import cv2
import websocket
from websocket import create_connection

websocket.enableTrace(True)
ws = create_connection('<ws host wih client query>')

camera = cv2.VideoCapture(0)

str_obj = {
           "Msg":"",
           "ReceiverID":"shd",
           "action":"sendmsg"
           }

while True:
    try:
        grabbed, frame = camera.read()  # grab the current frame
        frame = cv2.resize(frame, (640, 480))  # resize the frame
        encoded, buffer = cv2.imencode('.jpg', frame)
        buffer = buffer.tostring()
        jpg_as_text = base64.b64encode(buffer)
        str_obj["Msg"] = str(jpg_as_text)        
        ws.send(json.dumps(str_obj))

    except KeyboardInterrupt:
        # print(jpg_as_text)
        camera.release()
        cv2.destroyAllWindows()
        break

Ниже приведен мой файл client_viewer.py, который получает сообщение от Lambda:

import json
import pprint
import base64
import numpy as np
import cv2
import websocket
from websocket import create_connection

websocket.enableTrace(True)
ws = create_connection('<ws host wih client query>')
print("Connected")

while True:
    try:
        received = ws.recv()
        #print(received)
        if received is not None:
            received = eval(received)
            frame = received['Message']
            img = base64.b64decode(frame)
            npimg = np.fromstring(img, dtype=np.uint8)
            source = cv2.imdecode(npimg, 1)
            cv2.imshow("Stream", source)
            cv2.waitKey(1)

    except KeyboardInterrupt:
        cv2.destroyAllWindows()
        break

Я вполне могу отправить любое сообщение другим клиентам через API,

{"Msg":"<message>", "ReceiverID":"shd", "action":"sendmsg"}
...