-2

I am using file_put_contents to create a video file. the problem is the speed and performance. It takes about an average of 30 to 60 minutes for an average file size of 50 mb to be created and that is just for one file alone. I am decoding a byte array to create the file. How can I improve the speed and performance?

$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$Video = $json_obj->Video;
$CAF = $json_obj->CAF;
$Date = $json_obj->Date;
$CafDate = date("Y-m-d", strtotime($Date));

$video_decode = base64_decode($Video);
$video_filename = __DIR__ . '/uploads/'. $CAF . '_'.$CafDate.'_VID.mp4';
$video_dbfilename = './uploads/'. $CAF . '_'.$CafDate.'_VID.mp4';
$save_video = file_put_contents($video_filename, $video_decode);

2 Answers2

1

You should not load entire files to the memory when you can't foresee the size or when it's going to handle huge files. It's better to read the file in chunks and process it chunk by chunk.

Here's a quick and dirty example of how to achieve it:

<?php
// open the handle in binary-read mode
$handle = fopen("php://input", "r");

// open handle for saving the file
$local_file = fopen("path/to/file", "w");

// create a variable to store the chunks
$chunk = '';

// loop until the end of the file
while (!feof($handle)) {
  // get a chunk
  $chunk = fread($handle, 8192);

  // here you do whatever you want with $chunk
  // (i.e. save it appending to some file)
  fwrite($local_file, $chunk);
}

// close handles
fclose($handle);
fclose($local_file);
0

There are many problems here, with a compounding effect.

$json_str = file_get_contents('php://input');

This reads the entire input into memory, and blocks until it's done. Don't do this.

$json_obj = json_decode($json_str);

If you have 50MB of JSON, you're probably doing something wrong.

$Video = $json_obj->Video;

This is what you're doing wrong... storing a large binary blob in a small structured data serialization format. You realize that the JSON parser has to read and handle the entire thing? Don't send JSON for this!

$video_decode = base64_decode($Video);

Don't use base-64 encoding unless absolutely necessary. It adds 33% overhead to the storage size, as well as CPU for encoding/decoding. This is a complete waste, and is totally unnecessary.

$video_filename = __DIR__ . '/uploads/'. $CAF . '_'.$CafDate.'_VID.mp4';
$video_dbfilename = './uploads/'. $CAF . '_'.$CafDate.'_VID.mp4';

You may have a serious security issue with those two lines. What if someone posts a path of ../../../etc/init.d/something-evil? Don't let the user dictate the filename on disk in any way.

$save_video = file_put_contents($video_filename, $video_decode);

The comment from file_get_contents() applies here in that you should be using this method. Stream the contents to disk instead.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • What can I do to fix this? –  Dec 19 '18 at 04:11
  • I really need to save the video to disk and save the path to my database –  Dec 19 '18 at 04:13
  • @LawrenceAgulto Stop sending your video as base-64 in JSON. Send it as regular binary. Use PHP's built-in handling of file uploads. – Brad Dec 19 '18 at 04:26
  • Can you show me how? And I am not sending my video as a base64 but a byte array –  Dec 19 '18 at 04:39
  • @LawrenceAgulto How could you be sending your video as a byte array, while your code clearly shows you're attempting to decode base64 and JSON? How could I possibly show you any more details when you've provided none of the client-side code? – Brad Dec 19 '18 at 05:05
  • The video is from my application in c# the only way to send the video to my server is to convert the video into a byte array and send it via Json there is no problem with creating the video itself the problem is the speed How can I improve my code to optimize the speed? –  Dec 19 '18 at 06:16
  • @LawrenceAgulto I've given you a point-by-point explanation of why your code isn't performing as well as it could, as well as a list of steps to resolution. Why are you ignoring that? Why do you think that there's no problem with this base64 encoded video in JSON? What you're complaining about is akin to putting a race car on a barge and complaining that it cannot go 180 MPH down the river. – Brad Dec 19 '18 at 15:08
  • @LawrenceAgulto Your statement, "the only way to send the video to my server is to convert the video into a byte array and send it via Json", is absolutely false. You have at least two other good ways to do this. The easiest in the context of PHP, and the most appropriate in your case, is to use a `multipart/form-data` request body. It's trivial for you to do in C#. https://stackoverflow.com/a/19983672/362536 Another way to do it is just send the binary data itself as the request body. There you would have the downside of reading the input stream in your non-native PHP code. – Brad Dec 19 '18 at 15:12
  • I really need help I dont know what else im going to do –  Dec 19 '18 at 16:26
  • @LawrenceAgulto I've listed this out for you step-by-step and you keep rejecting the solutions right in front of you. I give up. If you were actually interested in solving this yourself, you would ask specific questions about anything you specifically don't understand. Sounds like you should just hire someone to build this for you, since you don't actually want to learn. – Brad Dec 19 '18 at 16:27
  • I want to learn I just need a code to guide me to get me started the problem is file_put_contents is taking so long thats all I just want to make my code optimize I just really dont know where or how to start –  Dec 19 '18 at 16:30
  • @LawrenceAgulto That's only part of your problem and if you'd just read what I wrote in my answer, you'd understand that you can *skip that entire step and let PHP do it for you* if you'd just send the data correctly in the first place. The easiest way to optimize something is just eliminate it. – Brad Dec 19 '18 at 16:35
  • @LawrenceAgulto What do you expect me to tell you? That there's some magic `make_it_go_faster()` function in PHP that you forgot to use, so you can just change one line and solve all of your problems? That's not how it works. You've architected this poorly. Several of us have indicated this to you on this, and all of your repeated duplicate questions. We've also indicated to you how to fix it. Instead, you're fixated on something you believe is the problem, which isn't. – Brad Dec 19 '18 at 16:37
  • I converted the video file into a byte array and just sending it via JSON. The sending process is fast the problem is just to convert the byte array into a video file –  Dec 19 '18 at 16:39
  • can you remote my computer so that you can see my whole code? –  Dec 19 '18 at 16:45
  • Download anydesk or teamviewer and I will show you the whole code my C# and PHP code –  Dec 19 '18 at 16:46
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/185501/discussion-between-lawrence-agulto-and-brad). –  Dec 19 '18 at 16:47
  • @LawrenceAgulto Sure. I have some availability in January. My consulting fee is $250/hr., and it's probably a 4-5 hour project to fix your code and explain the changes to you. – Brad Dec 19 '18 at 16:47