PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/services/services/resample/resample.php

https://github.com/jinzora/jinzora3
PHP | 317 lines | 205 code | 26 blank | 86 comment | 21 complexity | b44abdc7a7dda0f537e0866d12460e88 MD5 | raw file
  1. <?php if (!defined(JZ_SECURE_ACCESS)) die ('Security breach detected.');
  2. /**
  3. * - JINZORA | Web-based Media Streamer -
  4. *
  5. * Jinzora is a Web-based media streamer, primarily desgined to stream MP3s
  6. * (but can be used for any media file that can stream from HTTP).
  7. * Jinzora can be integrated into a CMS site, run as a standalone application,
  8. * or integrated into any PHP website. It is released under the GNU GPL.
  9. *
  10. * - Resources -
  11. * - Jinzora Author: Ross Carlson <ross@jasbone.com>
  12. * - Web: http://www.jinzora.org
  13. * - Documentation: http://www.jinzora.org/docs
  14. * - Support: http://www.jinzora.org/forum
  15. * - Downloads: http://www.jinzora.org/downloads
  16. * - License: GNU GPL <http://www.gnu.org/copyleft/gpl.html>
  17. *
  18. * - Contributors -
  19. * Please see http://www.jinzora.org/team.html
  20. *
  21. * - Code Purpose -
  22. * - Resample or transcode files on the fly to MP3 so they can more easily be streamed
  23. *
  24. * @since 05.25.05
  25. * @author Ross Carlson <ross@jinzora.org>
  26. * @author Ben Dodson <ben@jinzora.org>
  27. */
  28. define('SERVICE_RESAMPLE_resample','true');
  29. /**
  30. * Creates a resampled track
  31. *
  32. * @author Ross Carlson, Ben Dodson
  33. * @version 06.10.05
  34. * @since 06.10.05
  35. * @param $file The file that we are resampling/transcoding
  36. */
  37. function SERVICE_CREATE_RESAMPLED_TRACK($file, $format, $bitrate, $meta, $destination = false){
  38. global $path_to_lame, $path_to_flac, $path_to_mpc, $path_to_wavpack,
  39. $path_to_oggdec, $path_to_oggenc, $lame_cmd, $include_path,
  40. $jzSERVICES, $path_to_mpcenc, $path_to_wavunpack, $path_to_wmadec,
  41. $path_to_mplayer, $mplayer_opts, $path_to_faad;
  42. // Ok, now based on the input file let's create the beginning of the command
  43. $extArr = explode(".",$file);
  44. $ext = $extArr[count($extArr)-1];
  45. // Now let's create the output filename
  46. // Did they specify one?
  47. if ($destination){
  48. $outFile = $destination;
  49. } else {
  50. $outArry = explode("/",$file);
  51. $outFile = $outArry[count($outArry)-1];
  52. $outFile = getcwd(). "/data/resampled/". str_replace($ext,$format,$outFile);
  53. $outFile = str_replace(".". $format,"",$outFile). "-". $bitrate. ".". $format;
  54. }
  55. // Now, does the output file already exist? If so let's NOT do this again, ok?
  56. if (is_file($outFile)){
  57. return $outFile;
  58. }
  59. switch ($ext){
  60. case "flac":
  61. $command = $path_to_flac. ' -d -c --totally-silent "'. $file. '"';
  62. break;
  63. case "mpc":
  64. $command = $path_to_mpc. ' --wav "'. $file. '"';
  65. break;
  66. case "mp3":
  67. $command = $path_to_lame. ' --decode -S --silent --quiet "'. $file. '" - ';
  68. break;
  69. case "wv":
  70. $command = $path_to_wavunpack. ' -q "'. $file. '" - ';
  71. break;
  72. case "ogg":
  73. if (stristr($path_to_oggdec,"oggdec")){
  74. //$command = $path_to_oggdec. ' --stdout "'. $file. '"';
  75. $command = $path_to_oggdec . ' -Q "' . $file . '" -o -';
  76. } else {
  77. $command = $path_to_oggdec. ' --skip 1 -q -d wav -f - "'. $file. '"';
  78. }
  79. break;
  80. case "wma":
  81. $command .= ' | '. $path_to_wmadec. ' -w "'. $file. '"';
  82. break;
  83. case "wav":
  84. case "ra":
  85. case "ram":
  86. case "rm":
  87. case "m4a":
  88. $command = $path_to_mplayer. ' ' . $mplayer_opts . ' "' . $file . '"';
  89. break;
  90. default:
  91. return false;
  92. break;
  93. }
  94. // Ok, now that we have the input command let's create the output command
  95. switch ($format){
  96. case "mp3":
  97. // Now let's add the proper options to the lame command
  98. $command .= ' | '. $lame_cmd. $bitrate . ' -f - > "'. $outFile. '"';
  99. break;
  100. case "wav":
  101. $command .= ' > "'. $outFile. '"';
  102. break;
  103. case "mpc":
  104. // First let's figure out the quality setting
  105. switch ($bitrate){
  106. case "128":
  107. $quality = " --standard";
  108. break;
  109. case "192":
  110. $quality = " --xtreme";
  111. break;
  112. case "320":
  113. case "original":
  114. $quality = " --insane";
  115. break;
  116. }
  117. $command .= ' | '. $path_to_mpcenc. $quality. ' --silent --overwrite --standard - "'. $outFile. '"';
  118. break;
  119. case "wv":
  120. $command .= ' | '. $path_to_wavpack. ' -y -i -q - "'. $outFile. '"';
  121. break;
  122. case "flac":
  123. $command .= ' | '. $path_to_flac. ' --totally-silent - > "'. $outFile. '" ';
  124. break;
  125. case "ogg":
  126. return false;
  127. break;
  128. default:
  129. return false;
  130. break;
  131. }
  132. // Now let's fix up the paths for Windows
  133. if (stristr($_ENV['OS'],"win")){
  134. $command = str_replace("/","\\",$command);
  135. }
  136. // Let's log the command we just passed
  137. writeLogData("resample-command",$command);
  138. // Now let's execute the command
  139. exec($command);
  140. // Ok, now let's write the meta data to our new track
  141. $jzSERVICES->setTagData($outFile, $meta);
  142. // Now let's return the newly created filename
  143. return $outFile;
  144. }
  145. /**
  146. * Returns if the file is resampleable
  147. *
  148. * @author Ross Carlson, Ben Dodson
  149. * @version 06.10.05
  150. * @since 06.10.05
  151. * @param $file The file that we are resampling/transcoding
  152. */
  153. function SERVICE_IS_RESAMPLABLE($file){
  154. // Ok, let's check the file extension and see if we can resample it
  155. //Now let's figure out the file type
  156. $extArr = explode(".",$file);
  157. $ext = $extArr[count($extArr)-1];
  158. switch ($ext){
  159. case "mp3":
  160. case "flac":
  161. case "mpc":
  162. case "wv":
  163. case "ogg":
  164. case "wav":
  165. case "wma":
  166. case "ra":
  167. case "ram":
  168. case "rm":
  169. case "m4a":
  170. return true;
  171. break;
  172. default:
  173. return false;
  174. break;
  175. }
  176. }
  177. /**
  178. * The general resample/transcode function
  179. *
  180. * @author Ross Carlson, Ben Dodson
  181. * @version 05.25.05
  182. * @since 05.25.05
  183. * @param $file The file that we are resampling/transcoding
  184. * @param $name The name of the stream
  185. * @param $resample The rate to resample/transcode to
  186. */
  187. function SERVICE_RESAMPLE($file, $name, $resample){
  188. global $path_to_lame, $path_to_flac, $path_to_mpc, $path_to_wavunpack,
  189. $path_to_oggdec, $lame_cmd, $path_to_wmadec, $path_to_shn,
  190. $path_to_mplayer, $mplayer_opts, $path_to_faad, $path_to_macpipe, $path_to_ofr;
  191. $jzSERVICES = new jzServices();
  192. $jzSERVICES->loadStandardServices();
  193. // Now let's add the proper options to the lame command
  194. $lame_cmd .= $resample . ' -f -';
  195. //Now let's figure out the file type
  196. $extArr = explode(".",$file);
  197. $ext = $extArr[count($extArr)-1];
  198. // Now if we're on Windows we need to change the slashes for the command line
  199. if (stristr($_ENV['OS'],"win")){
  200. $file = str_replace("/","\\",$file);
  201. }
  202. switch ($ext){
  203. case "mp3":
  204. $meta = $jzSERVICES->getTagData($file);
  205. if ($meta['bitrate'] <= $resample) {
  206. header("Content-Type: audio/x-mp3");
  207. streamFile($file,$meta['artist'] . $meta['title'], $resample);
  208. exit();
  209. } else {
  210. $command = $path_to_lame. " --mp3input -S --silent --quiet --lowpass 12.0 --resample 22.05 -m j -b ". $resample. ' - < "'. $file. '" -';
  211. }
  212. break;
  213. case "flac":
  214. $command = $path_to_flac. ' -d -c --totally-silent "'. $file. '" | '. $lame_cmd;
  215. break;
  216. case "mpc":
  217. $command = $path_to_mpc. ' --wav "'. $file. '" | '. $lame_cmd;
  218. break;
  219. case "wv":
  220. $command = $path_to_wavunpack. ' -q "'. $file. '" - | '. $lame_cmd;
  221. break;
  222. case "ogg":
  223. // Ok, are they using oggdec or ogg123?
  224. if (stristr($path_to_oggdec,"oggdec")){
  225. //$command = $path_to_oggdec. ' --stdout "'. $file. '" | '. $lame_cmd;
  226. $command = $path_to_oggdec. ' -Q "'. $file. '" -o - | '. $lame_cmd;
  227. } else {
  228. $command = $path_to_oggdec. ' --skip 1 -q -d wav -f - "'. $file. '" | '. $lame_cmd;
  229. }
  230. break;
  231. case "wav":
  232. $command = $path_to_lame. " -S --silent --quiet --lowpass 12.0 --resample 22.05 -m j -b ". $resample. ' - < "'. $file. '" -';
  233. break;
  234. case "shn":
  235. if (stristr($_ENV['OS'],"win")){
  236. $command = $path_to_shn. ' -x "' . $file. '" - | '. str_replace(" -S --silent"," -x -S --silent",$lame_cmd);
  237. } else {
  238. $command = $path_to_shn. ' -x "' . $file. '" - | '. $lame_cmd;
  239. }
  240. break;
  241. case "wma":
  242. $command = $path_to_wmadec. ' -w "' . $file. '" | '. $lame_cmd;
  243. break;
  244. case "ape":
  245. $command = $path_to_macpipe. ' "' . $file. '" - -d | '. $lame_cmd;
  246. break;
  247. case "ofr":
  248. $command = $path_to_ofr. ' --decode --silent "' . $file. '" --output - | '. str_replace(" -S --silent"," -x -S --silent",$lame_cmd);
  249. break;
  250. case "ra":
  251. case "ram":
  252. case "rm":
  253. case "m4a":
  254. if (stristr($_ENV['OS'],"win")){
  255. $command = $path_to_faad. ' -w "' . $file. '" | '. str_replace(" -S --silent"," -x -S --silent",$lame_cmd);
  256. } else {
  257. $command = $path_to_mplayer. ' ' . $mplayer_opts . ' "' . $file . '" | '. $lame_cmd;
  258. }
  259. break;
  260. default:
  261. exit();
  262. break;
  263. }
  264. // Let's log the command we just passed
  265. writeLogData("resample-command",$command);
  266. // Now let's send the resampled data
  267. sendResampledFile($command,$name);
  268. exit();
  269. }
  270. /**
  271. * Sends the resampled/transcoded file
  272. *
  273. * @author Ross Carlson, Ben Dodson
  274. * @version 05.25.05
  275. * @since 05.25.05
  276. * @param $command The command to execute to resample/transcode
  277. * @param $name The name of the stream
  278. */
  279. function sendResampledFile($command, $name){
  280. // Now let's send the header
  281. // CRUCIAL: //
  282. ignore_user_abort(false);
  283. header("ICY 200 OK");
  284. header("icy-name: $name");
  285. header("Content-type: audio/mpeg");
  286. // header("Content-length: ".(string)(filesize($file))); // TODO: get the real filesize.
  287. header("Content-Disposition: inline; filename=\"".$name."\"");
  288. header("Connection: close");
  289. passthru($command);
  290. }
  291. ?>