php video upload и ffmpeg не создадут миниатюру - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь создать функцию загрузки видео для моего проекта. Но у меня проблема с разделом ffmpeg . ffmpeg уже установлен на моем сервере. Но я не могу получить миниатюру. Я попытался создать эскиз, используя следующий код:

$videoa = exec("/usr/bin/ffmpeg  -i $videoUrlp.flv -f flv -s 650x390 $videoUrlp.mp4 2>&1");
$videob = exec("/usr/bin/ffmpeg  -i $videoUrlp.mp4 -vcodec png -ss 00:00:5 -s 650x390 -vframes 1 -an -f rawvideo $videoUrlp.png");

Но я получаю это при использовании var_dump(); для var_dump($videoa); и var_dump($videob);

строка (74) "https://mywebsite.com/uploads/video/ey1kXNew_video.flv: Ошибка ввода / вывода "string (0)" "

Также, если я использую shell_exec, как это:

$videoa = shell_exec("/usr/bin/ffmpeg  -i $videoUrlp.flv -f flv -s 650x390 $videoUrlp.mp4");
$videob = shell_exec("/usr/bin/ffmpeg  -i $videoUrlp.mp4 -vcodec png -ss 00:00:5 -s 650x390 -vframes 1 -an -f rawvideo $videoUrlp.png");

и var_dumps(), дающие мне NULL NULL.

Пожалуйста, помогите мне, где я не прав.

А вот мой полный код загрузки видео:

$valid_formats = array("mp4","MP4","flv");
            if(isset($_POST) and $_SERVER['REQUEST_METHOD'] == "POST") {
               $name = $_FILES['uploading']['name'];
               $size = $_FILES['uploading']['size'];
               if(strlen($name)) {
                   $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); 
                   $name = alphaID(microtime(true) * 10000).'_video';
                   if(in_array($ext,$valid_formats)) {
                   if($size<(50024*50024)) {
                      $GetVideoName = $name;
                      $video_ext=$ext;
                       $tmp = $_FILES['uploading']['tmp_name'];
                       if(move_uploaded_file($tmp, $videoPath.$GetVideoName.'.'.$video_ext)) {
                           $videoUrlp = $base_url.'uploads/video/'.$GetVideoName;
                           $videoa = exec("/usr/bin/ffmpeg  -i $videoUrlp.flv -f flv -s 650x390 $videoUrlp.mp4 2>&1");
                           $videob = exec("/usr/bin/ffmpeg  -i $videoUrlp.mp4 -vcodec png -ss 00:00:5 -s 650x390 -vframes 1 -an -f rawvideo $videoUrlp.png");
                           echo var_dump($videoa);
                           echo var_dump($videob);

                        } else {
                            echo "Fail upload folder with read access.";
                        }
                     } else
                        echo "Image file size max 1 MB";                    
                     } else
                        echo "invalidvieo"; 
                 } else
                    echo "Please select image..!";
                 exit;
              }

Я тестировал также так:

echo exec("/usr/bin/ffmpeg -i $videoUrlp.flv -ar 22050 -ab 32 -f flv -s 780x400 $videoUrlp.$video_ext");
echo exec("/usr/bin/ffmpeg -i $videoUrlp.$video_ext -deinterlace -an -ss 1 -t 00:00:05 -r 1 -y -vcodec mjpeg -f mjpeg $videoUrlp.png 2>&1");

и я вижу следующее эхо

video:71kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%

и еще одна попытка, затем я получаю эту заметку: https://mywebsite.com/uploads/video/1547892356_video.flv: Соединение отказано

echo exec("/usr/bin/ffmpeg -i $videoUrlp.flv -ar 22050 -ab 32 -f flv -s 780x400 $videoUrlp.$video_ext");
echo exec("/usr/bin/ffmpeg -i $videoUrlp.$video_ext -deinterlace -an -ss 1 -t 00:00:05 -r 1 -y -vcodec mjpeg -f mjpeg $videoUrlp.png 2>&1");

