2014-11-07 4 views
4

FFMpeg를 사용하여 비디오를 변환 중이며 명령 줄에서 올바르게 작동합니다. 다음 명령을 사용하고 있습니다 :FFMpeg는 명령 줄에서 작동하지만 PHP 스크립트에서는 작동하지 않습니다.

ffmpeg -i input.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv output.flv 

그러나 PHP 스크립트를 사용하여 명령을 실행하면 출력 비디오가 인코딩되지 않습니다.

exec("ffmpeg -i input.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv output.flv",$output, $returnvalue); 

$returnvalue = 127; 

FFMPEG 설치 경로 :

[[email protected] ~]# which ffmpeg 

/root/bin/ffmpeg 

내 스크립트 경로 :

www.domainname.com/core/foldername/ffmpeg.php

저를주세요 같은 ASAP를위한 솔루션.

감사합니다.

답변

4

PHP 스크립트에서 ffmpeg을 실행하는 자연적인 방법은 같은 것입니다 :

여기서 지적해야 할 몇 가지 문제가 있습니다
<?php 
    echo "Starting ffmpeg...\n\n"; 
    echo shell_exec("ffmpeg -i input.avi output.avi &"); 
    echo "Done.\n"; 
?> 

. 첫 번째 것은 우리가 ffmpeg을 앰퍼샌드 연산자 "&"을 사용하여 백그라운드에서 실행되도록 지정했지만 PHP 스크립트는 이 계속 실행되지 않으며 ffmpeg이 실행을 마칠 때까지 실행됩니다. 이것은 말한다 PHP의 exec() 기능에 대한 사항 중 하나에 언급, 사실에 기인한다 : 에 대한 위해

을 프로그램이이 기능으로 시작되는 경우는,는 백그라운드에서 계속 실행 프로그램의 출력은 이어야하며 파일이나 다른 출력 스트림으로 리디렉션되어야합니다. 그렇게하지 않으면 은 프로그램 실행이 끝날 때까지 PHP가 멈추도록합니다.

​exec() 대신에 shell_exec()을 나타내는 예제를 혼동하지 마십시오. PHP의 모든 프로그램 실행 함수 은 유사한 코드베이스과 제한 사항을 공유합니다.

그래서,이 문제를 해결하기 위해, 우리는 같은 것을 할 필요가 :

<?php 
    echo "Starting ffmpeg...\n\n"; 
    echo shell_exec("ffmpeg -i input.avi output.avi >/dev/null 2>/dev/null &"); 
    echo "Done.\n"; 
?> 

을 말한다 부분 ">을/dev/null"는 표준 출력 (stdout)를 리디렉션합니다 (실제 오류 출력을 무시하고) "2>/dev/null"은 으로 인스턴스를 /dev/null (오류 로그 메시지를 무시하고) /dev/null으로 리디렉션합니다. 이 두 가지를 더 짧은 표현으로 결합 할 수 있습니다 : ">/dev/null 2> & 1". 원하는 경우 I/O 리디렉션에 대해 자세히 읽을 수 있습니다.

여기에 중요한 참고 사항을 언급해야합니다.ffmpeg 명령 줄 도구는 오류 로그 메시지 출력에 stderr을 사용하고 ffmpeg에서 생성 된 출력 미디어 스트림을 다른 명령 줄 도구로 리디렉션하기 위해 stdout은 파이프 사용을 위해 예약되어 있습니다. 즉, ffmpeg을 백그라운드에서 실행하면 stderr을 나중에 로그 파일로 리디렉션하여 나중에 확인할 수 있습니다.

한 가지 더 알아 두어야 할 것은 표준 INPUT (표준 입력)입니다. 명령 줄 ffmpeg 도구는 사용자 입력 (일반적으로 키보드에서)을 받아들이고 사용자의 현재 화면/터미널에 오류 로그를보고하는 대화 형 유틸리티로 설계되었습니다. 백그라운드에서 ffmpeg을 실행할 때 ffmpegstdin에서 입력을 받아 들여서는 안되며 기다려야한다고 말하고 싶습니다. 우리는 "이와 유사한 것 백그라운드에서는 FFmpeg 명령 줄 도구 :

