Stream mp3s From Firebase Storage - android

Issue
I am building a backend service that creates mp3s for an Android client to stream via ExoPlayer.
Looking at Firebase's Storage Pricing in the long term, if there are 10 gbs stored and 10,000 users there would be 100,000 gb to transfer which is very expensive ($11,600).
What would be the best solution to stream mp3s on the cloud in order to avoid data transfer fees?
Possible Solutions
Use ExoPlayer to stream mp3s directly from the cloud without downloading.
Use a separate API to download the 10gb from Cloud Storage one time, and stream the mp3s to the mobile client from the separate API.

Possible solution #1 is the best solution: Use ExoPlayer to stream mp3s directly from the cloud without downloading.
Thank you Oliver Woodman on the ExoPlayer team for resolving this question on Github!
If a mp3 file is saved to the cloud, ie:Firebase Storage / Google Cloud Storage, can the file be streamed from Exoplayer without needing to download the full file size?
Yes. That's just what happens by default when you use ExoPlayer to play a stream.
If the mp3 can be streamed directly from Cloud Storage roughly what percentage of memory of the file is used in the transfer of the stream since the file itself is not being downloaded?
You can configure this by instantiating your own DefaultLoadControl, which you can pass to ExoPlayerFactory.newSimpleInstance when building the player. You can also implement your own LoadControl from scratch if you need more control.
Note that whilst buffering less far ahead saves on data transfer costs, it also makes re-buffers more likely to occur because the player will be less able to ride out temporary network connectivity issues.

Related

Is it possible to record mp3 files with an android app and store this mp3 in a DynamoDB?

So I have two questions.
First, is it possible to record mp3 in an android app and how?
Second, is it possible to store this mp3 in a DynamoDB from the Android App and how?
you can store binary data in DynamoDB yet there is a limit. Maximum size of item in DynamoDB is 400KB, which is not that much for an mp3.
You are also charged by WCU & RCU, every 4KB is single RCU and every 1KB to write is single WCU, or 2 WCUs if you write with transactional write.
Better save mp3 to S3 and save meta data to DynamoDB. You will be able to store any mp3 up to 5Tb in size. Will be able to utilize it's store classes to get the most cost-effective way to save that file too. DynamoDb is not great to store big files, it's best for high-velocity data because of it's infinity scale.
If you will end up uploading mp3 to S3, you should google around S3 presigned URLs too. That way you can keep your mp3 private and just get the private link for a short period of time so the user could download mp3 from s3 directly. Passing it through lambda will cost more $ and lambda also has it's file limits, won't be easy to pass through 100mb of mp3, which you may or may not have :)
Also to Upload the mp3 to S3 if you will be using lambda, you will be able to upload max 6Mb. While that's the limit of lambda's payload. Just use S3 presigned URLs to provide direct upload link from user to S3 bucket.
Yes!
First you need to actually record the audio, use a library or refer to the Android docs to record it.
After that you will have a audio file that you need to upload to your database, I'm not personally a fan of uploading direct raw data into the database, I'm not a skilled dynamoDB but I don't think you can save blobs in a document.
I'd recommend to create an API, AWS has API Gateway and Lambdas you may use them to get the file uploaded from the Android device and store it on S3 and save the document reference to your DynamoDB

Video Streaming from Google Cloud Storage

How would we go about getting a video from google cloud storage and streaming that video to a mobile device?
I dont see anything related to videos in the Java API like there is for getting images with ImagesServiceFactory
The videos are only going to be a maximum of 10-15 seconds long if that makes any difference.
Any advice on how to proceed here would be great
There is no difference between streaming a video and downloading any other file from the Cloud Storage. Thus, no special video API.
If the files are not public, you need a servlet that will read the content of the video from Cloud Storage and stream it to the client. Note that you cannot run it on App Engine or managed VM as they do not support file streaming and the request size is limited to 32MB.
Your best option is to run this on a Compute Engine instance:
Bandwidth between Compute Engine and Cloud Storage is free.
Authentication is simple.
Alternatively, you may use a signed URL for your video files. This saves you from developing/deploying a separate Compute Engine instance just for the streaming purposes - signed URLs can be returned by your existing backend.

stream video on device bytewise to videoview - Android

I want to play encrypted video files present on my device after decrypting them. I want to pre-process the data-stream and parallel play it using videoview like streaming video from Internet.
Is there any way I could buffer the processed data to videoview like a network stream ?
I think you are saying that you want to decrypt the video in one process and then pass the decrypted 'clear stream' video to another process to play it?
If the video is DRM protected, then your use case is very unlikely to be supported by any of the leading DRM solutions - they go to great lengths to ensure the clear stream video is not accessible by an application on the device (for obvious reasons).
If you are using or a simple encryption with the encryption key available to your application then you should be able to do this.
Update
Answering BMvit's question in the comment - one way is to follow these steps:
Stream the encrypted file from the server as usual, 'chunk by chunk'
On your Android device, read from the stream and decrypt each chunk as it is received
Using a localhost http server on your Android device, now 'serve' the decrypted chunks to the MediaPlayer (the media player should be set up to use a URL pointing at your localhost http server)
I am guessing this is the most likely the approach that the libMedia library uses, although I have never seen the source so I could not say for sure: http://libeasy.alwaysdata.net
It is worth being aware that this is tricky (which is probably why LibMedia is not free).

How to play an encrypted video file in Android

I searched through a lot of questions on SO but I can't find the answer, that's why I ask the following question:
An Android app should be able to play an encrypted video file (stored on the SD card and retrieved from a webserver).
The file has to be stored on the SD card so that the app can play the video file without having an active internet connection.
Because the video files may not be copied, the plan is to encrypt them server side when uploading the files to a webserver.
What is the best option?
1) I have seen suggestions for running a local webserver which decrypts the file (and how to do this?)
2) or should we decrypt the file, save it as a temporary file and set this temporary file as the source for the videoplayer?
3) something completely different?
You are trying to implement a DRM scheme, and a naive one at that. Look into DRM schemes and report back if you cannot implement the impossible. All you can hope for is obfuscation, and there are plenty of ways of doing that (none of them are secure of course).
What you need is DRM. Digital Rights Management (DRM) controls the access to your digital content such as video. Firstly, you need to encrypt the video with an encryption video like AES-128. Then with the use of DRM play in exoplayer. Exoplayer has DRM support. you can check here. https://exoplayer.dev/drm.html
You will expose the user to a waiting time if you choose to decrypt a entire big video beforehand. As of the security, you can guess it's a poor idea to have the contents in clear in a file, even temporary. The local webserver is a better choice because it's a streaming method, so without file storage. There is no class for an http server in the SDK, you have to implement your own one, otherwise look for an existing library similar to LocalSingleHttpServer.

Securing Video in android

Im presently working on an android application which will allow the user to download video and audio content from a server and play them on the phone of the end user.
What I'm trying to do is to secure the audio and video. The files should not be accessible to other applications and the user must not be able to take them off the device and use them.
This is a shot in the dark but can i do this by storing the videos in theSQLLite database as blobs.
And also is it possible to play the videos in android if they are stored as blobs.
I wouldn't use blobs, they are only performant if the binary-files are 256KB or less.
I guess the only way to make the videos secure so the user can't use them is to stream them down from you'r server and deleting the buffer when the Application closes.
On a rootet Device, you have access to every directory, so you can't save the videos on the SDcard or the Phone-Memory.

Categories

Resources