如何将在 django 中从 opencv 捕获的实时视频发送到 aws kinesis-video-streams putmedia 端点?

时间:2021-02-03 07:43:04

标签: python django opencv amazon-kinesis-video-streams

实现: 使用 OpenCV 在 Web 浏览器中捕获摄像头的实时馈送,并使用 PUT_MEDIA(end_point) 将其发送到 AWS Kinesis-video-stream(一种 aws 服务)。

已提及 Amazon AWS Kinesis Video Boto GetMedia/PutMedia 并做了一些更改以从相机拍摄。

显示用户流的 HTML 代码(从网络摄像头捕获的视频):

<html>
<body>
<video autoplay="true" id="myVideo"></video>
</body>
</html>

'''

**views.py**

def get_endpoint_boto():
    import boto3

    client = boto3.client('kinesisvideo','us-east-2',aws_access_key_id = your_env_access_key_var ,aws_secret_access_key = your_env_secret_key_var)
    response = client.get_data_endpoint(
        StreamName=your_stream_name,
        APIName='PUT_MEDIA'
    )
    print(response)
    endpoint = response.get('DataEndpoint', None)
    print("endpoint %s" % endpoint)
    if endpoint is None:
        raise Exception("endpoint none")
    return endpoint

def sign(key, msg):
    return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()

def get_signature_key(key, date_stamp, regionName, serviceName):
    kDate = sign(('AWS4' + key).encode('utf-8'), date_stamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'aws4_request')
    return kSigning

def get_host_from_endpoint(endpoint):
    if not endpoint.startswith('https://'):
        return None
    retv = endpoint[len('https://'):]
    return str(retv)

def get_region_from_endpoint(endpoint):
    if not endpoint.startswith('https://'):
        return None
    retv = endpoint[len('https://'):].split('.')[2]
    return str(retv)


class gen_request_parameters:
    def __init__(self):
        self._data = ''
        if True:
            print('True')
            cap = cv.VideoCapture(0)
            cap.set(5,60)
            if not cap.isOpened():
                exit()
            ret, frame = cap.read()
            request_parameters = cap.read()
            self._data = request_parameters
            self._pointer = 0
            self._size = len(self._data)
    
    def __next__(self):
        print('next')
        if self._pointer >= self._size:
            raise StopIteration
        left = self._size - self._pointer
        chunksz = 16000
        if left < 16000:
            chunksz = left
        pointer_start = self._pointer
        self._pointer = self._pointer + chunksz
        print("Data: chunk size %d" % chunksz)
        return self._data[pointer_start:self._pointer]

def mediagolive(request, streamname):
    your_stream_name = streamname
    print(your_stream_name)
    endpoint = get_endpoint_boto()

    method = 'POST'
    service = 'kinesisvideo'
    host = get_host_from_endpoint(endpoint)
    region = get_region_from_endpoint(endpoint)
    endpoint += '/putMedia'
    content_type = 'application/json'
    start_tmstp = repr(time.time())
    access_key = None
    secret_key = None
    while True:
        k = your_env_access_key_var
        if k is not None and type(k) is str and k.startswith('AKIA'):
            access_key = k
        k = your_env_secret_key_var
        if k is not None and type(k) is str and len(k) > 4:
            secret_key = k
        break
    if access_key is None or secret_key is None:
        print('No access key is available.')
        exit()
    t = datetime.datetime.utcnow()
    amz_date = t.strftime('%Y%m%dT%H%M%SZ')
    date_stamp = t.strftime('%Y%m%d')
    canonical_uri = '/putMedia'
    canonical_querystring = ''
    canonical_headers = ''
    canonical_headers += 'connection:keep-alive\n'
    canonical_headers += 'content-type:application/json\n'
    canonical_headers += 'host:' + host + '\n'
    canonical_headers += 'transfer-encoding:chunked\n'
    canonical_headers += 'user-agent:AWS-SDK-KVS/2.0.2 GCC/7.4.0 Linux/4.15.0-46-generic x86_64\n'
    canonical_headers += 'x-amz-date:' + amz_date + '\n'
    canonical_headers += 'x-amzn-fragment-acknowledgment-required:1\n'
    canonical_headers += 'x-amzn-fragment-timecode-type:ABSOLUTE\n'
    canonical_headers += 'x-amzn-producer-start-timestamp:' + start_tmstp + '\n'
    canonical_headers += 'x-amzn-stream-name:' + your_stream_name + '\n'
    signed_headers = 'connection;content-type;host;transfer-encoding;user-agent;'
    signed_headers += 'x-amz-date;x-amzn-fragment-acknowledgment-required;'
    signed_headers += 'x-amzn-fragment-timecode-type;x-amzn-producer-start-timestamp;x-amzn-stream-name'
    canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers
    canonical_request += '\n'
    canonical_request += hashlib.sha256(''.encode('utf-8')).hexdigest()
    algorithm = 'AWS4-HMAC-SHA256'
    credential_scope = date_stamp + '/' + region + '/' + service + '/' + 'aws4_request'
    string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + '\n' + hashlib.sha256(
        canonical_request.encode('utf-8')).hexdigest()

    signing_key = get_signature_key(secret_key, date_stamp, region, service)

    signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'),
                        hashlib.sha256).hexdigest()

    authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', '
    authorization_header += 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature

    headers = {
        'Accept': '*/*',
        'Authorization': authorization_header,
        'connection': 'keep-alive',
        'content-type': content_type,
        #'host': host,
        'transfer-encoding': 'chunked',
        # 'x-amz-content-sha256': 'UNSIGNED-PAYLOAD',
        'user-agent': 'AWS-SDK-KVS/2.0.2 GCC/7.4.0 Linux/4.15.0-46-generic x86_64',
        'x-amz-date': amz_date,
        'x-amzn-fragment-acknowledgment-required': '1',
        'x-amzn-fragment-timecode-type': 'ABSOLUTE',
        'x-amzn-producer-start-timestamp': start_tmstp,
        'x-amzn-stream-name': your_stream_name,
        'Expect': '100-continue'
    }

    print('\nBEGIN REQUEST++++++++++++++++++++++++++++++++++++')
    print('Request URL = ' + endpoint)
    r = requests.post(endpoint, data=gen_request_parameters().__next__(), headers=headers)
    print('\nResponse Meta ++ \n',r.content.decode('utf8'))
    print('\nRESPONSE++++++++++++++++++++++++++++++++++++')
    print('Response code: %d\n' % r.status_code)
    print(r.text)
'''

