kinesis_video_webrtc 1.0.3
kinesis_video_webrtc: ^1.0.3 copied to clipboard
A Flutter package for AWS Kinesis Video Streams - WebRTC
Usage #
final res = await http.get(Uri.parse("http://localhost/config?role=VIEWER"));
final cfg = jsonDecode(res.body);
final config = SignalingClientConfig(
channelARN: cfg['channelARN'],
channelEndpoint: cfg['wss'],
region: cfg['region'],
role: Role.VIEWER,
clientId: SignalingClient.getRandomClientId(),
credentials: Credentials(cfg['credentials']['accessKeyId'], cfg['credentials']['secretAccessKey'], cfg['credentials']['sessionToken']),
);
_signalingClient = SignalingClient(config);
_signalingClient.onOpen.listen((_) async {
_rtcPeerConnection = await createPeerConnection({'iceServers': cfg['iceServers'], 'iceTransportPolicy': 'all', 'sdpSemantics': 'unified-plan'});
_rtcPeerConnection!.onTrack = (event) {
if (event.streams.isNotEmpty) {
_remoteStream = event.streams[0];
_remoteVideoRenderer.srcObject = event.streams[0];
}
setState(() {});
};
_rtcPeerConnection!.onIceCandidate = (candidate) async {
if (candidate != null && candidate.candidate != null) {
_signalingClient.sendIceCandidate(candidate);
} else {
_signalingClient.sendSdpOffer(await _rtcPeerConnection?.getLocalDescription() as RTCSessionDescription);
}
};
try {
_localStream = await navigator.mediaDevices.getUserMedia({'audio': true, 'video': false});
_localStream!.getAudioTracks().forEach((track) {
_rtcPeerConnection!.addTrack(track, _localStream!);
});
} catch (e) {
logger.severe('getUserMedia failed: $e');
}
RTCSessionDescription offer = await _rtcPeerConnection!.createOffer({
'mandatory': {'OfferToReceiveAudio': true, 'OfferToReceiveVideo': true},
'optional': [],
});
await _rtcPeerConnection!.setLocalDescription(offer);
_signalingClient.sendSdpOffer(await _rtcPeerConnection!.getLocalDescription() as RTCSessionDescription);
});
_signalingClient.onSdpAnswer.listen((answer) async {
await _rtcPeerConnection?.setRemoteDescription(answer);
});
_signalingClient.onIceCandidate.listen((candidate) {
_rtcPeerConnection?.addCandidate(candidate.iceCandidate);
});
_signalingClient.open();
The complete example can be found here 👉 examples
An example of fetching the configuration #
from flask import Flask, jsonify, render_template, request
from flask_cors import CORS
import boto3
app = Flask(__name__)
CORS(app)
REGION = ""
CHANNEL_NAME = ""
AWS_ACCESS_KEY_ID = ""
AWS_SECRET_ACCESS_KEY = ""
AWS_SESSION_TOKEN = None
ROLE_ARN = ""
kvs = boto3.client("kinesisvideo", region_name=REGION, aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
aws_session_token=AWS_SESSION_TOKEN, )
sts = boto3.client("sts", region_name=REGION)
@app.route("/config")
def get_config():
role = request.args.get('role', default="MASTER")
# Get sts credentials
resp = sts.assume_role(
RoleArn=ROLE_ARN,
RoleSessionName="WebRTCSession",
DurationSeconds=3600
)
creds = resp["Credentials"]
# 1. Describe Signaling Channel
desc = kvs.describe_signaling_channel(ChannelName=CHANNEL_NAME)
channel_arn = desc["ChannelInfo"]["ChannelARN"]
# 2. Get Signaling Endpoints
ep = kvs.get_signaling_channel_endpoint(
ChannelARN=channel_arn,
SingleMasterChannelEndpointConfiguration={
"Protocols": ["WSS", "HTTPS"],
"Role": role
}
)
wss = [x for x in ep["ResourceEndpointList"] if x["Protocol"] == "WSS"][0]["ResourceEndpoint"]
http = [x for x in ep["ResourceEndpointList"] if x["Protocol"] == "HTTPS"][0]["ResourceEndpoint"]
# 3. Get ICE Servers
kvs_signaling = boto3.client("kinesis-video-signaling", region_name=REGION, endpoint_url=http)
ice = kvs_signaling.get_ice_server_config(ChannelARN=channel_arn)
ice_servers = [
{'urls': ['stun:stun.kinesisvideo.'+REGION+'.amazonaws.com:443']}
]
for s in ice.get("IceServerList", []):
ice_servers.append({
"urls": s["Uris"],
"username": s.get("Username"),
"credential": s.get("Password")
})
return jsonify({
"region": REGION,
"channelARN": channel_arn,
"http": http,
"wss": wss,
"iceServers": ice_servers,
"credentials": {
"accessKeyId": creds["AccessKeyId"],
"secretAccessKey": creds["SecretAccessKey"],
"sessionToken": creds["SessionToken"],
"expiration": str(creds["Expiration"])
}
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=80, debug=True)