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.