PageRenderTime 29ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/Vendor/phpvideotoolkit/phpvideotoolkit.php4.php

https://github.com/Wargo/reddevil
PHP | 3295 lines | 1735 code | 168 blank | 1392 comment | 259 complexity | c07fc240df96d0353b02f1aafe1cf221 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.1, GPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * @author Oliver Lillie (aka buggedcom) <publicmail@buggedcom.co.uk>
  5. *
  6. * @license BSD
  7. * @copyright Copyright (c) 2008 Oliver Lillie <http://www.buggedcom.co.uk>
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
  9. * files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
  10. * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
  11. * is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be
  12. * included in all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  15. * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  16. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  17. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. *
  19. * @package PHPVideoToolkit (was called ffmpeg)
  20. * @version 0.1.5
  21. * @changelog SEE CHANGELOG
  22. * @abstract This class can be used in conjunction with several server binary libraries to manipulate video and audio
  23. * through PHP. It is not intended to solve any particular problems, however you may find it useful. This php class
  24. * is in no way associated with the actual FFmpeg releases. Any mistakes contained in this php class are mine and mine
  25. * alone.
  26. *
  27. * Please Note: There are several prerequisites that are required before this class can be used as an aid to manipulate
  28. * video and audio. You must at the very least have FFMPEG compiled on your server. If you wish to use this class for FLV
  29. * manipulation you must compile FFMPEG with LAME and Ruby's FLVTOOL2. I cannot answer questions regarding the install of
  30. * the server binaries needed by this class. I had too learn the hard way and it isn't easy, however it is a good learning
  31. * experience. For those of you who do need help read the install.txt file supplied along side this class. It wasn't written
  32. * by me however I found it useful when installing ffmpeg for the first time. The original source for the install.txt file
  33. * is located http://www.luar.com.hk/blog/?p=669 and the author is Lunar.
  34. *
  35. * @see install.txt
  36. *
  37. * @uses ffmpeg http://ffmpeg.sourceforge.net/
  38. * @uses lame http://lame.sourceforge.net/
  39. * @uses flvtool2 http://www.inlet-media.de/flvtool2 (and ruby http://www.ruby-lang.org/en/)
  40. *
  41. * @config examples/example-config.php Please edit this files in order for the examples to work.
  42. * @example examples/example01.php Converts video to Flash Video (ie FLV).
  43. * @example examples/example02.php Screen grabs video frames.
  44. * @example examples/example03.php Compile a movie from multiple jpegs
  45. * @example examples/example04.php Watermark a video.
  46. * @example examples/example05.php Access media metadata without using the ffmpeg-php library.
  47. * @example examples/example06.php Extract audio from video.
  48. * @example examples/example07.php Join multiple videos together.
  49. * @example examples/example08.php Easy video conversion to common formats using the adapters.
  50. * @example examples/example09.php Shows you how to access the information about your ffmpeg installation.
  51. * @example examples/example10.php Shows you how to extract a specific frame from a movie.
  52. * @example examples/example11.php Shows you how to use the ffmpeg-php adapters to provide a pure php emulation of ffmpeg-php.
  53. * @example examples/example12.php Shows you how to manipulate/format timecode strings.
  54. * @example examples/example13.php This demonstrates how to simply create a FLV stream script.
  55. */
  56. /**
  57. * Set the ffmpeg binary path
  58. */
  59. if(!defined('PHPVIDEOTOOLKIT_FFMPEG_BINARY'))
  60. {
  61. define('PHPVIDEOTOOLKIT_FFMPEG_BINARY', '/usr/local/bin/ffmpeg');
  62. }
  63. /**
  64. * Set the flvtool2 binary path
  65. */
  66. if(!defined('PHPVIDEOTOOLKIT_FLVTOOLS_BINARY'))
  67. {
  68. define('PHPVIDEOTOOLKIT_FLVTOOLS_BINARY', '/usr/bin/flvtool2');
  69. }
  70. /**
  71. * Set the watermark vhook path
  72. */
  73. if(!defined('PHPVIDEOTOOLKIT_FFMPEG_WATERMARK_VHOOK'))
  74. {
  75. define('PHPVIDEOTOOLKIT_FFMPEG_WATERMARK_VHOOK', '/usr/local/lib/vhook/watermark.so');
  76. }
  77. /**
  78. * Set the memcoder path
  79. */
  80. if(!defined('PHPVIDEOTOOLKIT_MENCODER_BINARY'))
  81. {
  82. define('PHPVIDEOTOOLKIT_MENCODER_BINARY', '/usr/local/bin/mencoder');
  83. }
  84. /**
  85. * Codec support constants
  86. */
  87. define('PHPVIDEOTOOLKIT_ENCODE', 'encode');
  88. define('PHPVIDEOTOOLKIT_DECODE', 'decode');
  89. /**
  90. * Process Results from PHPVideoToolkit::execute
  91. */
  92. // any return value with this means everything is ok
  93. define('PHPVIDEOTOOLKIT_RESULT_OK', true);
  94. // any return value with this means the file has been processed/converted ok however it was
  95. // not able to be written to the output address. If this occurs you will need to move the
  96. // processed file manually from the temp location
  97. define('PHPVIDEOTOOLKIT_RESULT_OK_BUT_UNWRITABLE', -1);
  98. /**
  99. * Overwrite constants used in setOutput
  100. */
  101. define('PHPVIDEOTOOLKIT_OVERWRITE_FAIL', 'fail');
  102. define('PHPVIDEOTOOLKIT_OVERWRITE_PRESERVE', 'preserve');
  103. define('PHPVIDEOTOOLKIT_OVERWRITE_EXISTING', 'existing');
  104. define('PHPVIDEOTOOLKIT_OVERWRITE_UNIQUE', 'unique');
  105. /**
  106. * Formats supported
  107. * 3g2 3gp2 format
  108. * 3gp 3gp format
  109. * aac ADTS AAC
  110. * aiff Audio IFF
  111. * amr 3gpp amr file format
  112. * asf asf format
  113. * avi avi format
  114. * flv flv format
  115. * gif GIF Animation
  116. * mov mov format
  117. * mov,mp4,m4a,3gp,3g2,mj2 QuickTime/MPEG4/Motion JPEG 2000 format
  118. * mp2 MPEG audio layer 2
  119. * mp3 MPEG audio layer 3
  120. * mp4 mp4 format
  121. * mpeg MPEG1 System format
  122. * mpeg1video MPEG video
  123. * mpeg2video MPEG2 video
  124. * mpegvideo MPEG video
  125. * psp psp mp4 format
  126. * rm rm format
  127. * swf Flash format
  128. * vob MPEG2 PS format (VOB)
  129. * wav wav format
  130. * jpeg mjpeg format
  131. * yuv4mpegpipe yuv4mpegpipe format
  132. */
  133. define('PHPVIDEOTOOLKIT_FORMAT_3GP2', '3g2');
  134. define('PHPVIDEOTOOLKIT_FORMAT_3GP', '3gp');
  135. define('PHPVIDEOTOOLKIT_FORMAT_AAC', 'aac');
  136. define('PHPVIDEOTOOLKIT_FORMAT_AIFF', 'aiff');
  137. define('PHPVIDEOTOOLKIT_FORMAT_AMR', 'amr');
  138. define('PHPVIDEOTOOLKIT_FORMAT_ASF', 'asf');
  139. define('PHPVIDEOTOOLKIT_FORMAT_AVI', 'avi');
  140. define('PHPVIDEOTOOLKIT_FORMAT_FLV', 'flv');
  141. define('PHPVIDEOTOOLKIT_FORMAT_GIF', 'gif');
  142. define('PHPVIDEOTOOLKIT_FORMAT_MJ2', 'mj2');
  143. define('PHPVIDEOTOOLKIT_FORMAT_MP2', 'mp2');
  144. define('PHPVIDEOTOOLKIT_FORMAT_MP3', 'mp3');
  145. define('PHPVIDEOTOOLKIT_FORMAT_MP4', 'mp4');
  146. define('PHPVIDEOTOOLKIT_FORMAT_MPEG4', 'mpeg4');
  147. define('PHPVIDEOTOOLKIT_FORMAT_M4A', 'm4a');
  148. define('PHPVIDEOTOOLKIT_FORMAT_MPEG', 'mpeg');
  149. define('PHPVIDEOTOOLKIT_FORMAT_MPEG1', 'mpeg1video');
  150. define('PHPVIDEOTOOLKIT_FORMAT_MPEG2', 'mpeg2video');
  151. define('PHPVIDEOTOOLKIT_FORMAT_MPEGVIDEO', 'mpegvideo');
  152. define('PHPVIDEOTOOLKIT_FORMAT_PSP', 'psp');
  153. define('PHPVIDEOTOOLKIT_FORMAT_RM', 'rm');
  154. define('PHPVIDEOTOOLKIT_FORMAT_SWF', 'swf');
  155. define('PHPVIDEOTOOLKIT_FORMAT_VOB', 'vob');
  156. define('PHPVIDEOTOOLKIT_FORMAT_WAV', 'wav');
  157. define('PHPVIDEOTOOLKIT_FORMAT_JPG', 'mjpeg');
  158. define('PHPVIDEOTOOLKIT_FORMAT_Y4MP', 'yuv4mpegpipe');
  159. /**
  160. * Size Presets
  161. */
  162. define('PHPVIDEOTOOLKIT_SIZE_SAS', 'SameAsSource');
  163. define('PHPVIDEOTOOLKIT_SIZE_SQCIF', '128x96');
  164. define('PHPVIDEOTOOLKIT_SIZE_QCIF', '176x144');
  165. define('PHPVIDEOTOOLKIT_SIZE_CIF', '352x288');
  166. define('PHPVIDEOTOOLKIT_SIZE_4CIF', '704x576');
  167. define('PHPVIDEOTOOLKIT_SIZE_QQVGA', '160x120');
  168. define('PHPVIDEOTOOLKIT_SIZE_QVGA', '320x240');
  169. define('PHPVIDEOTOOLKIT_SIZE_VGA', '640x480');
  170. define('PHPVIDEOTOOLKIT_SIZE_SVGA', '800x600');
  171. define('PHPVIDEOTOOLKIT_SIZE_XGA', '1024x768');
  172. define('PHPVIDEOTOOLKIT_SIZE_UXGA', '1600x1200');
  173. define('PHPVIDEOTOOLKIT_SIZE_QXGA', '2048x1536');
  174. define('PHPVIDEOTOOLKIT_SIZE_SXGA', '1280x1024');
  175. define('PHPVIDEOTOOLKIT_SIZE_QSXGA', '2560x2048');
  176. define('PHPVIDEOTOOLKIT_SIZE_HSXGA', '5120x4096');
  177. define('PHPVIDEOTOOLKIT_SIZE_WVGA', '852x480');
  178. define('PHPVIDEOTOOLKIT_SIZE_WXGA', '1366x768');
  179. define('PHPVIDEOTOOLKIT_SIZE_WSXGA', '1600x1024');
  180. define('PHPVIDEOTOOLKIT_SIZE_WUXGA', '1920x1200');
  181. define('PHPVIDEOTOOLKIT_SIZE_WOXGA', '2560x1600');
  182. define('PHPVIDEOTOOLKIT_SIZE_WQSXGA', '3200x2048');
  183. define('PHPVIDEOTOOLKIT_SIZE_WQUXGA', '3840x2400');
  184. define('PHPVIDEOTOOLKIT_SIZE_WHSXGA', '6400x4096');
  185. define('PHPVIDEOTOOLKIT_SIZE_WHUXGA', '7680x4800');
  186. define('PHPVIDEOTOOLKIT_SIZE_CGA', '320x200');
  187. define('PHPVIDEOTOOLKIT_SIZE_EGA', '640x350');
  188. define('PHPVIDEOTOOLKIT_SIZE_HD480', '852x480');
  189. define('PHPVIDEOTOOLKIT_SIZE_HD720', '1280x720');
  190. define('PHPVIDEOTOOLKIT_SIZE_HD1080', '1920x1080');
  191. /**
  192. * Ratio Presets
  193. */
  194. define('PHPVIDEOTOOLKIT_RATIO_STANDARD', '4:3');
  195. define('PHPVIDEOTOOLKIT_RATIO_WIDE', '16:9');
  196. define('PHPVIDEOTOOLKIT_RATIO_CINEMATIC', '1.85');
  197. /**
  198. * @author Oliver Lillie (aka buggedcom) <publicmail@buggedcom.co.uk>
  199. * @license BSD
  200. * @package PHPVideoToolkit (was called ffmpeg)
  201. */
  202. class PHPVideoToolkit
  203. {
  204. var $version = '0.1.5';
  205. /**
  206. * Error strings
  207. */
  208. var $_messages = array(
  209. 'generic_temp_404' => 'The temporary directory does not exist.',
  210. 'generic_temp_writable' => 'The temporary directory is not write-able by the web server.',
  211. 'getFileInfo_no_input' => 'Input file does not exist so no information can be retrieved.',
  212. 'setInputFile_file_existence' => 'Input file "#file" does not exist',
  213. 'extractAudio_valid_format' => 'Value "#format" set from $toolkit->extractAudio, is not a valid audio format. Valid values ffmpeg PHPVIDEOTOOLKIT_FORMAT_AAC, PHPVIDEOTOOLKIT_FORMAT_AIFF, PHPVIDEOTOOLKIT_FORMAT_MP2, PHPVIDEOTOOLKIT_FORMAT_MP3, PHPVIDEOTOOLKIT_FORMAT_MP4, PHPVIDEOTOOLKIT_FORMAT_MPEG4, PHPVIDEOTOOLKIT_FORMAT_M4A or PHPVIDEOTOOLKIT_FORMAT_WAV. If you wish to specifically try to set another format you should use the advanced function $toolkit->addCommand. Set $command to "-f" and $argument to your required value.',
  214. 'extractFrame_video_frame_rate_404' => 'You have attempted to extract a thumbnail from a video while automagically guessing the framerate of the video, but the framerate could not be accessed. You can remove this error by manually setting the frame rate of the video.',
  215. 'extractFrame_video_info_404' => 'You have attempted to extract a thumbnail from a video and check to see if the thumbnail exists, however it was not possible to access the video information. Please check your temporary directory permissions for read/write access by the webserver.',
  216. 'extractFrame_video_frame_count' => 'You have attempted to extract a thumbnail from a video but the thumbnail you are trying to extract does not exist in the video.',
  217. 'extractFrames_video_begin_frame_count' => 'You have attempted to extract thumbnails from a video but the thumbnail you are trying to start the extraction from does not exist in the video.',
  218. 'extractFrames_video_end_frame_count' => 'You have attempted to extract thumbnails from a video but the thumbnail you are trying to end the extraction at does not exist in the video.',
  219. 'setFormat_valid_format' => 'Value "#format" set from $toolkit->setFormat, is not a valid format. Valid values are PHPVIDEOTOOLKIT_FORMAT_3GP2, PHPVIDEOTOOLKIT_FORMAT_3GP, PHPVIDEOTOOLKIT_FORMAT_AAC, PHPVIDEOTOOLKIT_FORMAT_AIFF, PHPVIDEOTOOLKIT_FORMAT_AMR, PHPVIDEOTOOLKIT_FORMAT_ASF, PHPVIDEOTOOLKIT_FORMAT_AVI, PHPVIDEOTOOLKIT_FORMAT_FLV, PHPVIDEOTOOLKIT_FORMAT_GIF, PHPVIDEOTOOLKIT_FORMAT_MJ2, PHPVIDEOTOOLKIT_FORMAT_MP2, PHPVIDEOTOOLKIT_FORMAT_MP3, PHPVIDEOTOOLKIT_FORMAT_MP4, PHPVIDEOTOOLKIT_FORMAT_MPEG4, PHPVIDEOTOOLKIT_FORMAT_M4A, PHPVIDEOTOOLKIT_FORMAT_MPEG, PHPVIDEOTOOLKIT_FORMAT_MPEG1, PHPVIDEOTOOLKIT_FORMAT_MPEG2, PHPVIDEOTOOLKIT_FORMAT_MPEGVIDEO, PHPVIDEOTOOLKIT_FORMAT_PSP, PHPVIDEOTOOLKIT_FORMAT_RM, PHPVIDEOTOOLKIT_FORMAT_SWF, PHPVIDEOTOOLKIT_FORMAT_VOB, PHPVIDEOTOOLKIT_FORMAT_WAV, PHPVIDEOTOOLKIT_FORMAT_JPG. If you wish to specifically try to set another format you should use the advanced function $toolkit->addCommand. Set $command to "-f" and $argument to your required value.',
  220. 'setAudioSampleFrequency_valid_frequency' => 'Value "#frequency" set from $toolkit->setAudioSampleFrequency, is not a valid integer. Valid values are 11025, 22050, 44100. If you wish to specifically try to set another frequency you should use the advanced function $toolkit->addCommand. Set $command to "-ar" and $argument to your required value.',
  221. 'setAudioFormat_valid_format' => 'Value "#format" set from $toolkit->setAudioFormat, is not a valid format. Valid values are PHPVIDEOTOOLKIT_FORMAT_AAC, PHPVIDEOTOOLKIT_FORMAT_AIFF, PHPVIDEOTOOLKIT_FORMAT_AMR, PHPVIDEOTOOLKIT_FORMAT_ASF, PHPVIDEOTOOLKIT_FORMAT_MP2, PHPVIDEOTOOLKIT_FORMAT_MP3, PHPVIDEOTOOLKIT_FORMAT_MP4, PHPVIDEOTOOLKIT_FORMAT_MPEG2, PHPVIDEOTOOLKIT_FORMAT_RM, PHPVIDEOTOOLKIT_FORMAT_WAV. If you wish to specifically try to set another format you should use the advanced function $toolkit->addCommand. Set $command to "-acodec" and $argument to your required value.',
  222. 'setVideoFormat_valid_format' => 'Value "#format" set from $toolkit->setAudioFormat, is not a valid format. Valid values are PHPVIDEOTOOLKIT_FORMAT_3GP2, PHPVIDEOTOOLKIT_FORMAT_3GP, PHPVIDEOTOOLKIT_FORMAT_AVI, PHPVIDEOTOOLKIT_FORMAT_FLV, PHPVIDEOTOOLKIT_FORMAT_GIF, PHPVIDEOTOOLKIT_FORMAT_MJ2, PHPVIDEOTOOLKIT_FORMAT_MP4, PHPVIDEOTOOLKIT_FORMAT_MPEG4, PHPVIDEOTOOLKIT_FORMAT_M4A, PHPVIDEOTOOLKIT_FORMAT_MPEG, PHPVIDEOTOOLKIT_FORMAT_MPEG1, PHPVIDEOTOOLKIT_FORMAT_MPEG2, PHPVIDEOTOOLKIT_FORMAT_MPEGVIDEO. If you wish to specifically try to set another format you should use the advanced function $toolkit->addCommand. Set $command to "-vcodec" and $argument to your required value.',
  223. 'setAudioBitRate_valid_bitrate' => 'Value "#bitrate" set from $toolkit->setAudioBitRate, is not a valid integer. Valid values are 16, 32, 64, 128. If you wish to specifically try to set another bitrate you should use the advanced function $toolkit->addCommand. Set $command to "-ab" and $argument to your required value.',
  224. 'prepareImagesForConversionToVideo_one_img' => 'When compiling a movie from a series of images, you must include at least one image.',
  225. 'prepareImagesForConversionToVideo_img_404' => '"#img" does not exist.',
  226. 'prepareImagesForConversionToVideo_img_copy' => '"#img" can not be copied to "#tmpfile"',
  227. 'prepareImagesForConversionToVideo_img_type' => 'The images can not be prepared for conversion to video. Please make sure all images are of the same type, ie gif, png, jpeg and then try again.',
  228. 'setVideoOutputDimensions_valid_format' => 'Value "#format" set from $toolkit->setVideoOutputDimensions, is not a valid preset dimension. Valid values are PHPVIDEOTOOLKIT_SIZE_SQCIF, PHPVIDEOTOOLKIT_SIZE_SAS, PHPVIDEOTOOLKIT_SIZE_QCIF, PHPVIDEOTOOLKIT_SIZE_CIF, PHPVIDEOTOOLKIT_SIZE_4CIF, PHPVIDEOTOOLKIT_SIZE_QQVGA, PHPVIDEOTOOLKIT_SIZE_QVGA, PHPVIDEOTOOLKIT_SIZE_VGA, PHPVIDEOTOOLKIT_SIZE_SVGA, PHPVIDEOTOOLKIT_SIZE_XGA, PHPVIDEOTOOLKIT_SIZE_UXGA, PHPVIDEOTOOLKIT_SIZE_QXGA, PHPVIDEOTOOLKIT_SIZE_SXGA, PHPVIDEOTOOLKIT_SIZE_QSXGA, PHPVIDEOTOOLKIT_SIZE_HSXGA, PHPVIDEOTOOLKIT_SIZE_WVGA, PHPVIDEOTOOLKIT_SIZE_WXGA, PHPVIDEOTOOLKIT_SIZE_WSXGA, PHPVIDEOTOOLKIT_SIZE_WUXGA, PHPVIDEOTOOLKIT_SIZE_WOXGA, PHPVIDEOTOOLKIT_SIZE_WQSXGA, PHPVIDEOTOOLKIT_SIZE_WQUXGA, PHPVIDEOTOOLKIT_SIZE_WHSXGA, PHPVIDEOTOOLKIT_SIZE_WHUXGA, PHPVIDEOTOOLKIT_SIZE_CGA, PHPVIDEOTOOLKIT_SIZE_EGA, PHPVIDEOTOOLKIT_SIZE_HD480, PHPVIDEOTOOLKIT_SIZE_HD720, PHPVIDEOTOOLKIT_SIZE_HD1080. You can also manually set the width and height.',
  229. 'setVideoOutputDimensions_sas_dim' => 'It was not possible to determine the input video dimensions so it was not possible to continue. If you wish to override this error please change the call to setVideoOutputDimensions and add a true argument to the arguments list... setVideoOutputDimensions(PHPVIDEOTOOLKIT_SIZE_SAS, true);',
  230. 'setVideoOutputDimensions_valid_integer' => 'You tried to set the video output dimensions to an odd number. FFmpeg requires that the video output dimensions are of event value and divisible by 2. ie 2, 4, 6,... etc',
  231. 'setVideoAspectRatio_valid_ratio' => 'Value "#ratio" set from $toolkit->setVideoOutputDimensions, is not a valid preset dimension. Valid values are PHPVIDEOTOOLKIT_RATIO_STANDARD, PHPVIDEOTOOLKIT_RATIO_WIDE, PHPVIDEOTOOLKIT_RATIO_CINEMATIC. If you wish to specifically try to set another video aspect ratio you should use the advanced function $toolkit->addCommand. Set $command to "-aspect" and $argument to your required value.',
  232. 'addWatermark_img_404' => 'Watermark file "#watermark" does not exist.',
  233. 'addWatermark_vhook_disabled' => 'Vhooking is not enabled in your FFmpeg binary. In order to allow video watermarking you must have FFmpeg compiled with --enable-vhook set. You can however watermark any extracted images using GD. To enable frame watermarking, call $toolkit->addGDWatermark($file) before you execute the extraction.',
  234. 'addVideo_file_404' => 'File "#file" does not exist.',
  235. 'setOutput_output_dir_404' => 'Output directory "#dir" does not exist!',
  236. 'setOutput_output_dir_writable' => 'Output directory "#dir" is not writable!',
  237. 'setOutput_%_missing' => 'The output of this command will be images yet you have not included the "%index" or "%timecode" in the $output_name.',
  238. 'setOutput_%d_depreciated' => 'The use of %d in the output file name is now depreciated. Please use %index. Number padding is still supported. You may also use %timecode instead to add a timecode to the filename.',
  239. 'execute_input_404' => 'Execute error. Input file missing.',
  240. 'execute_output_not_set' => 'Execute error. Output not set.',
  241. 'execute_overwrite_process' => 'Execute error. A file exists in the temp directory and is of the same name as this process file. It will conflict with this conversion. Conversion stopped.',
  242. 'execute_overwrite_fail' => 'Execute error. Output file exists. Process halted. If you wish to automatically overwrite files set the third argument in "PHPVideoToolkit::setOutput();" to "PHPVIDEOTOOLKIT_OVERWRITE_EXISTING".',
  243. 'execute_partial_error' => 'Execute error. Output for file "#input" encountered a partial error. Files were generated, however one or more of them were empty.',
  244. 'execute_image_error' => 'Execute error. Output for file "#input" was not found. No images were generated.',
  245. 'execute_output_404' => 'Execute error. Output for file "#input" was not found. Please check server write permissions and/or available codecs compiled with FFmpeg. You can check the encode decode availability by inspecting the output array from PHPVideoToolkit::getFFmpegInfo().',
  246. 'execute_output_empty' => 'Execute error. Output for file "#input" was found, but the file contained no data. Please check the available codecs compiled with FFmpeg can support this type of conversion. You can check the encode decode availability by inspecting the output array from PHPVideoToolkit::getFFmpegInfo().',
  247. 'execute_image_file_exists' => 'Execute error. There is a file name conflict. The file "#file" already exists in the filesystem. If you wish to automatically overwrite files set the third argument in "PHPVideoToolkit::setOutput();" to "PHPVIDEOTOOLKIT_OVERWRITE_EXISTING".',
  248. 'execute_result_ok_but_unwritable' => 'Process Partially Completed. The process successfully completed however it was not possible to output to "#output". The output was left in the temp directory "#process" for a manual file movement.',
  249. 'execute_result_ok' => 'Process Completed. The process successfully completed. Output was generated to "#output".',
  250. 'ffmpeg_log_ffmpeg_output' => 'OUTPUT',
  251. 'ffmpeg_log_ffmpeg_result' => 'RESULT',
  252. 'ffmpeg_log_ffmpeg_command' => 'COMMAND',
  253. 'ffmpeg_log_ffmpeg_join_gunk' => 'FFMPEG JOIN OUTPUT',
  254. 'ffmpeg_log_ffmpeg_gunk' => 'FFMPEG OUTPUT',
  255. 'ffmpeg_log_separator' => '-------------------------------'
  256. );
  257. /**
  258. * A public var that is to the information available about
  259. * the current ffmpeg compiled binary.
  260. * @var mixed
  261. * @access public
  262. */
  263. var $ffmpeg_info = false;
  264. /**
  265. * A private var that contains the info of any file that is accessed by PHPVideoToolkit::getFileInfo();
  266. * @var array
  267. * @access private
  268. */
  269. var $_file_info = array();
  270. /**
  271. * Determines what happens when an error occurs
  272. * @var boolean If true then the script will die, if not false is return by the error
  273. * @access public
  274. */
  275. var $on_error_die = false;
  276. /**
  277. * Holds the log file name
  278. * @var string
  279. * @access private
  280. */
  281. var $_log_file = null;
  282. /**
  283. * Determines if when outputting image frames if the outputted files should have the %d number
  284. * replaced with the frames timecode.
  285. * @var boolean If true then the files will be renamed.
  286. * @access public
  287. */
  288. var $image_output_timecode = true;
  289. /**
  290. * Holds the timecode separator for when using $image_output_timecode = true
  291. * Not all systems allow ':' in filenames.
  292. * @var string
  293. * @access public
  294. */
  295. var $timecode_seperator_output = '-';
  296. /**
  297. * Holds the starting time code when outputting image frames.
  298. * @var string The timecode hh(n):mm:ss:ff
  299. * @access private
  300. */
  301. var $_image_output_timecode_start = '00:00:00.00';
  302. /**
  303. * The format in which the image %timecode placeholder string is outputted.
  304. * - %hh (hours) representative of hours
  305. * - %mm (minutes) representative of minutes
  306. * - %ss (seconds) representative of seconds
  307. * - %fn (frame number) representative of frames (of the current second, not total frames)
  308. * - %ms (milliseconds) representative of milliseconds (of the current second, not total milliseconds) (rounded to 3 decimal places)
  309. * - %ft (frames total) representative of total frames (ie frame number)
  310. * - %st (seconds total) representative of total seconds (rounded).
  311. * - %sf (seconds floored) representative of total seconds (floored).
  312. * - %mt (milliseconds total) representative of total milliseconds. (rounded to 3 decimal places)
  313. * NOTE; there are special characters that will be replace by PHPVideoToolkit::$timecode_seperator_output, these characters are
  314. * - :
  315. * - .
  316. * @var string
  317. * @access public
  318. */
  319. var $image_output_timecode_format = '%hh-%mm-%ss-%fn';
  320. /**
  321. * Holds the fps of image extracts
  322. * @var integer
  323. * @access private
  324. */
  325. var $_image_output_timecode_fps = 1;
  326. /**
  327. * Holds the current execute commands that will need to be combined
  328. * @var array
  329. * @access private
  330. */
  331. var $_commands = array();
  332. /**
  333. * Holds the commands executed
  334. * @var array
  335. * @access private
  336. */
  337. var $_processed = array();
  338. /**
  339. * Holds the file references to those that have been processed
  340. * @var array
  341. * @access private
  342. */
  343. var $_files = array();
  344. /**
  345. * Holds the errors encountered
  346. * @access private
  347. * @var array
  348. */
  349. var $_errors = array();
  350. /**
  351. * Holds the input file / input file sequence
  352. * @access private
  353. * @var string
  354. */
  355. var $_input_file = null;
  356. /**
  357. * Holds the output file / output file sequence
  358. * @access private
  359. * @var string
  360. */
  361. var $_output_address = null;
  362. /**
  363. * Holds the process file / process file sequence
  364. * @access private
  365. * @var string
  366. */
  367. var $_process_address = null;
  368. /**
  369. * Temporary filename prefix
  370. * @access private
  371. * @var string
  372. */
  373. var $_tmp_file_prefix = 'tmp_';
  374. /**
  375. * Holds the temporary directory name
  376. * @access private
  377. * @var string
  378. */
  379. var $_tmp_directory = null;
  380. /**
  381. * Holds the directory paths that need to be removed by the ___destruct function
  382. * @access private
  383. * @var array
  384. */
  385. var $_unlink_dirs = array();
  386. /**
  387. * Holds the file paths that need to be deleted by the ___destruct function
  388. * @access private
  389. * @var array
  390. */
  391. var $_unlink_files = array();
  392. /**
  393. * Holds the timer start micro-float.
  394. * @access private
  395. * @var integer
  396. */
  397. var $_timer_start = 0;
  398. /**
  399. * Holds the times taken to process each file.
  400. * @access private
  401. * @var array
  402. */
  403. var $_timers = array();
  404. /**
  405. * Holds the times taken to process each file.
  406. * @access private
  407. * @var constant
  408. */
  409. var $_overwrite_mode = null;
  410. /**
  411. * Holds a integer value that flags if the image extraction is just a single frame.
  412. * @access private
  413. * @var integer
  414. */
  415. var $_single_frame_extraction = null;
  416. /**
  417. * Holds the watermark file that is used to watermark any outputted images via GD.
  418. * @access private
  419. * @var string
  420. */
  421. var $_watermark_url = null;
  422. /**
  423. * Holds the watermark options used to watermark any outputted images via GD.
  424. * @access private
  425. * @var array
  426. */
  427. var $_watermark_options = null;
  428. /**
  429. * Holds the number of files processed per run.
  430. * @access private
  431. * @var integer
  432. */
  433. var $_process_file_count = 0;
  434. /**
  435. * Holds the times taken to process each file.
  436. * @access private
  437. * @var array
  438. */
  439. var $_post_processes = array();
  440. /**
  441. * Holds commands should be sent added to the exec before the input file, this is by no means a definitive list
  442. * of all the ffmpeg commands, as it only utilizes the ones in use by this class. Also only commands that have
  443. * specific required places are entered in the arrays below. Anything not in these arrays will be treated as an
  444. * after-input item.
  445. * @access private
  446. * @var array
  447. */
  448. // var $_cmds_before_input = array();
  449. var $_cmds_before_input = array('-inputr');
  450. // var $_cmds_before_input = array('-r', '-f');
  451. /**
  452. * Constructs the class and sets the temporary directory.
  453. *
  454. * @access private
  455. * @param string $tmp_directory A full absolute path to you temporary directory
  456. */
  457. function PHPVideoToolkit($tmp_directory='/tmp/')
  458. {
  459. $this->_tmp_directory = $tmp_directory;
  460. // emulate php5 destructors
  461. register_shutdown_function(array(&$this, '__destruct'));
  462. }
  463. function microtimeFloat()
  464. {
  465. list($usec, $sec) = explode(" ", microtime());
  466. return ((float) $usec + (float) $sec);
  467. }
  468. /**
  469. * Resets the class
  470. *
  471. * @access public
  472. * @param boolean $keep_input_file Determines whether or not to reset the input file currently set.
  473. */
  474. function reset($keep_input_file=false, $keep_processes=false)
  475. {
  476. if($keep_input_file === false)
  477. {
  478. $this->_input_file = null;
  479. }
  480. if($keep_processes === false)
  481. {
  482. $this->_post_processes = array();
  483. }
  484. $this->_single_frame_extraction = null;
  485. $this->_output_address = null;
  486. $this->_process_address = null;
  487. $this->_log_file = null;
  488. $this->_commands = array();
  489. $this->_timer_start = 0;
  490. $this->_process_file_count = 0;
  491. $this->__destruct();
  492. }
  493. /**
  494. * Returns information about the specified file without having to use ffmpeg-php
  495. * as it consults the ffmpeg binary directly.
  496. *
  497. * @access public
  498. * @param string $file The absolute path of the file that is required to be manipulated.
  499. * @return mixed false on error encountered, true otherwise
  500. **/
  501. function getFFmpegInfo()
  502. {
  503. // check to see if this is a static call
  504. if(!$this)
  505. {
  506. $toolkit = new PHPVideoToolkit($tmp_directory);
  507. return $toolkit->getFFmpegInfo();
  508. }
  509. // check to see if the info has already been cached
  510. if($this->ffmpeg_info !== false)
  511. {
  512. return $this->ffmpeg_info;
  513. }
  514. // check to see if this is a static call
  515. $format = '';
  516. $info_file = $this->_tmp_directory.$this->unique('ffinfo').'.info';
  517. // execute the ffmpeg lookup
  518. // exec(PHPVIDEOTOOLKIT_FFMPEG_BINARY.' -formats &> '.$info_file);
  519. exec(PHPVIDEOTOOLKIT_FFMPEG_BINARY.' -formats 2>&1', $buffer);
  520. $buffer = implode("\r\n", $buffer);
  521. // $data = false;
  522. // try to open the file
  523. // $handle = fopen($info_file, 'r');
  524. // if($handle)
  525. // {
  526. // $data = array();
  527. // $buffer = '';
  528. // // loop through the lines of data and collect the buffer
  529. // while (!feof($handle))
  530. // {
  531. // $buffer .= fgets($handle, 4096);
  532. // }
  533. // echo($buffer);
  534. $data['compiler'] = array();
  535. $look_ups = array('configuration'=>'configuration: ', 'formats'=>'File formats:', 'codecs'=>'Codecs:', 'filters'=>'Bitstream filters:', 'protocols'=>'Supported file protocols:', 'abbreviations'=>'Frame size, frame rate abbreviations:', 'Note:');
  536. $total_lookups = count($look_ups);
  537. $pregs = array();
  538. $indexs = array();
  539. foreach($look_ups as $key=>$reg)
  540. {
  541. if(strpos($buffer, $reg) !== false)
  542. {
  543. $index = array_push($pregs, $reg);
  544. $indexs[$key] = $index;
  545. }
  546. }
  547. preg_match('/'.implode('(.*)', $pregs).'/s', $buffer, $matches);
  548. $configuration = trim($matches[$indexs['configuration']]);
  549. // grab the ffmpeg configuration flags
  550. preg_match_all('/--[a-zA-Z0-9\-]+/', $configuration, $config_flags);
  551. $data['compiler']['configuration'] = $config_flags[0];
  552. $data['compiler']['vhook-support'] = in_array('--enable-vhook', $config_flags[0]) && !in_array('--disable-vhook', $config_flags[0]);
  553. // grab the versions
  554. $data['compiler']['versions'] = array();
  555. preg_match_all('/([a-zA-Z0-9\-]+) version: ([0-9\.]+)/', $configuration, $versions);
  556. for($i=0, $a=count($versions[0]); $i<$a; $i++)
  557. {
  558. $data['compiler']['versions'][strtolower(trim($versions[1][$i]))] = $versions[2][$i];
  559. }
  560. // grab the ffmpeg compile info
  561. preg_match('/built on (.*), gcc: (.*)/', $configuration, $conf);
  562. if(count($conf) > 0)
  563. {
  564. $data['compiler']['gcc'] = $conf[2];
  565. $data['compiler']['build_date'] = $conf[1];
  566. $data['compiler']['build_date_timestamp'] = strtotime($conf[1]);
  567. }
  568. // grab the file formats available to ffmpeg
  569. preg_match_all('/ (DE|D|E) (.*) {1,} (.*)/', trim($matches[$indexs['formats']]), $formats);
  570. $data['formats'] = array();
  571. // loop and clean
  572. for($i=0, $a=count($formats[0]); $i<$a; $i++)
  573. {
  574. $data['formats'][strtolower(trim($formats[2][$i]))] = array(
  575. 'encode' => $formats[1][$i] == 'DE' || $formats[1][$i] == 'E',
  576. 'decode' => $formats[1][$i] == 'DE' || $formats[1][$i] == 'D',
  577. 'fullname' => $formats[3][$i]
  578. );
  579. }
  580. // grab the bitstream filters available to ffmpeg
  581. $data['filters'] = array();
  582. if(isset($indexs['filters']) && isset($matches[$indexs['filters']]))
  583. {
  584. $filters = trim($matches[$indexs['filters']]);
  585. if(empty($filters))
  586. {
  587. $data['filters'] = explode(' ', $filters);
  588. }
  589. }
  590. // grab the file prototcols available to ffmpeg
  591. $data['filters'] = array();
  592. if(isset($indexs['protocols']) && isset($matches[$indexs['protocols']]))
  593. {
  594. $protocols = trim($matches[$indexs['protocols']]);
  595. if(empty($protocols))
  596. {
  597. $data['protocols'] = explode(' ', str_replace(':', '', $protocols));
  598. }
  599. }
  600. // grab the abbreviations available to ffmpeg
  601. $data['abbreviations'] = array();
  602. if(isset($indexs['abbreviations']) && isset($matches[$indexs['abbreviations']]))
  603. {
  604. $abbreviations = trim($matches[$indexs['abbreviations']]);
  605. if(empty($abbreviations))
  606. {
  607. $data['abbreviations'] = explode(' ', $abbreviations);
  608. }
  609. }
  610. $this->ffmpeg_info = $data;
  611. }
  612. // fclose($handle);
  613. // if(is_file($info_file))
  614. // {
  615. // // if the info file exists remove it
  616. // unlink($info_file);
  617. // }
  618. $data['ffmpeg-php-support'] = $this->hasFFmpegPHPSupport();
  619. return $data;
  620. }
  621. /**
  622. * Determines the type of support that exists for the FFmpeg-PHP module.
  623. *
  624. * @access public
  625. * @return mixed. Boolean false if there is no support, String 'module' if the actuall
  626. * FFmpeg-PHP module is loaded, or String 'emulated' if the FFmpeg-PHP classes
  627. * can be emulated through the adapter classes.
  628. */
  629. function hasFFmpegPHPSupport()
  630. {
  631. return extension_loaded('ffmpeg') ? 'module' : (is_file(dirname(__FILE__).DIRECTORY_SEPARATOR.'adapters'.DIRECTORY_SEPARATOR.'ffmpeg-php'.DIRECTORY_SEPARATOR.'ffmpeg_movie.php') && is_file(dirname(__FILE__).DIRECTORY_SEPARATOR.'adapters'.DIRECTORY_SEPARATOR.'ffmpeg-php'.DIRECTORY_SEPARATOR.'ffmpeg_frame.php') && is_file(dirname(__FILE__).DIRECTORY_SEPARATOR.'adapters'.DIRECTORY_SEPARATOR.'ffmpeg-php'.DIRECTORY_SEPARATOR.'ffmpeg_animated_gif.php') ? 'emulated' : false);
  632. }
  633. /**
  634. * Determines if the ffmpeg binary has been compiled with vhook support.
  635. *
  636. * @access public
  637. * @return mixed. Boolean false if there is no support, true there is support.
  638. */
  639. function hasVHookSupport()
  640. {
  641. $info = $this->getFFmpegInfo();
  642. return $info['compiler']['vhook-support'];
  643. }
  644. /**
  645. * Returns information about the specified file without having to use ffmpeg-php
  646. * as it consults the ffmpeg binary directly. This idea for this function has been borrowed from
  647. * a French ffmpeg class located: http://www.phpcs.com/codesource.aspx?ID=45279
  648. *
  649. * @access public
  650. * @todo Change the search from string explode to a regex based search
  651. * @param string $file The absolute path of the file that is required to be manipulated.
  652. * @return mixed false on error encountered, true otherwise
  653. **/
  654. function getFileInfo($file=false, $tmp_directory='/tmp/')
  655. {
  656. // check to see if this is a static call
  657. if($file !== false && !$this)
  658. {
  659. $toolkit = new PHPVideoToolkit($tmp_directory);
  660. return $toolkit->getFileInfo($file);
  661. }
  662. // if the file has not been specified check to see if an input file has been specified
  663. if($file === false)
  664. {
  665. if(!$this->_input_file)
  666. {
  667. // input file not valid
  668. return $this->_raiseError('getFileInfo_no_input');
  669. //<- exits
  670. }
  671. $file = $this->_input_file;
  672. }
  673. $file = escapeshellarg($file);
  674. // die($file);
  675. // create a hash of the filename
  676. $hash = md5($file);
  677. // check to see if the info has already been generated
  678. if(isset($this->_file_info[$hash]))
  679. {
  680. return $this->_file_info[$hash];
  681. }
  682. // generate a random filename
  683. $info_file = $this->_tmp_directory.$this->unique($hash).'.info';
  684. // execute the ffmpeg lookup
  685. // exec(PHPVIDEOTOOLKIT_FFMPEG_BINARY.' -i '.$file.' &> '.$info_file);
  686. exec(PHPVIDEOTOOLKIT_FFMPEG_BINARY.' -i '.$file.' 2>&1', $buffer);
  687. $buffer = implode("\r\n", $buffer);
  688. // $data = false;
  689. // // try to open the file
  690. // $handle = fopen($info_file, 'r');
  691. // if($handle)
  692. // {
  693. // $data = array();
  694. // $buffer = '';
  695. // // loop through the lines of data and collect the buffer
  696. // while (!feof($handle))
  697. // {
  698. // $buffer .= fgets($handle, 4096);
  699. // }
  700. // die($buffer);
  701. // grab the duration and bitrate data
  702. preg_match_all('/Duration: (.*)/', $buffer, $matches);
  703. if(count($matches) > 0)
  704. {
  705. $parts = explode(', ', trim($matches[1][0]));
  706. $data['duration'] = array();
  707. $timecode = $parts[0];
  708. $data['duration']['seconds'] = $this->timecodeToSeconds($timecode);
  709. $data['bitrate'] = intval(ltrim($parts[2], 'bitrate: '));
  710. $data['duration']['start'] = ltrim($parts[1], 'start: ');
  711. $data['duration']['timecode'] = array();
  712. $data['duration']['timecode']['rounded'] = substr($timecode, 0, 8);
  713. $data['duration']['timecode']['seconds'] = array();
  714. $data['duration']['timecode']['seconds']['exact'] = $timecode;
  715. $data['duration']['timecode']['seconds']['excess'] = intval(substr($timecode, 9));
  716. }
  717. // match the video stream info
  718. preg_match('/Stream(.*): Video: (.*)/', $buffer, $matches);
  719. if(count($matches) > 0)
  720. {
  721. $data['video'] = array();
  722. // get the dimension parts
  723. // print_r($matches);
  724. preg_match('/([0-9]{1,5})x([0-9]{1,5})/', $matches[2], $dimensions_matches);
  725. // print_r($dimensions_matches);
  726. $dimensions_value = $dimensions_matches[0];
  727. $data['video']['dimensions'] = array(
  728. 'width' => floatval($dimensions_matches[1]),
  729. 'height' => floatval($dimensions_matches[2])
  730. );
  731. // get the framerate
  732. preg_match('/([0-9\.]+) (fps|tb)\(r\)/', $matches[0], $fps_matches);
  733. $data['video']['frame_rate'] = floatval($fps_matches[1]);
  734. $fps_value = $fps_matches[0];
  735. // get the ratios
  736. preg_match('/\[PAR ([0-9\:\.]+) DAR ([0-9\:\.]+)\]/', $matches[0], $ratio_matches);
  737. if(count($ratio_matches))
  738. {
  739. $data['video']['pixel_aspect_ratio'] = $ratio_matches[1];
  740. $data['video']['display_aspect_ratio'] = $ratio_matches[2];
  741. }
  742. // work out the number of frames
  743. if(isset($data['duration']) && isset($data['video']))
  744. {
  745. // set the total frame count for the video
  746. $data['video']['frame_count'] = ceil($data['duration']['seconds'] * $data['video']['frame_rate']);
  747. // set the framecode
  748. $frames = ceil($data['video']['frame_rate']*($data['duration']['timecode']['seconds']['excess']/10));
  749. $data['duration']['timecode']['frames'] = array();
  750. $data['duration']['timecode']['frames']['exact'] = $data['duration']['timecode']['rounded'].'.'.$frames;
  751. $data['duration']['timecode']['frames']['excess'] = $frames;
  752. $data['duration']['timecode']['frames']['total'] = $data['video']['frame_count'];
  753. }
  754. // formats should be anything left over, let me know if anything else exists
  755. $parts = explode(',', $matches[2]);
  756. $other_parts = array($dimensions_value, $fps_value);
  757. $formats = array();
  758. foreach($parts as $key=>$part)
  759. {
  760. $part = trim($part);
  761. if(!in_array($part, $other_parts))
  762. {
  763. array_push($formats, $part);
  764. }
  765. }
  766. $data['video']['pixel_format'] = $formats[1];
  767. $data['video']['codec'] = $formats[0];
  768. }
  769. // match the audio stream info
  770. preg_match('/Stream(.*): Audio: (.*)/', $buffer, $matches);
  771. if(count($matches) > 0)
  772. {
  773. // setup audio values
  774. $data['audio'] = array(
  775. 'stereo' => -1,
  776. 'sample_rate' => -1,
  777. 'sample_rate' => -1
  778. );
  779. $other_parts = array();
  780. // get the stereo value
  781. preg_match('/(stereo|mono)/i', $matches[0], $stereo_matches);
  782. if(count($stereo_matches))
  783. {
  784. $data['audio']['stereo'] = $stereo_matches[0];
  785. array_push($other_parts, $stereo_matches[0]);
  786. }
  787. // get the sample_rate
  788. preg_match('/([0-9]{3,6}) Hz/', $matches[0], $sample_matches);
  789. if(count($sample_matches))
  790. {
  791. $data['audio']['sample_rate'] = count($sample_matches) ? floatval($sample_matches[1]) : -1;
  792. array_push($other_parts, $sample_matches[0]);
  793. }
  794. // get the bit rate
  795. preg_match('/([0-9]{1,3}) kb\/s/', $matches[0], $bitrate_matches);
  796. if(count($bitrate_matches))
  797. {
  798. $data['audio']['bitrate'] = count($bitrate_matches) ? floatval($bitrate_matches[1]) : -1;
  799. array_push($other_parts, $bitrate_matches[0]);
  800. }
  801. // formats should be anything left over, let me know if anything else exists
  802. $parts = explode(',', $matches[2]);
  803. $formats = array();
  804. foreach($parts as $key=>$part)
  805. {
  806. $part = trim($part);
  807. if(!in_array($part, $other_parts))
  808. {
  809. array_push($formats, $part);
  810. }
  811. }
  812. $data['audio']['codec'] = $formats[0];
  813. }
  814. // check that some data has been obtained
  815. if(!count($data))
  816. {
  817. $data = false;
  818. }
  819. else
  820. {
  821. $data['_raw_info'] = $buffer;
  822. }
  823. // fclose($handle);
  824. // }
  825. // if(is_file($info_file))
  826. // {
  827. // // if the info file exists remove it
  828. // unlink($info_file);
  829. // }
  830. // cache info and return
  831. return $this->_file_info[$hash] = $data;
  832. }
  833. /**
  834. * Determines if your ffmpeg has particular codec support for encode or decode.
  835. *
  836. * @access public
  837. * @param string $codec The name of the codec you are checking for.
  838. * @param const $support PHPVideoToolkit::ENCODE or PHPVideoToolkit::DECODE, depending on which functionality is desired.
  839. * @return mixed. Boolean false if there is no support, true if there is support.
  840. */
  841. public function hasCodecSupport($codec, $support=PHPVideoToolkit::ENCODE)
  842. {
  843. $codec = strtolower($codec);
  844. $data = $this->getFFmpegInfo();
  845. return isset($data['formats'][$codec]) ? $data['formats'][$codec][$support] : false;
  846. }
  847. /**
  848. * Sets the input file that is going to be manipulated.
  849. *
  850. * @access public
  851. * @param string $file The absolute path of the file that is required to be manipulated.
  852. * @param mixed $input_frame_rate If 0 (default) then no input frame rate is set, if false it is automatically retreived, otherwise
  853. * any other integer will be set as the incoming frame rate.
  854. * @return boolean false on error encountered, true otherwise
  855. */
  856. function setInputFile($file, $input_frame_rate=0)
  857. {
  858. $files_length = count($file);
  859. // if the total number of files entered is 1 then only one file is being processed
  860. if($files_length == 1)
  861. {
  862. // check the input file, if there is a %d in there or a similar %03d then the file inputted is a sequence, if neither of those is found
  863. // then qheck to see if the file exists
  864. if(!preg_match('/\%([0-9]+)d/', $file) && strpos($file, '%d') === false && !is_file($file))
  865. {
  866. // input file not valid
  867. return $this->_raiseError('setInputFile_file_existence', array('file'=>$file));
  868. //<- exits
  869. }
  870. $escaped_name = $file;
  871. // $escaped_name = escapeshellarg($files[0]);
  872. $this->_input_file = $escaped_name;
  873. $this->_input_file_id = md5($escaped_name);
  874. // the -inputr is a hack for -r to come before the input
  875. if($input_frame_rate !== 0)
  876. {
  877. $info = $this->getFileInfo();
  878. if(isset($info['video']))
  879. {
  880. if($input_frame_rate === false)
  881. {
  882. $input_frame_rate = $info['video']['frame_rate'];
  883. }
  884. // input frame rate is a command hack
  885. $this->addCommand('-inputr', $input_frame_rate);
  886. }
  887. }
  888. }
  889. else
  890. {
  891. // more than one video is being added as input so we must join them all
  892. call_user_func_array(array(&$this, 'addVideo'), array($file, $input_frame_rate));
  893. }
  894. return true;
  895. }
  896. /**
  897. * A shortcut for converting video to FLV.
  898. *
  899. * @access public
  900. * @param integer $audio_sample_frequency
  901. * @param integer $audio_bitrate
  902. */
  903. function setFormatToFLV($audio_sample_frequency=44100, $audio_bitrate=64)
  904. {
  905. $this->addCommand('-sameq');
  906. $this->setAudioFormat(PHPVIDEOTOOLKIT_FORMAT_MP3);
  907. // adjust the audio rates
  908. $this->setAudioBitRate($audio_bitrate);
  909. $this->setAudioSampleFrequency($audio_sample_frequency);
  910. // set the video format
  911. $this->setFormat(PHPVIDEOTOOLKIT_FORMAT_FLV);
  912. // flag that the flv has to have meta data added after the excecution of this command
  913. // register the post tidy process
  914. $this->registerPostProcess('_addMetaToFLV', $this);
  915. }
  916. /**
  917. * When converting video to FLV the meta data has to be added by a ruby program called FLVTools2.
  918. * This is a second exec call only after the video has been converted to FLV
  919. * http://inlet-media.de/flvtool2
  920. *
  921. * @access private
  922. */
  923. function _addMetaToFLV($files)
  924. {
  925. $file = array_pop($files);
  926. // prepare the command suitable for exec
  927. $exec_string = $this->_prepareCommand(PHPVIDEOTOOLKIT_FLVTOOLS_BINARY, '-U '.$file);
  928. // execute the command
  929. exec($exec_string);
  930. if(is_array($this->_processed[0]))
  931. {
  932. array_push($this->_processed[0], $exec_string);
  933. }
  934. else
  935. {
  936. $this->_processed[0] = array($this->_processed[0], $exec_string);
  937. }
  938. return true;
  939. }
  940. /**
  941. * Streams a FLV file from a given point. You can control bandwidth, cache and session options.
  942. * Inspired by xmoov-php
  943. * @see xmoov-php,
  944. * - @link http://xmoov.com/
  945. * - @author Eric Lorenzo Benjamin jr
  946. * @access public
  947. * @param integer $seek_pos The position in the file to seek to.
  948. * @param array|boolean $bandwidth_options If a boolean value, false then no bandwidth limiting will take place.
  949. * If true then bandwidth limiting will take place with packet_size = 90 and packet_interval = 0.3.
  950. * If an array the following values are default packet_size = 90 and packet_interval = 0.3, you will also
  951. * have to set active = true, ie array('active'=>true, 'packet_size'=>90, 'packet_interval'=>0.3)
  952. * @param boolean $allow_cache If true the file will be allowed to cache in the browser, if false then it won't
  953. * @return boolean
  954. */
  955. public function flvStreamSeek($seek_pos=0, $bandwidth_options=array(), $allow_cache=true)
  956. {
  957. // check for input file
  958. if(!$this->_input_file)
  959. {
  960. // input file not valid
  961. return $this->_raiseError('streamFLV_no_input');
  962. //<- exits
  963. }
  964. // make the pos safe
  965. $seek_pos = intval($seek_pos);
  966. // absorb the bandwidth options
  967. $bandwidth_options = is_array($bandwidth_options) ? array_merge(array('active'=>false, 'packet_size'=>90, 'packet_interval'=>0.3), $bandwidth_options) : array('active'=>$bandwidth_options, 'packet_size'=>90, 'packet_interval'=>0.3);
  968. // if this file is not allowed to be cached send cache headers for all browsers.
  969. if(!$allow_cache)
  970. {
  971. session_cache_limiter('nocache');
  972. header('Expires: Thu, 19 Nov 1981 08:52:00 GMT');
  973. header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
  974. header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
  975. header('Pragma: no-cache');
  976. }
  977. // open file
  978. $handle = fopen($this->_input_file, 'rb');
  979. $file_size = filesize($this->_input_file) - (($seek_pos > 0) ? $seek_pos + 1 : 0);
  980. // send the flv headers
  981. header('Content-Type: video/x-flv');
  982. header('Content-Disposition: attachment; filename="'.basename($this->_input_file).'"');
  983. header('Content-Length: '.$file_size);
  984. // flv format header
  985. if($seek_pos != 0)
  986. {
  987. print('FLV');
  988. print(pack('C', 1));
  989. print(pack('C', 1));
  990. print(pack('N', 9));
  991. print(pack('N', 9));
  992. }
  993. // seek to the required point
  994. if(fseek($handle, $seek_pos) === -1)
  995. {
  996. // input file not valid
  997. return $this->_raiseError('streamFLV_passed_eof');
  998. //<- exits
  999. }
  1000. // if bandwidth control is active then workout the options
  1001. if($bandwidth_options['active'])
  1002. {
  1003. $packet_interval = intval($bandwidth_options['packet_interval']);
  1004. $packet_size = intval($bandwidth_options['packet_size']) * 1042;
  1005. }
  1006. // output the file
  1007. while(!feof($handle))
  1008. {
  1009. // limit the bandwidth
  1010. if($bandwidth_options['active'] && $packet_interval > 0)
  1011. {
  1012. // output the required packet
  1013. $time_start = $this->microtimeFloat();
  1014. echo fread($handle, $packet_size);
  1015. $time_stop = $this->microtimeFloat();
  1016. // delay the output
  1017. $time_difference = $time_stop - $time_start;
  1018. if($time_difference < $packet_interval)
  1019. {
  1020. usleep(($packet_interval * 1000000) - ($time_difference * 1000000));
  1021. }
  1022. }
  1023. // no bandwidth limiting
  1024. else
  1025. {
  1026. echo fread($handle, $file_size);
  1027. }
  1028. }
  1029. // close the file
  1030. fclose($handle);
  1031. return true;
  1032. }
  1033. /**
  1034. * This is an alias for setFormat, but restricts it to audio only formats.
  1035. *
  1036. * @access public
  1037. * @param integer $format A supported audio format.
  1038. * @param integer $audio_sample_frequency
  1039. * @param integer $audio_bitrate
  1040. **/
  1041. function extractAudio($format=PHPVIDEOTOOLKIT_FORMAT_MP3, $audio_sample_frequency=44100, $audio_bitrate=64)
  1042. {
  1043. // check the format is one of the audio formats
  1044. if(!in_array($format, array(PHPVIDEOTOOLKIT_FORMAT_AAC, PHPVIDEOTOOLKIT_FORMAT_AIFF, PHPVIDEOTOOLKIT_FORMAT_MP2, PHPVIDEOTOOLKIT_FORMAT_MP3, PHPVIDEOTOOLKIT_FORMAT_MP4, PHPVIDEOTOOLKIT_FORMAT_MPEG4, PHPVIDEOTOOLKIT_FORMAT_M4A, PHPVIDEOTOOLKIT_FORMAT_WAV)))
  1045. {
  1046. return $this->_raiseError('extractAudio_valid_format', array('format'=>$format));
  1047. //<- exits
  1048. }
  1049. $this->setFormat($format);
  1050. // adjust the audio rates
  1051. $this->setAudioBitRate($audio_bitrate);
  1052. $this->setAudioSampleFrequency($audio_sample_frequency);
  1053. }
  1054. /**
  1055. * Sets the new video format.
  1056. *
  1057. * @access public
  1058. * @param defined $format The format should use one of the defined variables stated below.
  1059. * PHPVIDEOTOOLKIT_FORMAT_3GP2 - 3g2
  1060. * PHPVIDEOTOOLKIT_FORMAT_3GP - 3gp
  1061. * PHPVIDEOTOOLKIT_FORMAT_AAC - aac
  1062. * PHPVIDEOTOOLKIT_FORMAT_AIFF - aiff
  1063. * PHPVIDEOTOOLKIT_FORMAT_AMR - amr
  1064. * PHPVIDEOTOOLKIT_FORMAT_ASF - asf
  1065. * PHPVIDEOTOOLKIT_FORMAT_AVI - avi
  1066. * PHPVIDEOTOOLKIT_FORMAT_FLV - flv
  1067. * PHPVIDEOTOOLKIT_FORMAT_GIF - gif
  1068. * PHPVIDEOTOOLKIT_FORMAT_MJ2 - mj2
  1069. * PHPVIDEOTOOLKIT_FORMAT_MP2 - mp2
  1070. * PHPVIDEOTOOLKIT_FORMAT_MP3 - mp3
  1071. * PHPVIDEOTOOLKIT_FORMAT_MP4 - mp4
  1072. * PHPVIDEOTOOLKIT_FORMAT_MPEG4 - mpeg4
  1073. * PHPVIDEOTOOLKIT_FORMAT_M4A - m4a
  1074. * PHPVIDEOTOOLKIT_FORMAT_MPEG - mpeg
  1075. * PHPVIDEOTOOLKIT_FORMAT_MPEG1 - mpeg1video
  1076. * PHPVIDEOTOOLKIT_FORMAT_MPEG2 - mpeg2video
  1077. * PHPVIDEOTOOLKIT_FORMAT_MPEGVIDEO - mpegvideo
  1078. * PHPVIDEOTOOLKIT_FORMAT_PSP - psp
  1079. * PHPVIDEOTOOLKIT_FORMAT_RM - rm
  1080. * PHPV…

Large files files are truncated, but you can click here to view the full file