Use FFMPEG to get frame from a video on specific time (PHP) - php

Using FFMPEG, I want to get the frame from the video on a specific time (provided by the user) in PHP.
Can anybody help me with this? I've never used FFMPEG.
Thanks in advance.

I found the solution
//video dir
$video = 'Salient.avi';
//where to save the image
$image = 'testimage%d.jpg';
//time to take screenshot at
$interval = '00:00:12';
//screenshot size
$size = '535x346';
echo "Starting ffmpeg...\n\n<br>";
$cmd = "ffmpeg -i $video -ss $interval -f image2 -s $size -vframes 1 $image";
echo shell_exec($cmd);
echo "Done.\n";

Related

How to trim a video by 4 fragments to 4 seconds using the PHP-FFMpeg?

How to trim a video using the PHP-FFMpeg?
I need to implement the following FFMpeg command:
ffmpeg -i 7207783801bb.mp4 -filter_complex \
"[0:v]trim=start=10:end=11,setpts=PTS-STARTPTS[a]; \
[0:v]trim=start=20:end=21,setpts=PTS-STARTPTS[b]; \
[a][b]concat[c]; \
[0:v]trim=start=30:end=31,setpts=PTS-STARTPTS[d]; \
[0:v]trim=start=40:end=41,setpts=PTS-STARTPTS[f]; \
[d][f]concat[g]; \
[c][g]concat[out1]" -map [out1] 7207783801bbout.mp4
When I use the following code:
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open('7207783801bb.mpg');
$video->filters()->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(10), FFMpeg\Coordinate\TimeCode::fromSeconds(11));
$video->filters()->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(20), FFMpeg\Coordinate\TimeCode::fromSeconds(21));
$video->filters()->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(30), FFMpeg\Coordinate\TimeCode::fromSeconds(31));
$video->filters()->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(40), FFMpeg\Coordinate\TimeCode::fromSeconds(41));
$video->save(new FFMpeg\Format\Video\X264(), '7207783801bbout.mp4');
then I get only 40 seconds of video.
And I need to get 10-11, 20-21, 30-31, 40-41 seconds using the PHP-FFMpeg. Only 4 seconds.
From the manual pages
Clip
The clip filter takes two
parameters:
$start, an instance of FFMpeg\Coordinate\TimeCode, specifies the start
point of the clip
$duration, optional, an instance of FFMpeg\Coordinate\TimeCode, specifies the duration of the clip
(Emphasis mine)
So your second parameter needs to be 1 instead of (for example) 11 as it is the clip duration...
$video->filters()->clip(FFMpeg\Coordinate\TimeCode::fromSeconds(10),
FFMpeg\Coordinate\TimeCode::fromSeconds(1));
I this case FFMpeg\Media\AdvancedMedia can be used
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->openAdvanced(['7207783801bb.mp4']);
$video->filters()
->custom('[0:v]', 'trim=start=10:end=11,setpts=PTS-STARTPTS', '[a]')
->custom('[0:v]', 'trim=start=20:end=21,setpts=PTS-STARTPTS', '[b]')
->custom('[a][b]', 'concat', '[c]')
->custom('[0:v]', 'trim=start=30:end=31,setpts=PTS-STARTPTS', '[d]')
->custom('[0:v]', 'trim=start=40:end=41,setpts=PTS-STARTPTS', '[f]')
->custom('[d][f]', 'concat', '[g]')
->custom('[c][g]', 'concat', '[out1]')
;
$video
->map(['[out1]'], new \FFMpeg\Format\Video\X264(), '7207783801bbout.mp4')
->save();

FTP Video Upload and Thumbnail Rotation Issue

