Record real time Audio from browser and stream to Amazon S3 for storage - amazon-web-services

I want to record audio from my browser and live stream it for storage in Amazon S3. I cannot wait till the recording is finished as client can close the browser, so I would like to store what has been spoken (or nearest 5-10 second).
The issue is multipart upload does not support less than 5Mib chunks, and audio files will be for most part less than 5Mib.
Ideally I would like to send the chunks in 5 seconds, so what has been said in last 5 seconds to be uploaded.
Can it be support by S3? or should I use any other AWS service to first hold the recording parts - heard about kinesis stream but not sure if it can serve the purpose.

Related

How spark streaming application works when it fails?

I started learning about spark streaming applications with kinesis. I got a case where our spark streaming application fails, it restarts but the issue is, when it restarts, it tries to process more amount of messages than it can process and fails again. So,
Is there any way, we can limit the amount of data a spark streaming application can process in terms of bytes?
Any let say, if a spark streaming application fails and remains down for 1 or 2 hours, and the InitialPositionInStream is set to TRIM_HORIZON, so when it restarts, it will start from the last messages processed in kinesis stream, but since there is live ingestion going on in kinesis then how the spark streaming application works to process this 1 or 2 hours of data present in kinesis and the live data which is getting ingested in kinesis?
PS - The spark streaming is running in EMR and the batch size is set to 15 secs, and the kinesis CheckPointInterval is set to 60 secs, after every 60 secs it writes the processed data details in DynamoDB.
If my question is/are unclear or you need any more informations for answering my questions, do let me know.
spark-streaming-kinesis
Thanks..
Assuming you are trying to read the data from message queues like kafka or event hub.
If thats the case, when ever spark streaming application goes down, it will try to process the data from the offset it left before getting failed.
By the time, you restart the job - it would have accumulated more data and it will try to process all backlog data and it will fail either by Out of Memory or executors getting lost.
To prevent that, you can use something like "maxOffsetsPerTrigger" configuration which will create a back pressuring mechanism there by preventing the job from reading all data at once. It will stream line the data pull and processing.
More details can be found here: https://spark.apache.org/docs/2.2.0/structured-streaming-kafka-integration.html
From official docs
Rate limit on maximum number of offsets processed per trigger
interval. The specified total number of offsets will be proportionally
split across topicPartitions of different volume.
Example to set max offsets per trigger
val df = spark
.read
.format("kafka")
.option("kafka.bootstrap.servers", "host1:port1")
.option("subscribe", "topicName")
.option("startingOffsets", "latest")
.option("maxOffsetsPerTrigger", "10000")
.load()
To process the backfills as soon as possible and catch up with real time data, you may need to scale up your infra accordingly.
May be some sort of auto scaling might help in this case.
After processing the backlogged data, your job will scale down automatically.
https://emr-etl.workshop.aws/auto_scale/00-setup.html

how to stream microphone audio from browser to S3

I want to stream the microphone audio from the web browser to AWS S3.
Got it working
this.recorder = new window.MediaRecorder(...);
this.recorder.addEventListener('dataavailable', (e) => {
this.chunks.push(e.data);
});
and then when user clicks on stop upload the chunks new Blob(this.chunks, { type: 'audio/wav' }) as multiparts to AWS S3.
But the problem is if the recording is 2-3 hours longer then it might take exceptionally longer and user might close the browser before waiting for the recording to complete uploading.
Is there a way we can stream the web audio directly to S3 while it's going on?
Things I tried but can't get a working example:
Kineses video streams, looks like it's only for real time streaming between multiple clients and I have to write my own client which will then save it to S3.
Thought to use kinesis data firehose but couldn't find any client data producer from brower.
Even tried to find any resource using aws lex or aws ivs but I think they are just over engineering for my use case.
Any help will be appreciated.
You can set the timeslice parameter when calling start() on the MediaRecorder. The MediaRecorder will then emit chunks which roughly match the length of the timeslice parameter.
You could upload those chunks using S3's multipart upload feature as you already mentioned.
Please note that you need a library like extendable-media-recorder if you want to record a WAV file since no browser supports that out of the box.

AWS Media Live - handle stream start and stop events