这是我得到的控制台日志: 在这里,我收到了来自 AWS 的“200”响应,这意味着我能够正确到达终点。 但我不确定帧是否被发送到 AWS 流,因为在 kinesis-video-streaming 仪表板中的 AWS 媒体播放中没有显示任何内容。

BEGIN REQUEST++++++++++++++++++++++++++++++++++++
Request URL = https://s-171c51c7.kinesisvideo.us-east-2.amazonaws.com/putMedia
True
frame [[[ 45  66 118]
  [110 131 183]
  [152 176 220]

  [ 77  60  63]
  [ 73  58  61]
  [ 71  57  59]]

 [[ 66  65 127]
  [136 135 197]
  [156 179 221]

  [ 77  63  65]
  [ 71  62  61]
  [ 70  61  60]]

 [[ 61  80 131]
  [126 145 197]
  [159 185 215]
  [ 80  65  68]
  [ 77  64  64]
  [ 76  62  62]]


 [[ 32  25  24]
  [ 32  25  24]
  [ 31  26  27]

  [ 22  22  22]
  [ 20  23  21]
  [ 20  23  21]]

 [[ 26  24  24]
  [ 28  25  26]
  [ 28  25  26]

  [ 22  22  22]
  [ 21  21  21]
  [ 21  21  21]]

 [[ 25  24  22]
  [ 26  25  23]
  [ 26  25  23]

  [ 22  22  22]
  [ 22  22  22]
  [ 21  21  21]]]
next
Data: chunk size 100
[ WARN:1] global C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-kh7iq4w7\opencv\modules\videoio\src\cap_msmf.cpp (434) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback

在 HTML 上呈现的错误:

TypeError at /go_live/
cannot unpack non-iterable bool object
Request Method: GET
Request URL:    http://127.0.0.1:8000/go_live/
Django Version: 3.0.5
Exception Type: TypeError
Exception Value:    
cannot unpack non-iterable bool object

0 个答案:

没有答案