How to use AWS WebRTC signed url in the frontend? - amazon-web-services

The aws repo https://github.com/awslabs/amazon-kinesis-video-streams-webrtc-sdk-js provides the backend code to generate a presigned url.
I was able to log it and it looks like this (modified by adding/removing some characters to avoid misuse):
wss://v-7bd53a347.kinesisvideo.ap-south-1.amazonaws.com/?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-ChannelARN=arn%3Aaws%3Akinesisvideo%3Aap-south-1%3A3514502525359%3Achannel%2Fwebcam-signalling-channel-4%2F1637856477339&X-Amz-ClientId=U5PAWCWS5VE&X-Amz-Credential=ASIAVDVAVN2XSBEJVNOK%2F20211207%2Fap-south-1%2Fkinesisvideo%2Faws4_request&X-Amz-Date=20211207T160335Z&X-Amz-Expires=299&X-Amz-Security-Token=IQoJb3JopZ2luX2VjEND%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCmFwLXNvdXRoLTEiRzBFAiEA50TmitWwvooci6xG3i1M4jGzt7c7lfEu36TcdzOOFm8CIBNZLLDLB%2FDiBGIkU1PymctAcnobgu4WX%2F4KptvG%2BTOjKtMECKn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQAhoMMzUxNDUwNTI1MzU5IgzlJEvF6NfKu43Rf70qpwRckEnOpVflPcE%2FvLtSXqgUCDI5qE5F9RUSpqtVKEA0Q6qPClsXw9IJMx2PWWQdgQ5I2uuMG1Ql1EH5DbY%2Fac0%2B%2BXWUJnPeHjDvpuNRk4J52YWAO02s4692U0EayCJsyxD57z5OKuQ8y9xkfjd60juMqJ8QUX1NsRgx10OJvxEbQh8Fou2N9qJeJokSrLOD6bCIRZdJQ%2FLzg6q7HdR5oqnNTMHNv7sJ0gmcxF7UhT0wS%2FuIcEtyNBo%2FyE1NI0ytgXVic6R7Pe4wSyzIn76W2x98I3OrbPa67vq3NzyJK1h%2F%2FqhfqNFPOaBP7eFGxcVWRPqz2VOknNtMD3b8QFZV2HwwnLBUXv2Dgp3Ez%2Fl%2F06hnAwHARStNtpP3ZX1maJE%2FBK52tRP%2BAWG1mv5wNodPWNAj%2B%2B04Obn91%2BjmAUc6ntXLWbZLUUuAtS8RSYDkX41ZA%2BnKTPZusBjh5vxW8A8fa3YKl33b4T9QT5eTWqNq9EXeI51Vd6mZsWh9kgEF768MSDn3hfTTIhFienuErO6N5wPWzOVp71aUgJS95Y2LTffOocP3CL3daCaYiEvzA%2FolDXwRzTqYRK6MwlqeAGjREmIoYjb11K4kU8mtHfDAKq5c1JA4cW719WBAoiQsxRO0egcFuskkGSCiAEaMAbg94eSnHpFLmPWYJwHj61eBU4JzIUsmzhxLF5x4MADUjxf1yOTRyx3FhIiO51gutW1fbgTt7z9lPn9szDXi76NBjqFAiE7AMy1zOl4hnXhjO60JRiKgHL0YuKsHJPAV02UmAdgf7lY%2Bl14ABncq4q1HSv%2BRKA2rr1ZM9JfgjMGHD0Xw9a8qFjN0RX5N%2FMw0F5nvVV9oGC8lYmT%2BLwW7DfyinSIA30SMzfXVfIEcGhEil900hoZMQZyvOWM4q7F%2Bye%2FN4%2FzS1RqMNHQGIT%2FdgOZkSJwyho6cpH1kEZXZMfhlWjOnTBjcqQzGYd9g9GLocDq8ZivrAKCtEM6yR%2Bh%2FsLhtGinqpsVFM%2BhaxK9G929tvlIQ3ZxA4GRAuTBepucoeVhmOwWv0f%2Fk82xjET%2FD5zVYvtMEpoU76aPal7pYNis98DspPB9ugrAw%3D%3D&X-Amz-Signature=8303b836351e231e9e7850cdd565a21073eaa4cb699b06d50c9e7f7e15a933e&X-Amz-SignedHeaders=host
I am not able to understand how to use it in the frontend to view the video stream.
I have come across other comments seeking examples but there are no responses:
How to use Kinesis Video Stream WebRTC SDK in the browser without providing credentials?
Has anyone been able to use it?

