Guest User

Untitled

a guest
Jan 22nd, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.24 KB | None | 0 0
  1. <?php
  2.  
  3. /*
  4. * qtfaststart.php v0.1 by Valentin Schmidt
  5. * based on qt-faststart.c v0.2 by Mike Melanson (melanson@pcisys.net)
  6. *
  7. * This file is placed in the public domain. Use the program however you
  8. * see fit.
  9. *
  10. * This utility rearranges a Quicktime file such that the moov atom
  11. * is in front of the data, thus facilitating network streaming.
  12. *
  13. * Notes: Quicktime files can come in many configurations of top-level
  14. * atoms. This utility stipulates that the very last atom in the file needs
  15. * to be a moov atom. When given such a file, this utility will rearrange
  16. * the top-level atoms by shifting the moov atom from the back of the file
  17. * to the front, and patch the chunk offsets along the way. This utility
  18. * presently only operates on uncompressed moov atoms.
  19. */
  20.  
  21. define('MOOV_ATOM', 'moov');
  22. define('FTYP_ATOM', 'ftyp');
  23. define('CMOV_ATOM', 'cmov');
  24. define('STCO_ATOM', 'stco');
  25. define('CO64_ATOM', 'co64');
  26.  
  27. define('ATOM_PREAMBLE_SIZE', 8);
  28. define('COPY_BUFFER_SIZE', 1024);
  29.  
  30. function
  31. BE_32($x, $offset=0){
  32. return
  33. (ord($x[$offset+0]) << 24) |
  34. (ord($x[$offset+1]) << 16) |
  35. (ord($x[$offset+2]) << 8) |
  36. (ord($x[$offset+3]));
  37. }
  38.  
  39. function
  40. BE_64($x, $offset=0){
  41. return
  42. (ord($x[$offset+0]) << 56) |
  43. (ord($x[$offset+1]) << 48) |
  44. (ord($x[$offset+2]) << 40) |
  45. (ord($x[$offset+3]) << 32) |
  46. (ord($x[$offset+4]) << 24) |
  47. (ord($x[$offset+5]) << 16) |
  48. (ord($x[$offset+6]) << 8) |
  49. (ord($x[$offset+7]));
  50. }
  51.  
  52. function
  53. status($s){
  54. echo $s.'<br />';
  55. }
  56.  
  57. function
  58. qtfaststart($inputVideoFile, $outputVideoFile){
  59.  
  60. $atom_offset = 0;
  61. $atom_type = '';
  62.  
  63. $infile = fopen($inputVideoFile, "rb");
  64. if (!$infile) {
  65. return 0;
  66. }
  67.  
  68.  
  69. /* traverse through the atoms in the file to make sure that 'moov' is at the end */
  70. while (!feof($infile)) {
  71. if (($atom_bytes = fread($infile, ATOM_PREAMBLE_SIZE)) == FALSE) {
  72. break;
  73. }
  74.  
  75. $atom_size = BE_32($atom_bytes, 0);
  76. $atom_type = substr($atom_bytes, 4, 4);
  77.  
  78. /* keep ftyp atom */
  79. if ($atom_type == FTYP_ATOM) {
  80. $ftyp_atom_size = $atom_size;
  81. fseek($infile, -ATOM_PREAMBLE_SIZE, SEEK_CUR);
  82. $ftyp_atom = fread($infile, $ftyp_atom_size);
  83. $start_offset = ftell($infile);
  84. } else {
  85. /* 64-bit special case */
  86. if ($atom_size == 1) {
  87. if (($atom_bytes = fread($infile, ATOM_PREAMBLE_SIZE)) == FALSE) {
  88. break;
  89. }
  90. $atom_size = BE_64($atom_bytes, 0);
  91. fseek($infile, $atom_size - ATOM_PREAMBLE_SIZE * 2, SEEK_CUR);
  92. } else {
  93. fseek($infile, $atom_size - ATOM_PREAMBLE_SIZE, SEEK_CUR);
  94. }
  95. }
  96.  
  97. $atom_offset += $atom_size;
  98.  
  99.  
  100. /* The atom header is 8 (or 16 bytes), if the atom size (which
  101. * includes these 8 or 16 bytes) is less than that, we won't be
  102. * able to continue scanning sensibly after this atom, so break. */
  103. if ($atom_size < 8) break;
  104. }
  105.  
  106. if (
  107. $atom_type != MOOV_ATOM) {
  108. status("last atom in file was not a moov atom");
  109. fclose($infile);
  110. return 0;
  111. }
  112.  
  113.  
  114. /* moov atom was, in fact, the last atom in the chunk; load the whole moov atom */
  115. fseek($infile, -$atom_size, SEEK_END);
  116. $last_offset = ftell($infile);
  117. $moov_atom_size = $atom_size;
  118. if (($moov_atom = fread($infile, $moov_atom_size)) == FALSE) {
  119. fclose($infile);
  120. return 0;
  121. }
  122.  
  123.  
  124. /* this utility does not support compressed atoms yet, so disqualify
  125. * files with compressed QT atoms */
  126. if (substr($moov_atom, 12, 4) == CMOV_ATOM) {
  127. status("this utility does not support compressed moov atoms yet");
  128. fclose($infile);
  129. return 0;
  130. }
  131.  
  132.  
  133. /* close; will be re-opened later */
  134. fclose($infile);
  135.  
  136.  
  137. /* crawl through the moov chunk in search of stco or co64 atoms */
  138. for ($i = 4; $i < $moov_atom_size - 4; $i++) {
  139. $atom_type = substr($moov_atom, $i, 4);
  140.  
  141. if ($atom_type == STCO_ATOM) {
  142. status(" patching stco atom");
  143. $atom_size = BE_32($moov_atom, $i - 4);
  144. if ($i + $atom_size - 4 > $moov_atom_size) {
  145. status(" bad atom size");
  146. return 0;
  147. }
  148. $offset_count = BE_32($moov_atom, $i + 8);
  149. for ($j = 0; $j < $offset_count; $j++) {
  150. $current_offset = BE_32($moov_atom, $i + 12 + $j * 4);
  151. $current_offset += $moov_atom_size;
  152. $moov_atom[$i + 12 + $j * 4 + 0] = chr( ($current_offset >> 24) & 0xFF);
  153. $moov_atom[$i + 12 + $j * 4 + 1] = chr( ($current_offset >> 16) & 0xFF);
  154. $moov_atom[$i + 12 + $j * 4 + 2] = chr( ($current_offset >> 8) & 0xFF);
  155. $moov_atom[$i + 12 + $j * 4 + 3] = chr( ($current_offset >> 0) & 0xFF);
  156. }
  157. $i += $atom_size - 4;
  158.  
  159. } else if ($atom_type == CO64_ATOM) {
  160. status(" patching co64 atom");
  161. $atom_size = BE_32($moov_atom, $i - 4);
  162. if ($i + $atom_size - 4 > $moov_atom_size) {
  163. status(" bad atom size");
  164. return 0;
  165. }
  166. $offset_count = BE_32($moov_atom, $i + 8);
  167. for ($j = 0; $j < $offset_count; $j++) {
  168. $current_offset = BE_64($moov_atom, $i + 12 + $j * 8);
  169. $current_offset += $moov_atom_size;
  170. $moov_atom[$i + 12 + $j * 8 + 0] = chr( ($current_offset >> 56) & 0xFF);
  171. $moov_atom[$i + 12 + $j * 8 + 1] = chr( ($current_offset >> 48) & 0xFF);
  172. $moov_atom[$i + 12 + $j * 8 + 2] = chr( ($current_offset >> 40) & 0xFF);
  173. $moov_atom[$i + 12 + $j * 8 + 3] = chr( ($current_offset >> 32) & 0xFF);
  174. $moov_atom[$i + 12 + $j * 8 + 4] = chr( ($current_offset >> 24) & 0xFF);
  175. $moov_atom[$i + 12 + $j * 8 + 5] = chr( ($current_offset >> 16) & 0xFF);
  176. $moov_atom[$i + 12 + $j * 8 + 6] = chr( ($current_offset >> 8) & 0xFF);
  177. $moov_atom[$i + 12 + $j * 8 + 7] = chr( ($current_offset >> 0) & 0xFF);
  178. }
  179. $i += $atom_size - 4;
  180. }
  181. }
  182.  
  183.  
  184. /* re-open the input file and open the output file */
  185. $infile = fopen($inputVideoFile, "rb");
  186. if (!$infile) {
  187. return 0;
  188. }
  189.  
  190. if (
  191. $start_offset > 0) { /* seek after ftyp atom */
  192. fseek($infile, $start_offset, SEEK_SET);
  193. $last_offset -= $start_offset;
  194. }
  195.  
  196.  
  197. $outfile = fopen($outputVideoFile, "wb");
  198. if (!$outfile) {
  199. fclose($infile);
  200. return 0;
  201. }
  202.  
  203.  
  204. /* dump the same ftyp atom */
  205. if ($ftyp_atom_size > 0) {
  206. status(" writing ftyp atom");
  207. if ((fwrite($outfile, $ftyp_atom, $ftyp_atom_size)) == FALSE) {
  208. fclose($infile);
  209. fclose($outfile);
  210. return 0;
  211. }
  212. }
  213.  
  214.  
  215. /* dump the new moov atom */
  216. status(" writing moov atom");
  217. if ((fwrite($outfile, $moov_atom, $moov_atom_size)) == FALSE) {
  218. fclose($infile);
  219. fclose($outfile);
  220. return 0;
  221. }
  222.  
  223.  
  224. /* copy the remainder of the infile, from offset 0 -> last_offset - 1 */
  225. status(" copying rest of file");
  226. while ($last_offset) {
  227. if ($last_offset > COPY_BUFFER_SIZE)
  228. $bytes_to_copy = COPY_BUFFER_SIZE;
  229. else
  230. $bytes_to_copy = $last_offset;
  231. if (($copy_buffer = fread($infile, $bytes_to_copy)) == FALSE) {
  232. fclose($infile);
  233. fclose($outfile);
  234. return 0;
  235. }
  236. if ((fwrite($outfile, $copy_buffer, $bytes_to_copy)) == FALSE) {
  237. fclose($infile);
  238. fclose($outfile);
  239. return 0;
  240. }
  241. $last_offset -= $bytes_to_copy;
  242. }
  243.  
  244.  
  245. fclose($infile);
  246. fclose($outfile);
  247. return 1;
  248. }
  249.  
  250. ?>
Add Comment
Please, Sign In to add comment