/src/Zend/Media/Asf.php

http://php-reader.googlecode.com/ · PHP · 222 lines · 124 code · 15 blank · 83 comment · 20 complexity · 5b7a87b993df8c4034c13cd71f8deab0 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Media
  17. * @subpackage ASF
  18. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. * @version $Id: Asf.php 272 2012-03-29 19:53:29Z svollbehr $
  21. */
  22. /**#@+ @ignore */
  23. require_once 'Zend/Media/Asf/Object/Container.php';
  24. /**#@-*/
  25. /**
  26. * This class represents a file in Advanced Systems Format (ASF) as described in
  27. * {@link http://go.microsoft.com/fwlink/?LinkId=31334 The Advanced Systems
  28. * Format (ASF) Specification}. It is a file format that can contain various
  29. * types of information ranging from audio and video to script commands and
  30. * developer defined custom streams.
  31. *
  32. * The ASF file consists of code blocks that are called content objects. Each
  33. * of these objects have a format of their own. They may contain other objects
  34. * or other specific data. Each supported object has been implemented as their
  35. * own classes to ease the correct use of the information.
  36. *
  37. * @category Zend
  38. * @package Zend_Media
  39. * @subpackage ASF
  40. * @author Sven Vollbehr <sven@vollbehr.eu>
  41. * @author Elias Haapam?ki <elias.haapamaki@turunhelluntaisrk.fi>
  42. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  43. * @license http://framework.zend.com/license/new-bsd New BSD License
  44. * @version $Id: Asf.php 272 2012-03-29 19:53:29Z svollbehr $
  45. */
  46. class Zend_Media_Asf extends Zend_Media_Asf_Object_Container
  47. {
  48. /** @var string */
  49. private $_filename;
  50. /**
  51. * Constructs the ASF class with given file and options.
  52. *
  53. * The following options are currently recognized:
  54. * o encoding -- Indicates the encoding that all the texts are presented
  55. * with. By default this is set to utf-8. See the documentation of iconv
  56. * for accepted values.
  57. * o readonly -- Indicates that the file is read from a temporary location
  58. * or another source it cannot be written back to.
  59. *
  60. * @param string|resource|Zend_Io_Reader $filename The path to the file,
  61. * file descriptor of an opened file, or a {@link Zend_Io_Reader} instance.
  62. * @param Array $options The options array.
  63. */
  64. public function __construct($filename, $options = array())
  65. {
  66. if ($filename instanceof Zend_Io_Reader) {
  67. $this->_reader = &$filename;
  68. } else {
  69. require_once 'Zend/Io/FileReader.php';
  70. try {
  71. $this->_reader = new Zend_Io_FileReader($filename);
  72. } catch (Zend_Io_Exception $e) {
  73. $this->_reader = null;
  74. require_once 'Zend/Media/Id3/Exception.php';
  75. throw new Zend_Media_Asf_Exception($e->getMessage());
  76. }
  77. if (is_string($filename) && !isset($options['readonly'])) {
  78. $this->_filename = $filename;
  79. }
  80. }
  81. $this->setOptions($options);
  82. if ($this->getOption('encoding', null) === null) {
  83. $this->setOption('encoding', 'utf-8');
  84. }
  85. $this->setOffset(0);
  86. $this->setSize($this->_reader->getSize());
  87. $this->constructObjects
  88. (array
  89. (self::HEADER => 'Header',
  90. self::DATA => 'Data',
  91. self::SIMPLE_INDEX => 'SimpleIndex',
  92. self::INDEX => 'Index',
  93. self::MEDIA_OBJECT_INDEX => 'MediaObjectIndex',
  94. self::TIMECODE_INDEX => 'TimecodeIndex'));
  95. }
  96. /**
  97. * Returns the mandatory header object contained in this file.
  98. *
  99. * @return Zend_Media_Asf_Object_Header
  100. */
  101. public function getHeader()
  102. {
  103. $header = $this->getObjectsByIdentifier(self::HEADER);
  104. return $header[0];
  105. }
  106. /**
  107. * Returns the mandatory data object contained in this file.
  108. *
  109. * @return Zend_Media_Asf_Object_Data
  110. */
  111. public function getData()
  112. {
  113. $data = $this->getObjectsByIdentifier(self::DATA);
  114. return $data[0];
  115. }
  116. /**
  117. * Returns an array of index objects contained in this file.
  118. *
  119. * @return Array
  120. */
  121. public function getIndices()
  122. {
  123. return $this->getObjectsByIdentifier
  124. (self::SIMPLE_INDEX . '|' . self::INDEX . '|' .
  125. self::MEDIA_OBJECT_INDEX . '|' . self::TIMECODE_INDEX);
  126. }
  127. /**
  128. * Writes the changes to given media file. All object offsets must be
  129. * assumed to be invalid after the write operation.
  130. *
  131. * @param string $filename The optional path to the file, use null to save
  132. * to the same file.
  133. */
  134. public function write($filename)
  135. {
  136. if ($filename === null && ($filename = $this->_filename) === null) {
  137. require_once 'Zend/Media/Asf/Exception.php';
  138. throw new Zend_Media_Asf_Exception
  139. ('No file given to write to');
  140. } else if ($filename !== null && $this->_filename !== null &&
  141. realpath($filename) != realpath($this->_filename) &&
  142. !copy($this->_filename, $filename)) {
  143. require_once 'Zend/Media/Asf/Exception.php';
  144. throw new Zend_Media_Asf_Exception
  145. ('Unable to copy source to destination: ' .
  146. realpath($this->_filename) . '->' . realpath($filename));
  147. }
  148. if (($fd = fopen
  149. ($filename, file_exists($filename) ? 'r+b' : 'wb')) === false) {
  150. require_once 'Zend/Media/Asf/Exception.php';
  151. throw new Zend_Media_Asf_Exception
  152. ('Unable to open file for writing: ' . $filename);
  153. }
  154. $header = $this->getHeader();
  155. $headerLengthOld = $header->getSize();
  156. $header->removeObjectsByIdentifier(Zend_Media_Asf_Object::PADDING);
  157. $header->headerExtension->removeObjectsByIdentifier
  158. (Zend_Media_Asf_Object::PADDING);
  159. require_once 'Zend/Io/StringWriter.php';
  160. $buffer = new Zend_Io_StringWriter();
  161. $header->write($buffer);
  162. $headerData = $buffer->toString();
  163. $headerLengthNew = $header->getSize();
  164. // Fits right in
  165. if ($headerLengthOld == $headerLengthNew) {
  166. }
  167. // Fits with adjusted padding
  168. else if ($headerLengthOld >= $headerLengthNew + 24 /* for header */) {
  169. $header->headerExtension->padding->setSize
  170. ($headerLengthOld - $headerLengthNew);
  171. $buffer = new Zend_Io_StringWriter();
  172. $header->write($buffer);
  173. $headerData = $buffer->toString();
  174. $headerLengthNew = $header->getSize();
  175. }
  176. // Must expand
  177. else {
  178. $header->headerExtension->padding->setSize(4096);
  179. $buffer = new Zend_Io_StringWriter();
  180. $header->write($buffer);
  181. $headerData = $buffer->toString();
  182. $headerLengthNew = $header->getSize();
  183. fseek($fd, 0, SEEK_END);
  184. $oldFileSize = ftell($fd);
  185. ftruncate
  186. ($fd, $newFileSize = $headerLengthNew - $headerLengthOld +
  187. $oldFileSize);
  188. for ($i = 1, $cur = $oldFileSize; $cur > 0; $cur -= 1024, $i++) {
  189. if ($cur >= 1024) {
  190. fseek($fd, -(($i * 1024) +
  191. ($newFileSize - $oldFileSize)), SEEK_END);
  192. $buffer = fread($fd, 1024);
  193. fseek($fd, -($i * 1024), SEEK_END);
  194. fwrite($fd, $buffer, 1024);
  195. } else {
  196. fseek($fd, 0);
  197. $buffer = fread($fd, $cur);
  198. fseek($fd, $newFileSize - $oldFileSize);
  199. fwrite($fd, $buffer, $cur);
  200. }
  201. }
  202. }
  203. fseek($fd, 0);
  204. fwrite($fd, $headerData, $headerLengthNew);
  205. fclose($fd);
  206. }
  207. }