Boto3 Kinesis视频GetMedia和OpenCV

12

我正在尝试使用Boto3从Kinesis获取视频流,然后使用OpenCV同时显示视频并将其保存到文件中。

获取签名URL和Getmedia请求的过程似乎完美无缺,但是当我尝试使用OpenCV渲染它时,它似乎不起作用。

数据肯定会传输到流中。

import boto3
import numpy as np
import cv2

kinesis_client = boto3.client('kinesisvideo',
                              region_name='eu-west-1',
                              aws_access_key_id='ACC',
                              aws_secret_access_key='KEY'
                              )

response = kinesis_client.get_data_endpoint(
    StreamARN='ARN',
    APIName='GET_MEDIA'
)
video_client = boto3.client('kinesis-video-media',
                            endpoint_url=response['DataEndpoint']
                            )
stream = video_client.get_media(
    StreamARN='ARN',
    StartSelector={'StartSelectorType': 'NOW'}
)
# print(stream)


datafeed = stream['Payload'].read()
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))

while(True):
        ret, frame = stream['Payload'].read()


        out.write(frame)

        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        else:
            break
cap.release()
out.release()
cv2.destroyAllWindows()
2个回答

10
为了回答这个问题,我发现可以使用Kinesis视频流提供的HLS输出来找到基本解决方案。该功能于2018年7月推出。
博客文章:https://aws.amazon.com/blogs/aws/amazon-kinesis-video-streams-adds-support-for-hls-output-streams/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+AmazonWebServicesBlog+%28Amazon+Web+Services+Blog%29 我在下面粘贴了我的代码的工作版本。
我正在使用AWS环境变量进行BOTO3身份验证。
import boto3
import cv2

STREAM_NAME = "test-stream"
kvs = boto3.client("kinesisvideo")
# Grab the endpoint from GetDataEndpoint
endpoint = kvs.get_data_endpoint(
    APIName="GET_HLS_STREAMING_SESSION_URL",
    StreamName=STREAM_NAME
)['DataEndpoint']

print(endpoint)

# # Grab the HLS Stream URL from the endpoint
kvam = boto3.client("kinesis-video-archived-media", endpoint_url=endpoint)
url = kvam.get_hls_streaming_session_url(
    StreamName=STREAM_NAME,
    PlaybackMode="LIVE"
)['HLSStreamingSessionURL']


vcap = cv2.VideoCapture(url)

while True:
    # Capture frame-by-frame
    ret, frame = vcap.read()

    if frame is not None:
        # Display the resulting frame
        cv2.imshow('frame',frame)

        # Press q to close the video windows before it ends if you want
        if cv2.waitKey(22) & 0xFF == ord('q'):
            break
    else:
        print("Frame is None")
        break

# When everything done, release the capture
vcap.release()
cv2.destroyAllWindows()
print("Video stop")

太棒了!感谢您分享您的代码!千万个感谢。 - Henry Navarro
对我来说,帧始终为“无”。我在Kinesis视频流媒体查看器中获取了实时反馈,因此它正在运行。 - Jack Vial

0
你可以这样做。这很简单,但不完美(解析流中的mkv可能更好,以便始末位置总是正确)。此外,如果流中的mkv小于1024字节,它将无法工作。
import boto3
import cv2

kinesis_client = boto3.client("kinesisvideo", region_name="eu-central-1")
get_media_response = kinesis_client.get_data_endpoint(StreamName="my_stream_name", APIName="GET_MEDIA")
video_client = boto3.client("kinesis-video-media", endpoint_url=get_media_response["DataEndpoint"], region_name="eu-central-1")
stream = video_client.get_media(StreamName="my_stream_name", StartSelector={"StartSelectorType": "NOW"})

mkv = b''
while True:
    chunk = stream["Payload"].read(1024)
    if chunk == b'':
        # nothing in the stream
        # you could wait a little and try again
        break
    if mkv == b'':
        mkv += chunk
    else:
        index = chunk.find(b'\x1aE\xdf\xa3') # magic numbers marking the beginning of an mkv
        if index == -1:
            mkv += chunk
        else:
            mkv += chunk[0:index]
            # process mkv
            with open("file.mkv", "wb") as f:
                f.write(mkv)
            video = cv2.VideoCapture("file.mkv")
            while video.isOpened():
                ret, frame = video.read()
                if ret:
                    cv2.imshow("Frame", frame)
                else:
                    break
            mkv = chunk[index:]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接