In case you are still looking for an answer, the signed url can be used while creating a signalling client in the front end code and can be used for connecting with AWS WebRTC Signalling service. You may find an example at below
https://blog.learningdollars.com/2021/05/09/aws-kinesis-video-stream-with-signed-url/
I implemented the above but was unable to see request from one front-end module to the other front-end module using AWS Kinesis WebRTC.

Related

Playing an mp3 created by AWS api gateway in an Alexa skill

I have an AWS lambda function that is called by AWS api gateway. The function takes URLs from multiple mp3 files hosted on AWS S3 and concatenates them into a single mp3 file. When I call the api from a browser all is good (the browser opens a media player and the combined audio mp3 is played).
The URL request looks like this:
https://0xxxxxxxx.execute-api.eu-west-1.amazonaws.com/alpha/files?file=https://xxx.s3-eu-west-1.amazonaws.com/file1.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file2.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file3.mp3
the HTTP response is of type audio/mpeg, about 10 seconds long, and is base64 encoded.
I've tried to wrap this into SSML in my skill and it fails. From the Alexa skills kit voice and tone simulator, I get the error message "error retrieving text to speech; the input was incompatible"
In the simulator, this is what I wrote:
<speak>
<audio src='https://0xxxxxxxx.execute-api.eu-west-1.amazonaws.com/alpha/files?file=https://xxx.s3-eu-west-1.amazonaws.com/file1.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file2.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file3.mp3'/>
</speak>
and I used this to confirm that S3 access works in the simulator:
<speak>
<audio src='https://s3.amazonaws.com/ask-soundlibrary/human/amzn_sfx_crowd_applause_05.mp3'/>
</speak>
Any ideas what is wrong? Is the issue with the http response from my lambda skill, or does something need to be enabled in api gateway? From my api gateway logs, it seems that the skill never tries to access the gateway.
Should I be using a different approach to fetch the mp3 for playback? Note, i want to use SSML as my audio is an effect and therefore shouldn't use the audioplayer (This is an Amazon requirement).
I might help you with this. The same problem happened to me. And after researching I resolved it. The problem here is "&" in you link which you provide in SSML. The solution you provided worked because there is no "&" now in your link. Too many parameters is not the problem.
I will suggest you to replace "&" with "&"
In python -
url = 'https://0xxxxxxxx.execute-api.eu-west-1.amazonaws.com/alpha/files?file=https://xxx.s3-eu-west-1.amazonaws.com/file1.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file2.mp3&file=https://xxx.s3-eu-west-1.amazonaws.com/file3.mp3'
url = url.replace("&","&")
<speak>
"<audio src='" + url + "'/>"
</speak>
I hope this helps you. Please let me know if doesn't work.
Ok, I've worked it out myself.
It seems that SSML audio src doesn't like too many parameters in the URL call. I now just pass 1 parameter in the URL and use my lambda function to strip out the multiple filenames frome that single parameter.
https://0xxxxxxxx.execute-api.eu-west-1.amazonaws.com/alpha/files?file=/file1.mp3file=file2.mp3file=file3.mp3

AWS API Gateway Integration Request setup automation

