Streaming video from server to mobile using base64 - php

We are building an application that deals with images and videos and the privacy requirement is high , where users are not allowed to gain access to the images and videos at all time (privacy option) ,
therefore we went with the option of having a php api that clients request the file and the api returns a base64 encoded response that the client decode and display ,that is for image side ,as for video we are having a trouble finding the right logic .
does VideoView in android helps me achieve this ?
does the api needs to send the video in chunks instead of one large base64 ?
is base64 even right for this requirement ,noting that user should not have direct access to the file at all times .
php api function :
function viewFile($data) {
$file = file_get_contents($data['file_path']);
$mime = mime_content_type($data['file_path']);
return ['status' => 200, 'file' => ['mime' => $mime, 'base64' => base64_encode($file)]];
}

Security with base64? That does not exist. I made a text (in Portuguese) that might help you. Read.
I do not recommend using a very large base64. The server will have a lot of load, the download will be slow, etc.
The ideal is to divide it into smaller pieces. For this you can use bento4 e o ExoPlayer.
For images, I recommend using Cipher. More information for Android and More information for PHP
I made this code to encrypt images. It is already quite old, but I think I can help you enteder this issue.
https://github.com/valdeirpsr/estudo-openssl/blob/master/library/OpensslEncrypt/OpensslEncrypt.php

Related

How can I save an image received from a Webhook? (WhatsApp API)

So, I'm starting to understand a bit more of WhatsApp API and all the messages that my number received are sent to my server via Webhook. The text messages are fine, but I'm struggling with the media messages.
When the user sends an image for example, Facebook's Webhook only sends me the mime_type and the sha256 of the image.
Can anyone please guide me the steps of what I need to do?
Do I need to convert it to base64, and then write the file in my server? Do I need to use a specific function? Do I need to use another programming language that's not PHP?
I'm totally lost on this one.
The way to do this, as pointed out by #CBroe is to use the media endpoints.
Assuming message is the message from the Webhook
// Get the image information, including the download link
$image_url_handle = fopen("https://graph.facebook.com/v13.0/" . $message->id);
$image_url = "";
// Read all of the data before parsing
while (!feof($image_url_handle)) {
$image_url .= fread($image_url_handle);
}
// Close the stream
fclose(image_url_handle);
// Get the url from the image information
$image_url = json_decode($image_url)->url;
// Start a request to the download URL.
$image_stream = fopen($image_url);
Note: There is no error handling or frameworks, though this should work most of the time

Dynamic S3 Link for downloading or viewing a PDF

I am storing some customer PDFs in S3 for multiple parties to either view in the browser or download. The trouble is I can only get a single file in S3 to either always download or always view in the browser.
I could just upload the same file twice with each having its own ContentDisposition, but that seems wasteful when ideally it could be as simple as adding something like ?ContentDisposition=inline to the public bucket URL.
My Question: How can dynamically set a ContentDisposition for a single S3 file?
For context, my current code looks something like this:
$s3_object = array(
'ContentDisposition' => sprintf('attachment; filename="%s"', addslashes($basename)),
'ACL' => 'public-read',
'ContentType' => 'pdf',
'StorageClass' => 'REDUCED_REDUNDANCY',
'Bucket' => 'sample',
'Key' => static::build_file_path($path, $filename, $extension),
'Body' => $binary_content,
);
$result = $s3_client->putObject($s3_object);
Also, I did try to search for this elsewhere in SO, but most people seem to just be looking for one or the other, so I didn't find any SO answers that showed how to do this.
I ended up stumbling across the definitive answer for this today (over a month later) while looking at other S3 documentation. Going to the GetObject docs for the S3 API and under the section labeled "Overriding Response Header Values" we find the following:
Note: You must sign the request, either using an Authorization header or a presigned URL, when using these parameters. They cannot be used with an unsigned (anonymous) request.
response-content-language
response-expires
response-cache-control
response-content-disposition
response-content-encoding
This answer's how to dynamically change any S3 object's content-disposition in the URL. However, at least for me, this is an imperfect solution because my intended use case was to store the URL for years as part of an invoicing archive, but signed URLs are only valid for a maximum of 1 week.
I could technically also try to find a way to make the Authorization header work for me or just query the S3 API to get a new signed URL every time I want to link to it, but that has other security, performance, and ROI implications for me that make it not worth it.

How to send big files from URL to Telegram bot?