<?php 
    echo "Starting ffmpeg...\n\n"; 
    echo shell_exec("ffmpeg -y -i input.avi output.avi </dev/null >/dev/null 2>/var/log/ffmpeg.log &"); 
    echo "Done.\n"; 
?> 

"다시 **를 I/O 리디렉션을 사용하여, ffmpeg이 말할 수 -y " 옵션이 자동으로 사용됩니다 -yes/no 확인을 요구하지 않고 출력 파일 (output.avi)을 덮어 씁니다. 반대의 시나리오가 필요한 경우, 출력 파일이 이미있는 경우 전체 프로세스를 자동 취소하려면 "-n" 옵션을 대신 사용하십시오

옵션

래퍼 라이브러리

일부 PHP 라이브러리에서는 ffmpeg을 PHP 객체로 래핑 할 수 있으며 명령 줄을 사용하지 않으려는 경우 사용할 수있는 멋진 구문을 제공합니다. 이 중 하나는 적극적으로 유지 관리되는 PHP-FFMpeg입니다. PHP 구성 요소 설치와 별도로 최근 ffmpegffprobe 빌드 만 다운로드하면됩니다. 그런 다음 PHP 코드를 다음과 같이 실행할 수 있습니다.

$ffmpeg = FFMpeg\FFMpeg::create(); 
$video = $ffmpeg->open('video.mpg'); 
$video 
    ->filters() 
    ->resize(new FFMpeg\Coordinate\Dimension(320, 240)) 
    ->synchronize(); 
$video 
    ->save(new FFMpeg\Format\Video\X264(), 'export-x264.mp4') 

당연히 백그라운드에서 이러한 작업을 수행해야합니다. GearmanClient과 같은 라이브러리는이를 용이하게합니다.

참고 :ffmpeg-php는 2007 년부터 개발 (및 "는 FFmpeg-0.4.9_pre1 이상" 필요) 당신는 FFmpeg의 아주 오래된 버전을 사용하도록 제한하는 것을 의미하지 않는 확장, 최신 버전으로 업데이트 할 필요가 없습니다. 많은 변경/개선이 이루어지기 때문에 ffmpeg's 코드 안에 매일 ffmpeg-php은 최신 ffmpeg과 호환되지 않습니다.

자세한 내용은 official documentation을 읽으십시오.

+0

Excelent answer! –

1

이것은 나에게 일어났습니다. 다른 포럼에서이 사실을 발견했습니다. PHP의 속임수는 FFMPEG의 절대 경로를 제공하는 것입니다. 이런 식으로 실행 해보십시오.

exec("/root/bin/ffmpeg -i input.avi -ab 56 -ar 44100 -b 200 -r 15 -s 320x240 -f flv output.flv",$output, $returnvalue); 

PHP가 명령 줄에 직접 입력 할 때와 다른 사용자라는 사실에 대해. 나는 그것이 같은 바로 가기 목록 또는 그것이 무엇이든간에 있지 않다고 생각한다.

정확하게 이유는 확실하지 않지만 저에게는 효과적입니다.

행운을 비네.

+1

감사합니다. 그것은 나를 위해 일했습니다. –

0

다른 스레드에서 내가 말했던 대부분의 사람들에게 도움이되는 솔루션을 다루었습니다.

https://stackoverflow.com/a/38626752/2074077

기본적으로 사용자는 공개 디렉토리에 액세스해야합니다.

<?php 
    exec('whoami'); // Gives you the running user; often it's www-data 
?> 

그런 다음 공개 소유권을 whoami 사용자로 변경하십시오.

sudo chown -R www-data:root /var/www 
관련 문제