Вот последний вывод shell_exec:

 $local = 'https://website.com/uploads/video/'.$GetVideoName.'.'.$video_ext;
 $localTumb = 'https://website.com/uploads/video/'.$GetVideoName.'.png';
 echo shell_exec("/usr/bin/ffmpeg -i $local -deinterlace -an -ss 1 -t 00:00:05 -r 1 -y -vcodec mjpeg -f mjpeg $localTumb 2>&1");    

ffmpeg версия 2.8.15 Copyright (c) 2000-2018 разработчики FFmpeg, созданные с использованием gcc 4.8.5 (GCC) 20150623 (Red Hat 4.8.5-36) конфигурация: --prefix = / usr --bindir = / usr / bin
--datadir = / usr / share / ffmpeg --incdir = / usr / include / ffmpeg --libdir = / usr / lib64 --mandir = / usr / share / man --arch = x86_64 --optflags = '- O2 -g -pipe -Wall -Wp, -D_FORTIFY_SOURCE = 2 -fexceptions -fstack-protector-strong --param = ssp-buffer-size = 4 -grecord-gcc-Switches -m64 -mtune = универсальный '--extra-ldflags = '- Wl, -z, relro' --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-version3 --enable-bzlib --disable-crystalhd --enable- gnutls --enable-ladspa --enable-libass --enable-libcdio --enable-libdc1394 --enable-libfdk-aac --enable-nonfree --disable-indev = jack --enable-libfreetype --enable-libgsm --enable-libmp3lame --enable-openal --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libv4l2 --enable-libx264 --enable-libx265 --enable-libxvid --enable-x11grab --enable-avfilter --enable-avresample --enable-postproc --enable-pthreads --disable-static--enable-shared --enable-gpl --disable-debug --disable-stripping --shlibdir = / usr / lib64 --enable-runtime-cpudetect libavutil 54. 31.100 / 54. 31.100 libavcodec 56. 60.100 / 56. 60.100 libavformat 56. 40.101 / 56. 40.101 libavdevice 56. 4.100 / 56. 4.100 libavfilter 5. 40.101 / 5. 40.101 libavresample 2. 1. 0 / 2. 1. 0 libswscale 3. 1.101 / 3. 1.101 libswresample 1. 2.101 / 1. 2.101 libpostproc 53. 3.100 / 53. 3.100 Вход № 0, mov, mp4, m4a, 3gp, 3g2, mj2, из 'https://website.com/uploads/video/e0J6HwtK_video.mp4': Метаданные: major_brand: mp42 minor_version: 0 совместимые_бренды: isommp42 creation_time: 2018-01-01 12:09:49 Продолжительность: 00: 00: 41.49, начало: 0,000000, битрейт: 230 кбит / с Поток № 0: 0 (отмена): видео: h264 (ограниченная базовая линия) (avc1 / 0x31637661), yuv420p, 240x360 [SAR 1: 1 DAR 2: 3], 158 кбит / с, 9,73 к / с, 9,73 т / с, 19462 тбн, 19,46 тбк (по умолчанию) Метаданные: имя обработчика: VideoHandler Stream # 0: 1 (und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Гц, моно, fltp, 71 кбит / с (по умолчанию) Метаданные: creation_time: 2018-01-01 12:09:49 имя обработчика: файл IsoMedia Произведено Google, 5-11-2011 [swscaler @ 0xc8c580] устаревший пиксель используемый формат, убедитесь, что вы правильно установили диапазон. Output # 0, mjpeg, до 'https://website.com/uploads/video/e0J6HwtK_video.png': Метаданные: major_brand: mp42 minor_version: 0 совместимые_бренды: isommp42 кодировщик: Lavf56.40.101 Stream # 0: 0 (und): видео: mjpeg, yuvj420p (pc), 240x360 [SAR 1: 1 DAR 2: 3], q = 2-31, 200 кбит / с, 1 кадр / с, 1 тбн, 1 тбк (по умолчанию) Метаданные: имя-обработчика: кодировщик VideoHandler: Lavc56.60.100 mjpeg Отображение потока: Поток # 0: 0 -> # 0: 0 (h264 (собственный) -> mjpeg (native)) Нажмите [q], чтобы остановить, [?] для справочного кадра = 5 кадров в секунду = 0,0 q = 1,6 Lsize = время 100 кБ = 00: 00: 05,00 битрейт = 163,9 кбит / с dup = 0 drop = 32 видео: 100 КБ аудио: 0 КБ субтитры: 0 КБ Другие потоки: 0 КБ Заголовки: 0 КБ, мультиплексирование: 0,000000%