I cannot find any information how to handle the situation like this:
Stream starts: about 3 o'clock.
1.Before the person who is streaming (let's call him a streamer) start to stream I would like to have static image saying something like: 'The event will start soon'.
2.Streamer start pushing his stream to RTMP endpoint but he's late and starts at 3.02. Up until 3.02 the same picture should be visible (as in point 1).
3.Streamer should finish at 4 o'clock but he finishes 5 minutes before 4 (pushing stop at his device).
4.Now, ending screen should be visible from 5 minutes to four and later.
I know that inputs should be switched in order to change a view and this can be scheduled for fixed time, but I would like this to be switched dynamically, ie. when streamer starts pushing to RTMP URL and stops pushing to RTMP URL (from eg. Larix software). How to handle that in AWS Media Live?
Thank you for asking this question on stackoverflow, the easiest way to achieve what you are looking to do is by using an Input Prepare Scheduled Action. The channel will then monitor the input and raise an alarm if the RTMP source is not there. When the RTMP source begins then the alarm will remit, you can send the alarms to a lambda that will look for these alarms and can do the switch from slate MP4 to the RTMP source when it sees the RTMP input missing alarm was cleared. This can also be done for when RTMP input goes away.
Information on Prepare Inputs:
https://docs.aws.amazon.com/medialive/latest/ug/feature-prepare-input.html
Global configuration - Input loss behavior:
https://docs.aws.amazon.com/medialive/latest/ug/creating-a-channel-step3.html
Zach

Once only notification with DeliveryDelay with AWS SQS

In a web application, people upload files to be processed. File processing can take anywhere between 30 seconds and 30 minutes per file depending on the size of the file. Within an upload session, people upload anywhere between 1 and 20 files and these may be uploaded within multiple batches with the time lag between the batches being up to 5 minutes.
I want to notify the uploader when processing has completed, but also do not want to send a notification when the first batch has completed processing before another batch has been uploaded within the 2-5 minute time period. Ie. the uploader sees himself uploading multiple batches of files as one single "work period", which he may only do every couple of days.
Instead of implementing a regular check, I have implemented the notification with AWS SQS:
- on completion of each file being processed a message is sent to the queue with a 5 minute delivery delay.
- when this message is processed, it checks if there is any other file being processed still and if not, it sends the email notification
This approach leads to multiple emails being sent, if there are multiple files that complete processing in the last 5 minutes of all file processing.
As a way to fix this, I have thought to use an AQS SQS FIFO queue with the same Deduplicationid, however I understand I need to pass through the last message with the same Deduplicationid, not the first.
Is there a better way to solve this with event driven systems? Ideally I want to limit the amount of queues needed, as this system is very prototype driven and also not introduce another place to store state - I already have a relational database.
You can use AWS StepFunctions to control such types of workflows.
1. Upload files to s3
2. Store jobs in DynamoDB
3. Start StepFunction flow with job Id
4. Last step of flow is sending email notification
...
PROFIT!
I was not able to find a way to do this without using some sort of atomic central storage as suggested by #Ivan Shumov
In my case, a relational database is used to store file data and various processing metrics, so I have refined the process as:
on completion of each file being processed a message is sent to the
queue with a 5 minute delivery delay. The 5 minutes represents the largest time lag of uploads between multiple file batches in a single work session.
when the first file is processed, a unique processing id is established, stored with the user account and linked to all files in this session
when this message is processed, it checks if there is any other file being processed still and checks if there is a processing id against he user.
if there is a processing id against the user, it clears the processing ids from the user and file records, then send

Echo Spot sometimes takes minutes to start playing a video

I'm currently developing a custom skill for the echo spot. I'm using AWS Lamda functions in .net core, using the Alexa.NET SDK. One of the intents lets Alexa play a video, which are hosted on a S3 bucket, but sometimes (randomly - once after opening the skill, once after the 4th or 5th video), Alexa immediately understands the command, but takes ages to play the video. According to the cloudwatch logs, the command is parsed and the lambda function executed within a couple of milliseconds, but the video starts playing very delayed (up to two minutes).
REPORT RequestId: xyz Duration: 366.44 ms Billed Duration: 400 ms Memory Size: 576 MB Max Memory Used: 79 MB
The videos being returned by the lambda function are rather short (5-15 seconds) if that could affect the issue. The wifi itself is stable with more than 30mbit available, alexa is not too far away from the wifi router.
We've tried different video encodings (MP4, H264, ...), different audio codecs, samplerates and framerates - the issue remains. Any clues what could cause this issue? We've read the recommendations for videos and applied all the recommended settings to the video.
Can i somehow access the device's logs to see if there's another issue with the video?
Turns out, videos are being streamed when combined with a plain text output speech. If your output speech is empty, the echo spot will download the whole video and start playing once the video is completely loaded. Hence, i recommend adding a speech reply to all of your videos to ensure a smooth loading of the video.