PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/sites/all/modules/video/libraries/phpvideotoolkit/phpvideotoolkit.php4.php

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

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