Я пытаюсь ускорить создание файла с моим видео. Моя проблема в том, что file_put_contents занимает слишком много времени для создания видеофайла размером в среднем 50 МБ. Мой код ниже сначала декодирует видео и помещает его в каталог. $ Видео - байтовый массив. Есть ли способ создать видеофайл без декодирования base64 и что я могу сделать, чтобы ускорить создание файла?
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$CAFNo = $json_obj->CAFNo;
$Date = $json_obj->CAFDate;
$Video = $json_obj->Video;
$CafDate = date("Y-m-d", strtotime($Date));
$video_decode = base64_decode($Video);
$video_filename = __DIR__ . '/uploads/'. $CAFNo . '_'.$CafDate.'_VID.mp4';
$save_video = file_put_contents($video_filename, $video_decode);
$video_dbfilename = './uploads/'. $CAFNo . '_'.$CafDate.'_VID.mp4';
$sql = "UPDATE tblCaf SET Video = '$video_dbfilename' WHERE CAFNo = '$CAFNo'";
mysqli_query ($conn, $sql);
средний размер файла 50 МБ @Dave
Скорость будет связана с оборудованием, на котором вы запускаете код. В любом случае, слишком долго - это очень субъективно.
@ Дэйв, есть ли что-то, что я могу сделать в своем коде, чтобы хоть немного ускорить процесс?
@JonStirling, могу ли я использовать вместо этого fwrite ()? это быстрее?
И file_get_contents(), и file_put_contents() подразумевают загрузку всего видео в RAM. Использование таких функций бесполезно, старые добрые fopen() и fread() - единственный разумный механизм. (Почему вообще Base64?).
1) Вероятно, нет 2) Почему бы не попробовать и не посмотреть, а не спросить меня 3) Я не уверен, что вы читали мой комментарий.
@ ÁlvaroGonzález, как я могу его использовать, вы можете показать мне, просто чтобы получить общее представление






Медиа-файл может быть огромным, поэтому вы не можете обработать его методами, которые включают загрузку всего файла в ОЗУ, не говоря уже о том, чтобы иметь несколько копий данных одновременно. Ваш код делает это несколько раз.
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$Video = $json_obj->Video;
$video_decode = base64_decode($Video);
На данный момент у вас есть 4 копии видео, загруженные в RAM. Для мультимедийного файла размером 50 МБ это означает, что $video_decode содержит 50 МБ данных, а другие переменные даже больше. Вам также необходимо добавить внутреннюю память, используемую такими функциями, как json_decode(). Чтобы получить представление об используемой оперативной памяти, вы можете вставить это между каждой операцией:
var_dump(memory_get_usage(true));
Кроме того, современные видеокодеки представляют собой высокооптимизированные двоичные потоки. Если вы конвертируете эти двоичные данные в обычный текст, размер увеличится. Base64 увеличивает объем данных на 4/3. JSON добавляет небольшие накладные расходы, хотя на данный момент ничего серьезного.
Если бы мне пришлось разрабатывать это с нуля, я бы использовал POST запрос с двоичным форматом (либо multipart/form-data, либо пользовательскую кодировку, возможно, просто файл как есть), а затем просто читал ввод по частям:
multipart/form-dataPHP делает всю работу.Если вы предпочитаете или хотите придерживаться текущего дизайна, вам нужно адресовать все операции чтения и декодирования файлов по частям:
base64_decode(), если у вас обрабатывать это по частям.И последнее, но не менее важное: никогда не создавайте код SQL, вводя ненадежный внешний ввод:
$sql = "UPDATE tblCaf SET Video = '$video_dbfilename' WHERE CAFNo = '$CAFNo'";
Вместо этого используйте подготовленные операторы. Орды руководств, которые говорят об обратном, давно должны были сгореть.
Обновлять: Кажется, что концепция обработки данных небольшими порциями (вместо загрузки всего в память) не так проста, как я думал, поэтому я предоставлю исполняемый код, чтобы проиллюстрировать разницу.
Прежде всего, давайте создадим файл размером 100 МБ для тестирования:
$test = __DIR__ . '/test.txt';
$fp = fopen($test, 'wb') or die(1);
for ($i = 0; $i < 1839607; $i++) {
fwrite($fp, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n") or die(2);
}
fclose($fp);
Если вы прибегаете к простым в использовании однострочным вспомогательным функциям:
ini_set('memory_limit', '300M');
$test = __DIR__ . '/test.txt';
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
$data = file_get_contents($test);
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
file_put_contents(__DIR__ . '/copy.txt', $data);
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
printf("Maximum memory usage: %d MB\n", memory_get_peak_usage(true) / 1024 / 1024);
... это происходит ценой потенциально большого количества памяти (нет ничего лучше бесплатной еды):
Current memory usage: 0 MB
Current memory usage: 100 MB
Current memory usage: 100 MB
Maximum memory usage: 201 MB
Если разделить файл на небольшие части:
$test = __DIR__ . '/test.txt';
$chunk_size = 1024 * 1024;
$input = fopen($test, 'rb') or die(1);
$output = fopen(__DIR__ . '/copy.txt', 'wb') or die(2);
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
while (!feof($input)) {
$chunk = fread($input, $chunk_size) or die(3);
fwrite($output, $chunk) or die(4);
}
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
fclose($input);
fclose($output);
printf("Current memory usage: %d MB\n", memory_get_usage(true) / 1024 / 1024);
printf("Maximum memory usage: %d MB\n", memory_get_peak_usage(true) / 1024 / 1024);
... вы можете использовать фиксированный объем памяти для файлов любого размера:
Current memory usage: 0 MB
Current memory usage: 1 MB
Current memory usage: 1 MB
Maximum memory usage: 3 MB
Можете ли вы направить меня с помощью кода, который я не знаю, как использовать fread () в цикле
Просто скопируйте и вставьте последний пример из документации.
кто может создавать видео по кускам?
Как создается видео путем обработки данных по частям?
@LawrenceAgulto Я только что обновил свой ответ. Если я все еще не могу объяснить себя, укажите, в чем именно у вас возникли трудности.
Я запутался в назначении $ input и $ output
Это стандартные термины в информатике (я уверен, что вы видели аббревиатуру I / O много раз). «Ввод» - это место, откуда вы читаете, а «выход» - это место, куда писать.
Итак, я буду использовать fopen () my $ Video, мой код будет $ input = fopen ($ Video, 'rb') или die (1);, это правильно?
Дайте определение «занимает слишком много времени». Насколько велик создаваемый вами файл?