myfunction почти наверняка установлена как функция обратного вызова CURLOPT_WRITEFUNCTION для curl_exec, и если эта функция возвращает 0 (или любое другое число, кроме размера $ data), то curl прекратит передачу, а curl_exec вернет CURLE_ABORTED_BY_CALLBACK
код ошибки. таким образом, после того как вы загрузили> = 1 мегабайт, curl_exec остановится с ошибкой CURLE_ABORTED_BY_CALLBACK.
What I really want to do is download a certain percentage of the file, something like 2%, so that I can guarantee that I will get the first frame.
- в зависимости от кодировки фильма первого мегабайта может быть недостаточно. Существуют некоторые схемы кодирования (например, фильмы .mpeg могут быть закодированы таким образом), где вам нужно несколько байтов от конца файла для рендеринга первого кадра (iirc для .mpeg это называется MOOV Atom
- on Фильмы mpeg, в которых атом MOOV находится в конце файла, вам нужно несколько байтов от конца файла для рендеринга первого кадра. Для всех потоковых фильмов .mpeg, оптимизированных для потоковой передачи, атом MOOV находится в начале файла. , не конец, и ваша 1st mebibyte
схема будет работать, но если она будет в конце, ваша схема не будет работать, если весь фильм не будет <1 мегабайт) </p>
- гораздо лучший подход - просто позволить ffmpeg справиться с этим. ffmpeg будет знать, сколько данных нужно загрузить, и попытается загрузить только необходимые части, а не весь фильм, и вам понадобится программа наподобие ffmpeg, чтобы в любом случае извлечь первый кадр позже.
попробовать
function getFirstFrameAsJpg(string $url):string{
if(file_exists("/dev/null")){
$ret=shell_exec("ffmpeg -i ".escapeshellarg($url)." -f image2pipe -frames 1 -r 1 -c:v:1 jpeg - 2>/dev/null");
}else{
// windows, probably, where /dev/null isn't supported but NUL works the same way.
$ret=shell_exec("ffmpeg -i ".escapeshellarg($url)." -f image2pipe -frames 1 -r 1 -c:v:1 jpeg - 2>NUL");
}
return $ret;
}
вернет первый кадр видео в URL как двоичный файл для изображения .jpg. (что означает, что вы можете сделать file_put_contents('image.jpg',getFirstFrameAsJpg($url));
- интересно, если ffmpeg не установлен, $ ret будет NULL, что означает, что если вы используете strict_types = 1, вы получите исключение, в противном случае вы получите пустую строку.)
ps, прежде чем вы позволите потенциальным хакерам указать URL-адрес для этой функции, убедитесь, что он действительно является http-URL, поскольку я не учитывал последствия для безопасности, позволяющие хакерам запускать getFirstFrameAsJpg("/etc/passwd")
или подобное.
если вам нужно скачать с кучей заголовков, рассмотрите возможность настройки прокси-схемы для ffmpeg, где вместо этого ffmpeg предлагается загружать с уникального URL-адреса прокси-сервера, и пусть ffmpeg определяет, какие части фильма загружать, и убедитесь, что для такого прокси реализован заголовок диапазона http , так как ffmpeg понадобится, если для извлечения 1-го кадра из фильма требуется последняя часть фильма, чтобы извлечь первый кадр.
(спасибо c_14 @ freenode #ffmpeg за команду image2pipe)