I am trying to use the AWS API Gateway+Swagger to route the request to my express backend. I can't figure out how to automate the setup of the integration request as the Swagger file has no details on it.
I'm also having difficulty with the endpoint url parameter when setting my method requests to GET/VPC Link on the integration type
For example:
My api gateway path is /info/car/{model}/aggregate
Now the endpoint url is http://carapi.com/info/car/{model}/aggregate
I have lots of gateway paths all of which are the same paths that my carapi.com site uses, so I don't want to keep retyping the path over and over. When entering in the endpoint url, I was able to simplify not having to type carapi.com by using stage variables turning my endpoint url to
http://${stageVariables.carApi}/info/car/{model}/aggregate
However after reading https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#stagevariables-template-reference
I see that there is also a $context available, but it gives me an error(when I try to call the api in postman, says 'internal server error' for the message) when I try to implement the context (which through that link shows that I can implement the path).
http://${stageVariables.carApi}/${context.resourcePath}
So my question is: how do I automate the setup of Integration requests so I don't have to manually setup each and every one(as I have hundreds of paths)? Is there also anyway to not have to set the paths manually for the endpoints?
I don't know of any solution which is ready to use.
In my project, we wrote a custom solution that downloads the application Swagger json, parses it, adds the required integration and generates another json file. Then we import that into API Gateway. This has been converted as a Jenkins job and runs as a post job of microservice deployment.
Another way is, instead of generating the json, directly call API Gateway APIs and add the integration.

Lambda function custom domain

I have been messing around with AWS lambda today trying some things out. I am currently trying to trigger the function from a url in a browser.
The URL looks similar to this: https://abcdef.execute-api.eu-west-2.amazonaws.com/default/test
As I understand it I can assign a custom domain to my endpoint, but can I also get rid of the path part of the url, so for example:
GET: https://example.com/
GET: https://example.com/somefile.txt
POST: https://example.com/ ['some_post_field' => 'some data']
Will all be passed to my function, or do I need to configure an EC2 instance with NGINX to proxy-pass the requests to lambda?
Any thoughts would be useful.
There are now a couple different ways you can accomplish this in AWS:
The newest (arguably coolest!) is to use Cloudfront to run your code using their Lambda#Edge service. You can completely customize your URL path and have portions used as variables like any other REST endpoint. You attach your Lambda fn to "behaviour" endpoints which give you full URL control. Its fairly deep and beyond the scope of your question to explain it all here, but read through the docs at the link provided and you'll likely see lots of stuff you like.
Another older, more expensive but more documented method is to use AWS's API Gateway as you have eluded to in your question's tags. It has a great front end console and is easy to connect API endpoints to your Lambda backend logic by attaching them to REST methods. The console helps you "variable-ize" your URL with form field data. This service helps you the most with custom domains to trigger from. Setting up custom domains is a snap in API Gateway. Be sure to use AWS's SSL Certificate Manager for free SSL certs on your custom domain too!
How you specifically setup your endpoints depends on which service you choose. Personally, given your desire to serve up different types of content, I would lean towards CloudFront, and define a "behaviour" URL for your dynamic Lambda content. If the URL request does not match one of your defined behaviours, it defaults to the Cloudfront cache/origin to serve your static assets (somefile.txt). Only matches go to your attached Lambda fn with form data. Very slick!
A lot of example Lambda#Edge fn's are available here.
I have used both and have clients on both now. Lambda#Edge is ridiculously faster and less expensive, BUT is less documented, has a steeper learning curve, and console is not nearly as helpful. I would honestly try both to see which fits your situation and experience level best. Both will get the job done. EC2 is most definitely NOT needed (nor desired perhaps). Hope that helps — good luck!
Instead of directly exposing the Lambda function via URL, expose it through AWS API Gateway where you can define your own paths and map to a Domain.

Not able to stream PDF, using AWS gateway/Lambda setup

