An FFMPEG Question – Why PHP’s exec() Doesn’t Return the Command Output

string exec (…)

Here’s the tricky part. As we know from the exec() man page this function executes the given command. As described there, the exact declaration of this method is:

string exec  ( string $command  [, array &$output  [, int &$return_var  ]] )

So far so good. Normally exec() will return the output of the command.

FFmpeg version SVN-r21880, Copyright (c) 2000-2010 Fabrice Bellard, et al.
  built on Feb 18 2010 15:53:28 with gcc 4.3.2
  configuration: --enable-gpl --enable-nonfree --enable-shared --enable-postproc --enable-avfilter --enable-avfilter-lavf --enable-pthreads --enable-x11grab --enable-bzlib --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-version3 --enable-libdc1394 --enable-libfaac --enable-libfaad --enable-libfaadbin --enable-libgsm --enable-libmp3lame --enable-libschroedinger --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-zlib --prefix=/usr/local
  libavutil     50. 9. 0 / 50. 9. 0
  libavcodec    52.54. 0 / 52.54. 0
  libavformat   52.52. 0 / 52.52. 0
  libavdevice   52. 2. 0 / 52. 2. 0
  libavfilter    1.17. 0 /  1.17. 0
  libswscale     0.10. 0 /  0.10. 0
  libpostproc   51. 2. 0 / 51. 2. 0
...

However sometimes that is not so true. Let’s see an example with the popular FFMPEG program. In one hand when you try to start a video converting program with PHP you can simply call exec with the FFMPEG command as the first parameter. The output is OK and you can dump it as in the example here.

echo exec('/usr/local/bin/ffmpeg -i input.mp4 -acodec libfaac -ab 128k -ac 2 -vcodec libx264 -vpre normal -threads 0 output.mp4', $output);	
var_dump($output);

In some cases you can call FFMPEG only with the -i option to get some info about the input file. Such info can be the size of the image, the bitrate of the source file or the length of the movie. Executing this command:

echo exec('/usr/local/bin/ffmpeg -i input.mp4', $output);	
var_dump($output);

in the terminal you’ll see the output you wish. However if you trying to execute the command via exec() the output remains empty?

Why the Output Parameter is Empty?

Looking at the terminal screen you can’t see the difference, but actually in the second case, when you execute FFMPEG only with the -i option, the output is redirected to the standard error output. That’s why you can’t see it in the exec() second parameter. However there is a solution.

Sometimes PHP's exec() doesn't return the command output. You've to be sure that the command output is not redirected to the standard error stream.
Sometimes PHP's exec() doesn't return the command output. You've to be sure that the command output is not redirected to the standard error stream.

Solution and Conclusion

The solution is quite simple. You’ve to redirect the output of the FFMPEG command to the standard output.

/usr/local/bin/ffmpeg -i /var/www/android/test.mp4 2>&1

Now you can call this line with exec().

echo exec('/usr/local/bin/ffmpeg -i input.mp4 2>&1', $output);	
var_dump($output);

This showcase with the FFMPEG is important not only because now you can call FFMPEG’s command without problems, but because you now know that exec() can’t read the standard error output. Thus you’ve to be careful and always redirect to the standard output.

Use fopen() to Check File Availability?

Zend Framework and Zend_Http_Client

PHP's fopen() can be used to check remote file existence
PHP's fopen() can be used to check remote file existence

I’ve posted about Zend_Http_Client. Simply there you can ‘make’ your own http client and you can request a remote file. Just to check what’s going on with this file.

// new HTTP request to a file
$httpClient = new Zend_Http_Client('http://www.example.com/myfile.mp4');
 
// get the HEAD of the response and match agains the
// Content-Length. That's because using the Content-Type is slower
$response = $httpClient->request(Zend_Http_Client::HEAD);
 
// if the Content-Length is 0 the file doesn't exists
if (0 === (int)$response->getHeader('Content-Length')) {
	echo 'the file doesn\'t exits';
}

However is there any other way to answer the same question?

fopen()

Yes and no? Perhaps yes, but you should be careful. I’m still not sure it can be used in any case. However here’s the snippet.

if (FALSE === @fopen('http://www.example.com/myfile.mp4', 'r')) {
	echo 'the file doesn\'t exists';
}

fopen() will return FALSE whenever the file doesn’t exists.

In both cases I request a remote file – an MPEG-4 file. Note that fopen()’s first parameter can be a HTTP resource.

An Introduction to the Agile

Today the number of software projects has grown to an incredible extent. Software products are used practically everywhere and as it seems with the Internet in one hand and the mobile apps markets in other this trend is even more consolidated.

 

Agility in Software Development
The agile methods tend to be more responsive to a highly dynamic software projects.

 

Typically the software build processes are followed by the processes of controlling and managing software projects. In the very beginning of the software sciences these were methodologies that relied mainly on a detailed documentation, precise planning and higher degree of control. As it appears in many kind of projects this approach is simply ineffective. Most of those kind of projects are characterized as very dynamic, with many requirement changes that makes them difficult to predict and control with the traditional methods of software development. Continue reading An Introduction to the Agile

jQuery.unbind()

Binding Problems

jQuery JavaScript Library
jQuery JavaScript Library

Typically in jQuery when you bind an HTML element with some event this event is fired every time the user (client) triggers it. Thus when you’ve a click event attached on a button you can click it as many times as you want. In some rare cases this can be tricky. Let’s imagine the following scenario.

  1. The user clicks on a “vote” button.
  2. Some AJAX calls are performed.
  3. After a successful AJAX call you setup a cookie to deny further votes from this machine.

This seems to be pretty well known scenario, but as the click event is attached to the button there is enough time to click several times on the “vote” button and to vote several times. In this case before the cookie is set the user can vote more than once. Continue reading jQuery.unbind()

Scroll an IFRAME Content to a Predefined Position

IFRAME Source

Usually when you use an IFRAME tag to link an external source the page that’s referenced by the SRC attributes is loaded at the top left corner. This is the default behavior, but sometimes you’d like to show to your users not the entire page from the top left corner, but to show only part of the external page instead.

In most of the cases the reference is external and you don’t have control over the external page. Thus you’ve to scroll the IFRAME content to the desired position. This of course is impossible. Yeah, there are some JavaScript hacks, but they’re all a bad solution, because the scrolling occurs only after the page is loaded.

The Solution

You can wrap the IFRAME into a div and scroll the DIV content using absolute TOP and LEFT CSS properties.

Here’s an example:

#my-div
{
    width    : 400px;
    height   : 200px;
    overflow : hidden;
    position : relative;
}
 
#my-iframe
{
    position : absolute;
    top      : -100px;
    left     : -100px;
    width    : 1280px;
    height   : 1200px;
}

Here you have one DIV with dimensions 400x200px. Now by moving the IFRAME within it you can position it on the right place.

<div id="my-div">
<iframe src="http://www.example.com" id="my-iframe" scrolling="no"></iframe>
</div>

Continue reading Scroll an IFRAME Content to a Predefined Position