I have some big size files (in MP4 and Zip formats) and I want to send them to my chat by Telegram bot, I used the code below:
file_get_contents('https://api.telegram.org/bot[[app:token]]/sendDocument?chat_id=24523586&document='.$fileAddress);
But it just can send files with small sizes, less than 50MB! But I know there is no file size limitation for documents which are sending by file_id. You can see this page
Now how can I make file_id for my files? My files are uploaded on my server and I am using PHP.
Telegram bot API can only send files less than 20 MB by url param, you should lookup Sending Files section.
If you want to send 20-50 MB files, you should download and re-upload to Telegram bot API server.
You can refer this simple code
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.telegram.org/bot131210513:AXXXXXX/sendDocument?caption=Hello+World&chat_id=24523586',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: multipart/form-data'
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => [
'document' => curl_file_create('/etc/hosts', 'plain/text', 'Hosts-file.txt')
]
]);
$data = curl_exec($curl);
curl_close($curl);
2021 Update: Telegram now provides a self hostable Telegram Bot API which can upload 1.5GB.
You can install pwrtelegram on your server. Then simply switch the API URL and you will be able to upload up to 1.5 GB of files with your bot. That is the only possible way. Check out the link for more information.
Also, you cannot pass in any random file_id, as Telegram will not send it. You can only pass in a file_id which has been uploaded by your bot previously. To bypass the limit, use the method, above. It works very well.
Firstly you should send your file(s) to your bot and then get the fileID.
After that you can just use the fileID to send your files and this way the load will be on Telegram's server not yours. Of course you can send the files from your own server to but this method will cause speed reduction for your bot.
Note that when you send a file to your bot and get the fileID, from that moment the file can be sent immediately without needing to store the files on your own server.
You don't need to make a fileID.
All you need is sending the file to the bot and let the bot find out
the fileID and save it somewhere for future transfers.

YouTube v3 API: Age restriction when uploading video

It's possible to set age restriction individually/manually via the Web UI, but it's not possible to set globally for a channel or account as far as I can see.
Is it possible to set via API when uploading a video?
The point is to avoid banning if I upload a video on behalf of another user, and I don't get time to screen the video.
Thanks in advance,
Anders
Update 1:
This is how I found I should do, according to https://developers.google.com/youtube/v3/docs/videos:
$contentRating = new Google_Service_YouTube_ContentRating();
$contentRating->setYtRating('ytAgeRestricted');
$details = new Google_Service_YouTube_VideoContentDetails();
$details->setContentRating($contentRating);
$video->setContentDetails($details);
Remarkably there's not a single example of use of Google_Service_YouTube_VideoContentDetails anywhere.
When this data is added to the video, the upload fails with the following. Clearly YouTube didn't like my setting. Is the use of age-restriction in itself restricted?
Google_Exception::__set_state(array(
'message' => 'Failed to start the resumable upload (HTTP 400: youtube.part, contentDetails)',
'string' => '',
'code' => 0,
'file' => '/home/u/u6554025/www/twitizer.com/Google/Http/MediaFileUpload.php',
'line' => 300,
Update 2:
That's a bummer if true:
http://gadgetsytecnologia.com/de585c5edb2f3a366/uploading-video-via-youtube-api.html
"You can read this property as: contentDetails.contentRating.ytRating = "ytAgeRestricted" but it looks like you can't POST this property in the video Resource in the body of your POST request to Youtube API"
Neither does the official documentation mention that insert supports contentRating.
Live and learn. Adopt, adapt, improve.
If anyone has any idea how to circumvent this, possibly with a global setting for the channel, I'm all ears.
Thanks,
Anders

Video Recording from Browser using Flash, PHP, Red5

I wish to build an application using which I can record video (along with audio) and also audio (only audio preferably in mp3 format).
From some research I did, I found I need a client app in flash or flex, a RTMP Server (RED5 preferable as its free)
This is the code which I used to get cam working flash.
var camera:Camera = Camera.getCamera();
var video:Video = new Video();
video.attachCamera(camera);
addChild(video);
The problem is, I don't know how to send the stream to RED5.
Also, what do I need to do so that I can store the video according to the user. The website I am creating is in PHP/MySQL and need to have their own videos and audios recorded. I love the way facebook has integrated Video Recording.
Check this: http://www.actionscript.org/resources/articles/615/2/Getting-started-with-red5-server/Page2.html
It explains how to connect and use RED5 and gives you an example.
Here's the exact AS3 code for publishing video from Flash to a media server like Red5, Wowza or AMS:
//init vars
public var nc:NetConnection;
public var ns:NetStream;
//net connection to media server
nc = new NetConnection();
nc.connect("rtmp://yourmediaserver/oflaDemo/instance");
//net stream through which the recording data is sent
ns = new NetStream(nc)
//attach cam and mic to net stream
ns.attachCamera(Camera.getCamera())
ns.attachAudio(Microphone.getMicrophone())
//send the data to the media server
ns.publish("streamName","record");
For just audio comment the ns.attachAudio line .
Flash Player can't encode mp3 sound (it can decode). You'll get sound encoded with NellyMoser ASAO. Speex is also an option. See this answer for more details.
oflaDemo is a Red5 app that supports video recording that's shipped with Red5.
For a (commercial) Flash/HTML video recording solution that supports Red5 and PHP you should check out https://hdfvr.com.
Also, what do I need to do so that I can store the video according to the user.
Just execute a PHP script (from the Flash client) that saves the info in the database. You can use POST or GET to send the video data and sessions or cookies to retrieve the user data.
var video:Video;
var camera:Camera = Camera.getCamera();
camera.addEventListener(ActivityEvent.ACTIVITY, active);
video = new Video();
video.attachCamera(camera);
function active(event:Event):void
{
addChild(video);
camera.removeEventListener(ActivityEvent.ACTIVITY, active);
}

Categories