Problem Statement:- Not able to stream PDF, using AWS gateway/Lambda setup.
I've following Setup:-
Gateway API -> Lambda Function(java) -> S3
Api should stream a PDF back to the client via Lambda from S3 server.
I am unable to do so.
Things tried
1) On Lambda side
Use RequestStreamHandler, write PDF on OutputStream
outputStream.write();
Tried Setting Base64 encoding using following
AWS Base64 Utility
java.util Base64 Utility
apache Base64 utility
Send Byte[] without encoding
Use non-proxy handler, write PDF as string to one of the output variable.
Tried Setting Base64 encoding using following
AWS Base64 Utility
java.util Base64 Utility
apache Base64 utility
Send Byte[] without encoding
2) On Gateway Side
Set Proxy integration
Remove Proxy integration
Tried Set Content Handling using
Passthrough
Convert to Binary
Convert to String
Set headers
Content-Type = 'application/pdf'
Content-Disposition = 'attachment; filename="nameofpdffile.pdf"'
I've tried all the permutations/combinations of these 2. However, I am not able to get it to work and documentation around this area seems poor.
When I set Base64 encoding in Lambda and on gateway side specify content handling as convert to binary, i get error, fail to conert using Base64 decode.
For other combinations, I get binary data as output when I test it using gateway Test funciton, however my client(Postman, Chrome, Safari) fail to convert it to PDF
Note:- I've a workaround in place, where I create a signedURL to S3 object, and send it as redirect. However, I am trying to make it work by streaming a binary file using Lambda.
Thanks for reading such a long post. Any pointers, links in the right direction are highly appreciated.
- Frustated AWS user :-)
I had a similar problem with trying to offer up gzipped content: Client -> API-Gateway -> S3.
I couldn't figure out why the content I pulled couldn't get recognized by the client (either browser or code) until I inspected the header(the binary header, not http).
It appears that API Gateway by default assumes a string based encoding (utf-8) so what I was seeing is data that API Gateway was transforming on the fly and adding utf-8 headers in various places.
Late last year API Gateway started to support binary payloads. I started reading this article which may help in your case. It did not in mine, but your use case is slightly different and closer to the article so it might.
https://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/
As for what I ended up doing... I realized I was just using the API Gateway as a passthrough (to take advantage of the Cognito based authentication I had already setup) so I bypassed API Gateway all together and used the aws js sdk to connect directly to s3 (and set IAM policies on the bucket separately)

Asp Mvc 3 - Restful web service for consuming on multiple platforms

I am wanting to expose a restful web service for posting and retrieving data, this may be consumed by mobile devices or a web site.
Now the actual creation of the service isn't a problem, what does seem to be a problem is communicating from a different domain.
I have made a simple example service deployed on the ASP.NET development server, which just exposes a simple POST action to send a request with JSON content. Then I have created a simple web page using jquery ajax to send some dummy data over, yet I believe I am getting stung with the same origin policy.
Is this a common thing, and how do you get around it? Some places have mentioned having a proxy on the domain that you always request a get to, but then you cannot use it in a restful manner...
So is this a common issue with a simple fix? As there seem to be plenty of restful services out there that allow 3rd parties to use their service...
How exactly are you "getting stung with the same origin policy"? From your description, I don't see how it could be relevant. If yourdomain.com/some-path/defined-request.json returns a certain JSON response, then it will return that response regardless of what is requesting the file, unless you have specifically defined required credentials that are not satisfied.
Here is an example of such a web service. It will return the same JSON object regardless of from where the request is made: http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true
Unless I am misunderstanding you (in which case you should clarify your actual problem), the same origin policy doesn't really seem to apply here.
Update Re: Comment
"I make a simple HTML page and load it as file://myhtmlfilelocation/myhtmlfile.html and try to make an ajax request"
The cause of your problem is that you are using the file:// URL scheme, instead of the http:// protocol scheme. You can find information about this scheme in Section 3.10 of RFC 1738. Here is an excerpt:
The file URL scheme is used to designate files accessible on a particular host computer. This scheme, unlike most other URL schemes, does not designate a resource that is universally accessible over the Internet.
You should be able to resolve your issue by using the http:// scheme instead of the file:// scheme when you make your asynchronous HTTP request.