Ответы [ 3 ]

0 голосов
/ 22 января 2019

используйте этот код: ` // путь большого пальца должен быть добавлен в коде ниже // тест для большого пальца

      $dir_img='uploads/';
      $mediapath='123.jpg';

      $file_thumb=create_movie_thumb($dir_img.$mediapath,$mediapath,$mediaid);

        $name_file=explode(".",$mediapath);
        $imgname="thumb_".$name_file[0].".jpg";     



        /*
          Function to create video thumbnail using ffmpeg
        */
        function create_movie_thumb($src_file,$mediapath,$mediaid)
        {
            global $CONFIG, $ERROR;

            $CONFIG['ffmpeg_path'] = '/usr/local/bin/'; // Change the path according to your server.
            $dir_img='uploads/';
            $CONFIG['fullpath'] = $dir_img."thumbs/";

            $src_file = $src_file;
            $name_file=explode(".",$mediapath);
            $imgname="thumb_".$name_file[0].".jpg";
            $dest_file = $CONFIG['fullpath'].$imgname;

            if (preg_match("#[A-Z]:|\\\\#Ai", __FILE__)) {
                // get the basedir, remove '/include'
                $cur_dir = substr(dirname(__FILE__), 0, -8);
                $src_file = '"' . $cur_dir . '\\' . strtr($src_file, '/', '\\') . '"';
                $ff_dest_file = '"' . $cur_dir . '\\' . strtr($dest_file, '/', '\\') . '"';
            } else {
                $src_file = escapeshellarg($src_file);
                $ff_dest_file = escapeshellarg($dest_file);
            }

            $output = array();

            if (eregi("win",$_ENV['OS'])) {
                // Command to create video thumb
                $cmd = "\"".str_replace("\\","/", $CONFIG['ffmpeg_path'])."ffmpeg\" -i ".str_replace("\\","/" ,$src_file )." -an -ss 00:00:05 -r 1 -vframes 1 -y ".str_replace("\\","/" ,$ff_dest_file);
                exec ("\"$cmd\"", $output, $retval);

            } else {
                // Command to create video thumb
                $cmd = "{$CONFIG['ffmpeg_path']}ffmpeg -i $src_file -an -ss 00:00:05 -r 1 -vframes 1 -y $ff_dest_file";
                exec ($cmd, $output, $retval);

            }


            if ($retval) {
                $ERROR = "Error executing FFmpeg - Return value: $retval";
                if ($CONFIG['debug_mode']) {
                    // Re-execute the command with the backtick operator in order to get all outputs
                    // will not work if safe mode is enabled
                    $output = `$cmd 2>&1`;
                    $ERROR .= "<br /><br /><div align=\"left\">Cmd line : <br /><span style=\"font-size:120%\">" . nl2br(htmlspecialchars($cmd)) . "</span></div>";
                    $ERROR .= "<br /><br /><div align=\"left\">The ffmpeg program said:<br /><span style=\"font-size:120%\">";
                    $ERROR .= nl2br(htmlspecialchars($output));
                    $ERROR .= "</span></div>";
                }
                @unlink($dest_file);
                return false;
            }

            $return = $dest_file;
            //@chmod($return, octdec($CONFIG['default_file_mode'])); //silence the output in case chmod is disabled
            return $return;
        }`
0 голосов
/ 23 января 2019

аргументы должны быть экранированы, вы не можете просто помещать туда переменные в качестве аргументов, URL содержат такие вещи, как &, которые имеют особое значение в оболочках .. например, это