I am uploading video using ffmpeg command. I am then creating then thumbnail. I want to rotate video, how can I achieve this?
Here is my Code:
$thumbnail_name = preg_replace('"\.(mp4|avi|flv|vob|oggg)$"', '.jpg', $newfilename);
$movie = "/home/foldername/public_html/master/assets/user_videos/".$newfilename;
$thumbnail = "/home/foldername/public_html/master/assets/user_videos/".$thumbnail_name;
$command = '/usr/bin/ffmpeg -y -ss 00:00:01 -i '.$movie.' -f image2 -vframes 1 '.$thumbnail.' 2>&1';
Add your command -vf transpose=1
Full code: ffmpeg -i input.mp4 -ss 0 -vframes 1 -vf transpose=1 out.jpg
For the transpose parameter you can pass:
0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip
Use -vf "transpose=2,transpose=2" for 180 degrees.

How to display a screenshot of a stream using avconv and php with exec?

When this script is run, the image is saved to a file:
<?php
$url = "rtmp://109.71.162.112:1935/live/sd.jasminchannel.stream";
exec('avconv -i "'.$url.'" -ss 00:00:01 -t 1 -r 1 -f image2 "screenshot.jpg" 2>&1', $output, $status);
header("Content-type: image/png");
readfile("screenshot.jpg");
I wish it was returned on the screen (on the fly means it, write to variable, instead without saving to file and afterwards reading, display, deleting this file):
<?php
$url = "rtmp://109.71.162.112:1935/live/sd.jasminchannel.stream";
exec('avconv -i "'.$url.'" -ss 00:00:01 -t 1 -r 1 -f image2 $variable 2>&1', $output, $status);
header("Content-type: image/png");
echo $variable;
How can I do this?
I think this will solve your problem:
<?php
$url = "rtmp://109.71.162.112:1935/live/sd.jasminchannel.stream";
header("content-type: image/jpeg");
echo passthru('avconv -i "'.$url.'" -ss 00:00:01 -t 1 -r 1 -f image2 pipe:.jpg 2>/dev/null');
This is untested, but it should work. I've been working on a similar problem at:
https://gist.github.com/megasaturnv/a42ed77d3d08d0d3d91725dbe06a0efe
and with the image in an tag:
https://gist.github.com/megasaturnv/6e5965732d4cff91f2e976e7a39efbaa

ffmpeg not detecting video file duration

Am using the following code to detect video duration before uploading using ffmpeg, but it doesn't seem to work:
<?php
$file=sample.avi;
$time = exec("$ffmpeg -i /path/".$file." 2>&1 |
grep Duration | cut -d ' ' -f 4 | sed s/,//");
echo $time;
?>
I need to echo video duration as text input to sql before uploading file to server.
i used https://github.com/wseemann/FFmpegMediaMetadataRetriever
with following code to retrive video duration
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource(mUri);
String time = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION);
int VideoDuration = Integer.parseInt(time);
mmr.release();

parse output 2>&1 with php script

I have an exec command I am using to make ffmpeg work.
$process = exec("/usr/local/bin/ffmpeg -i /home/g/Desktop/cave.wmv -deinterlace
-acodec libfaac -ab 96k -ar 44100 -vcodec libx264 -s 480x320 -f flv /home/g/Desktop
/file.flv 2>&1 | php testing123.php") ;
In testing123.php I use
$h = fopen('php://stdin', 'r'); $str = fgets($h); fclose($h);
//topic removed
$sql = 'INSERT INTO table
(id,status) VALUES(?,?)';
$stmt3 = $conn->prepare($sql);
$result=$stmt3->execute(array(rand(),$str));
However, as you may have guessed I get one database entry, only when the file initially executes from the exec command in the other file. Is there a way to keep executing the file or something else so that the output fed to the file can be inserted into my database every couple seconds?
You need to use a while loop. There are some examples in the fgets documentation.
$h = fopen('php://stdin', 'r');
while ( ($str = fgets($h)) !== false )
{
$sql = 'INSERT INTO ...';
mysql_query($sql);
}
fclose($h);
One of the comments in the documentation suggests using stream_get_line instead of fgets. In case you're interested, here's the direct link: http://www.php.net/manual/en/function.fgets.php#86319.

Categories