PHP calls ffmpeg to take a screenshot of the video and splice the script.

Source: Internet
Author: User
Tags imagejpeg php define

PHP calls ffmpeg to splice the video and scripts, and ffmpeg concatenates

The PHP script calls ffmpeg to splice the video for your reference. The specific content is as follows:

Currently, videos in common formats such as MKV, MPG, and MP4 are supported. Other formats need to be tested.

12 P an average generation time of 1.64 videos in 100 s, about 2 minutes and a half

9 P an average generation time of 1.13 videos in 100 s, which takes about 2 minutes

6 P an average generation time of 0.86 videos in 100 s, about 1 minute and a half

3 P an average generation time of 0.54 videos in 100 s, about 1 minute

<? Php define ('ds', DIRECTORY_SEPARATOR); date_default_timezone_set ("Asia/Shanghai"); class FileLoader {// PATH variable private $ rootdir = ''; private $ tmp = "tmp"; // tmp directory private $ source = "mpg"; // source directory private $ destination = "screenshoot "; // target path private $ emptyImageName = "empty.jpg"; // merged background image // file array private $ maxShoots = 12; // The maximum number of private $ videoInfo = NULL; private $ files = array (); // number of files private $ f IleArray = array (); private $ extensionArray = array ("mpg", "mkv", "mp4", "avi", "3gp", "mov "); // supported format: private $ timeArray = array ("00:00:10", "00:00:20", "00:00:30", "00:01:00", "00:01:30", "00:02:00", "00:02:30 ", "00:03:00", "00:03:30", "00:03:40", "00:03:50", "00:04:00"); // statistical variable private $ timeStart = 0; private $ timeEnd = 0; private $ fileCount = 0; private $ successCount = 0; private $ failedCount = 0;/*** initialization information */Function _ construct () {file_put_contents ("log.txt", ""); $ this-> rootdir = dirname (_ FILE __); $ count = count ($ this-> timeArray); for ($ I = 1; $ I <= $ count; $ I ++) {$ ii = $ I-1; $ this-> fileArray [$ ii] = $ this-> tmp. DS. $ I. ". jpg ";}}/*** current time, accurate to the decimal point */private static function microtime_float () {list ($ usec, $ sec) = explode ("", microtime (); return (float) $ usec + (float) $ sec);}/*** 00:00:00 time to second */pr Ivate static function timeToSec ($ time) {$ p = explode (':', $ time); $ c = count ($ p); if ($ c> 1) {$ hour = intval ($ p [0]); $ minute = intval ($ p [1]); $ sec = intval ($ p [2]);} else {throw new Exception ('error time format') ;}$ secs = $ hour * 3600 + $ minute * 60 + $ sec; return $ secs ;} /*** 00:00:00 time to second */private static function secToTime ($ time) {$ hour = floor ($ time/3600 ); $ min = floor ($ time-$ hour * 3600)/60); $ sec = $ time % 60; $ timeStr = sprintf ("% 02d: % 02d: % 02d", $ hour, $ min, $ sec ); return $ timeStr;}/*** get all files */private function getFiles ($ dir) {$ files = array (); $ dir = rtrim ($ dir, "/\\"). DS; $ dh = opendir ($ dir); if ($ dh = false) {return $ files;} while ($ file = readdir ($ dh ))! = False) {if ($ file {0} = '. ') {continue;} $ path = $ dir. $ file; if (is_dir ($ path) {$ files = array_merge ($ files, $ this-> getFiles ($ path);} elseif (is_file ($ path )) {$ files [] = $ path ;}} closedir ($ dh); return $ files;}/*** search path */public function searchDir ($ sourcePath = NULL) {$ this-> timeStart = $ this-> microtime_float (); if ($ sourcePath) {$ this-> rootdir = $ sourcePath;} if (file_exists ($ t His-> rootdir) & is_dir ($ this-> rootdir) {$ this-> files = $ this-> getFiles ($ this-> rootdir. DS. $ this-> source) ;}$ this-> fileCount = count ($ this-> files); foreach ($ this-> files as $ path) {$ fi = pathinfo ($ path); $ flag = array_search (strtolower ($ fi ['extension']), $ this-> extensionArray); if (! $ Flag) continue; $ this-> getScreenShoot (basename ($ path);} $ this-> timeEnd = $ this-> microtime_float (); $ time = $ this-> timeEnd-$ this-> timeStart; if ($ this-> fileCount> 0) {$ str = sprintf ("[TOTAL]: Cost Time: % 8 s | Total File: [% d] | Successed: [% d] | Failed: [% d] | Speed: %. 2fs per file \ n ", $ this-> secToTime ($ time), $ this-> fileCount, $ this-> successCount, $ this-> failedCount, $ time/$ this-> fileCount); file_put_c Ontents ("log.txt", $ str, FILE_APPEND);} else {$ str = sprintf ("[TOTAL]: Cost Time: % 8 s | Total File: [% d] | Successed: [% d] | Failed: [% d] | Speed: %. 2fs per file \ n ", $ this-> secToTime ($ time), $ this-> fileCount, $ this-> successCount, $ this-> failedCount, 0 ); file_put_contents ("log.txt", $ str, FILE_APPEND) ;}}/*** get video information */private function getVideoInfo ($ file) {$ re = array (); exec (". ". DS. "ffmpeg-I {$ file} 2> & 1", $ Re); $ info = implode ("\ n", $ re); if (preg_match ("/No such file or directory/I", $ info )) {return false;} if (preg_match ("/Invalid data/I", $ info) {return false;} $ match = array (); preg_match ("/\ d {2,} x \ d +/", $ info, $ match); list ($ width, $ height) = explode ("x ", $ match [0]); $ match = array (); preg_match ("/Duration :(. *?), /", $ Info, $ match); if ($ match) {$ duration = date (" H: I: s ", strtotime ($ match [1]);} else {$ duration = NULL;} $ match = array (); preg_match ("/bitrate :(. * kb \/s)/", $ info, $ match); $ bitrate = $ match [1]; if (! $ Width &&! $ Height &&! $ Duration &&! $ Bitrate) {return false;} else {return array ("file" => $ file, "width" => $ width, "height" => $ height, "duration" => $ duration, "bitrate" => $ bitrate, "secends" => $ this-> timeToSec ($ duration ));}} /*** set time */private function setShootSecends ($ secends, $ useDefault = NO) {if ($ useDefault) {if ($ secends <18) {$ time = 1 ;}else {$ time = 5 ;}$ range = floor ($ secends-$ time)/($ this-> maxShoots); if ($ Range <1) {$ range = 1 ;}$ this-> timeArray = array (); for ($ I = 0; $ I <$ this-> maxShoots; $ I ++) {$ this-> timeArray [$ I] = $ this-> secToTime ($ time); $ time = $ time + $ range; if ($ time> $ secends) break ;}}/ *** splice image */private function getFixedPhoto ($ fileName) {$ target = $ this-> rootdir. DS. $ this-> emptyImageName; // background image $ target_img = Imagecreatefromjpeg ($ target); $ source = array (); foreach ($ this-> fileA Rray as $ k => $ v) {$ source [$ k] ['source'] = Imagecreatefromjpeg ($ v ); $ source [$ k] ['SIZE'] = getimagesize ($ v);} $ tmpx = 5; $ tmpy = 5; // spacing between images for ($ I = 0; $ I <count ($ this-> timeArray); $ I ++) {imagecopy ($ target_img, $ source [$ I] ['source'], $ tmpx, $ tmpy, 0, 0, $ source [$ I] ['SIZE'] [0], $ source [$ I] ['SIZE'] [1]); $ target_img = $ this-> setTimeLabel ($ target_img, $ tmpx, $ tmpy, $ source [$ I] ['SIZE'] [0], $ source [$ I] ['SIZE'] [1], $ thi S-> timeArray [$ I]); $ tmpx = $ tmpx + $ source [$ I] ['SIZE'] [0]; $ tmpx = $ tmpx + 5; if ($ I + 1) % 3 = 0) {$ tmpy = $ tmpy + $ source [$ I] ['SIZE'] [1]; $ tmpy = $ tmpy + 5; $ tmpx = 5 ;}}$ target_img = $ this-> setVideoInfoLabel ($ target_img, $ tmpx, $ tmpy, $ this-> videoInfo ); imagejpeg ($ target_img, $ this-> rootdir. DS. $ this-> destination.ds.w.filename.'.jpg ');}/*** set the time scale label */private function setTimeLabel ($ image, $ image_x, $ image_y, $ Image_w, $ image_h, $ img_text) {imagealphablending ($ image, true); // set the color $ color = imagecolorallocate ($ image, 255,255,255 ); $ ttf_im = imagettfbbox (30, 0, "Arial. ttf ", $ this-> img_text); $ w = $ ttf_im [2]-$ ttf_im [6]; $ h = $ ttf_im [3]-$ ttf_im [7]; unset ($ ttf_im); $ txt_y = $ image_y + $ image_h + $ h-5; $ txt_x = $ image_x + $ w + 5; imagettftext ($ image, $ txt_x, $ txt_y, $ color, "Arial. ttf ", $ img_text); return $ image ;}/*** Set the video information tag */private function setVideoInfoLabel ($ image, $ txt_x, $ txt_y, $ videoInfo) {imagealphablending ($ image, true); $ color = imagecolorallocate ($ image,, 0); imagettftext ($ image, + 30, $ color, "FZLTHJW. ttf "," FileName :". basename ($ videoInfo ["file"]); imagettftext ($ image, + 30, $ color, "Arial. ttf "," Size :". $ videoInfo ["width"]. "x ". $ videoInfo ["height"]); imagettftext ($ image, 20 00 + 120, $ color, "Arial. ttf "," Duration :". $ videoInfo ["duration"]); imagettftext ($ image, 120, +, $ color, "Arial. ttf "," Bitrate :". $ videoInfo ["bitrate"]); return $ image;}/*** screen */public function getScreenShoot ($ fileName) {$ fi = pathinfo ($ fileName ); $ this-> videoInfo = $ this-> getVideoInfo ($ this-> rootdir. DS. $ this-> source. DS. $ fileName); if ($ this-> videoInfo) {$ this-> setShootSecends ($ this-> video Info ["secends"]); for ($ I = 0; $ I <count ($ this-> timeArray); $ I ++) {$ cmd = ". ". DS. "ffmpeg-ss ". $ this-> timeArray [$ I]. "-I ". $ this-> rootdir. DS. $ this-> source. DS. $ fileName. "-y-f image2-s 720*480-vframes 1 ". $ this-> rootdir. DS. $ this-> fileArray [$ I]; exec ($ cmd, $ out, $ status);} $ this-> getFixedPhoto ($ fileName ); $ str = sprintf ("[% s]: OK ........... [% s] [% 2dP] %-30s \ n ", date (" y-m-d h: I: s ", time (), $ this-> vide OInfo ["duration"], count ($ this-> timeArray), $ fileName); file_put_contents ("log.txt", $ str, FILE_APPEND ); $ this-> successCount + = 1;} else {$ str = sprintf ("[% s]: FAILED ................................. [% s] [% 2dP] %-30s \ n ", date (" y-m-d h: I: s ", time ()), $ this-> videoInfo ["duration"], count ($ this-> timeArray), $ fileName); file_put_contents ("log.txt", $ str, FILE_APPEND ); $ this-> failedCount + = 1;}/*** TODO: * capture an image, * It is troublesome to configure ffmpeg-php, * but this class is quite useful. */Public function getScreenShoot2 ($ fileName) {if (extension_loaded ('ffmpeg ') {// judge whether ffmpeg is loaded $ mov = new ffmpeg_movie ($ this-> rootdir. DS. $ this-> source. DS. $ fileName); // video path $ count = $ mov-> getFrameCount (); $ ff_frame = $ mov-> getFrame (floor ($ count/2 )); if ($ ff_frame) {$ gd_image = $ ff_frame-> toGDImage (); $ img = $ this-> rootdir. DS. "test.jpg"; // the absolute path of the image to be generated: imagejpeg ($ gd_image, $ img); // create a jpg image imagedestroy ($ g D_image); // destroy an image} else {echo "ffmpeg not loaded" ;}}$ fileLoader = new FileLoader (); $ fileLoader-> searchDir ();?>

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.