exec ("/ usr / bin / ffmpeg -i $ videoUrlp.flv -f flv -s 650x390 $ videoUrlp.mp4 2> & 1");

должно было быть так:

exec ("/ usr / bin / ffmpeg -i" .escapeshellarg ($ videoUrlp.flv). "-F flv -s 650x390" .escapeshellarg ($ videoUrlp.mp4). "2> & 1");

но ..

пожалуйста, кто-нибудь может мне помочь?

вот две функции для получения эскиза: getThumbPng2 () сначала загрузит все видео с помощью curl, сохранит его во временный файл, а затем извлечет URL с помощью ffmpeg (это безопаснее, если ffmpeg не создан с http / https / любая поддержка, или если ffmpeg заблокирован брандмауэром или чем-то еще, но недостатком является то, что он потенциально намного медленнее)

и первая функция извлекает миниатюру из ffmpeg без предварительной загрузки видео (что потенциально намного быстрее, поскольку ffmpeg будет просто читать необходимые части вместо загрузки всего видео, но может не работать по причинам, объясненным выше)

function getThumbPng2(string $uri, string &$imageBinary=NULL, string &$stderr=NULL):bool{
    $ch=curl_init($uri);
    if(!$ch){
        $imageBinary=$stderr="curl_init() failed";
        return false;
    }
    $tmph=tmpfile();
    curl_setopt_array($ch,array(
        CURLOPT_SSL_VERIFYPEER=>false,
        CURLOPT_SSL_VERIFYHOST=>false,
        CURLOPT_FILE=>$tmph
    ));
    if(!curl_exec($ch)){
        $imageBinary=$stderr="curl error: ".curl_errno($ch).": ".curl_error($ch);
        curl_close($ch);
        fclose($tmph);
        return false;
    }
    curl_close($ch);
    $ret=getThumbPng(stream_get_meta_data($tmph)['uri'],$imageBinary,$stderr);
    fclose($tmph);
    return $ret;
}
function getThumbPng(string $uri,string &$imageBinary=NULL, string &$stderr=NULL):bool{
    $imageBinary="";
    $stderr="";
    $descriptorspec = array(
        0 => array("pipe", "rb"),  // stdin
        1 => array("pipe", "wb"),  // stdout
        2 => array("pipe","wb") // stderr 
    );
    $cmd="ffmpeg -i ".escapeshellarg($uri)." -ss 00:00:3 -s 650x390 -vframes 1 -c:v png -f image2pipe -";
    // var_dump($cmd);
    $proc = proc_open($cmd, $descriptorspec, $pipes);
    if(!$proc){
        $stderr="failed to start ffmpeg, proc_open(\"ffmpeg\",...) failed. (why? don't know, and PHP has no way of telling us either, afaik.)";
        return false;
    }
    fclose($pipes[0]);// by default stdin is *inherited*, which is not what we want,
    // so to avoid the default behaviour, we explicitly create a stdin pipe and close it.
    $fetch=function()use(&$pipes,&$imageBinary,&$stderr){
        $tmp=stream_get_contents($pipes[1]);
        if(is_string($tmp)){
            $imageBinary.=$tmp;
        }
        $tmp=stream_get_contents($pipes[2]);
        if(is_string($tmp)){
            $stderr.=$tmp;
        }   
    };
    while(($status=proc_get_status($proc))['running']){
        usleep(10*1000);
        $fetch();
    }
    $fetch();
    fclose($pipes[1]);
    fclose($pipes[2]);
    $ret=$status['exitcode'];
    proc_close($proc);
    //var_dump($ret);
    return ($ret===0);
}

пример использования:

<?php
if(getThumbPng("http://files.4x4norway.no/2018/vik2.webm",$imageBinary,$stderr)){
    echo "got a thumbnail! (the png binary data is in the \$imageBinary variable.)";
}else{
    var_dump($imageBinary);
    echo "failed to create thumbnail! error: {$stderr}";
}
0 голосов
/ 20 января 2019

Если вы используете https, ваш ffmpeg должен быть настроен с поддержкой ssl ( ffmpeg over https завершается ошибкой ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...