5 * The classes in this file are responsible for controlling the MVCP server.
7 * The class Melted is responsible for handling the connection to the MVCP server as well
8 * as passing commands and receiving responses from the server.
10 * The class Playout is responsible for retreiving and loading the appropriate items on the
11 * schedule. It will use the Melted class to initialize and update the server.
15 * Licensed under The MIT License
16 * Redistributions of files must retain the above copyright notice.
19 * @copyright 2010 Skyler Sully
22 * @version $Revision: $
23 * @modifiedby $LastChangedBy: ssully$
24 * @lastmodified $Date: $
25 * @license http://www.opensource.org/licenses/mit-license.php The MIT License
30 * Retreives schedule information and performs functions to playout assets based on
31 * the schedule on time. Uses the Melted class
34 * @subpackage application.vendors.socket.library.client
44 var $name = 'playout';
47 * Contains defaults for the Playout class. They will be overwritten
48 * by the config passed to the constructor
53 var $_defaults = array(
54 'host' => 'localhost',
60 * Contains the settings necessary for the Playout Client.
65 var $settings = array();
81 * Array of command responses from the MVCP server.
86 var $responses = array();
89 * Contains the MVCP client
97 * Contains the playlist for the current hour
102 var $playlist = array();
105 * Playout constructor
107 function __construct($config = array()) {
108 $this->settings
= array_merge($this->_defaults
, $config);
109 $this->_initialize();
113 * Initializes the MVCP client
118 function _initialize() {
119 extract($this->settings
);
120 $this->Mvcp
= new MvcpClient($host, $port, $mode);
125 * Connects to the MVCP server. If the connection has failed because the service is down,
126 * it attempts to restart the MVCP service. If the service cannot be restarted after the
127 * $maxRestartTries setting, it will reboot the server.
133 if( !$this->Mvcp
->open() ) {
136 return $this->Mvcp
->isConnected();
141 * Disconnects from the MVCP server
146 function disconnect() {
147 $this->Mvcp
->close();
151 * Shuts down the Playout service by stopping whatever is playing and clearing the unit.
156 function shutdown() {
157 if( !$this->Mvcp
->isConnected() ) {
160 $this->_command('stop');
161 $this->_command('clear');
162 $this->_disconnect();
166 * Sets the key and value on the unit
171 * @param $unit (optional)
174 function uset($key, $value, $unit = 0) {
175 $this->command('uset', array($key, $value), $errors, $unit);
180 * Get the value for the specified key on the unit
184 * @param $unit (optional)
187 function uget($key, $unit = 0) {
188 $this->command('uget', array($key), $errors, $unit);
193 * Loads a clip onto the unit
197 * @param $in (optional)
198 * @param $out (optional)
199 * @param $unit (optional)
202 function load($clip, $in = null
, $out = null
, $unit = 0) {
203 $this->command('load', array($clip, $in, $out), $errors, $unit);
208 * Appends a clip to the unit
212 * @param $in (optional)
213 * @param $out (optional)
214 * @param $unit (optional)
217 function append($clip, $in = null
, $out = null
, $unit = 0) {
218 $this->command('apnd', array($clip, $in, $out), $errors, $unit);
223 * Sets the in point for the current clip
227 * @param $unit (optional)
230 function set_in($frame, $unit = 0) {
231 $this->command('set_in', array($frame), $errors, $unit);
236 * Sets the out point for the current clip
240 * @param $unit (optional)
243 function set_out($frame, $unit = 0) {
244 $this->command('set_out', array($frame), $errors, $unit);
249 * Steps a certain number of frames (positive or negative)
253 * @param $unit (optional)
256 function step($frames, $unit = 0) {
257 $this->command('step', array($frames), $errors, $unit);
262 * Plays the current clip(s) on the specified unit
265 * @param $unit (optional)
268 function play($unit = 0) {
269 $this->command('play', array(), $errors, $unit);
274 * Stops the current playing clips on the specified unit
277 * @param $unit (optional)
280 function stop($unit = 0) {
281 $this->command('stop', array(), $errors, $unit);
286 * Clears the entire unit
289 * @param $unit (optional)
292 function clear($unit = 0) {
293 $this->command('clear', array(), $errors, $unit);
298 * Clears everything from the playlist that has already been played
301 * @param $unit (optional)
304 function wipe($unit = 0) {
305 $this->command('wipe', array(), $errors, $unit);
310 * Convenience function to send commands to the MVCP server via the Mvcp class.
313 * @param $command - function name that corresponds with the command
315 * @param $arguments - array of arguments for command
316 * @return boolean - status of command
318 function command($command, $arguments = array(), &$errors = array(), $unit = 0) {
320 $this->Mvcp
->setUnit($unit);
321 $errors[] = $this->Mvcp
->sendCommand($command, $arguments, $response);
323 $this->responses
[] = $response;
330 * Handles communication between the application and the MVCP server.
334 class MvcpClient
extends Client
337 * Contains the name of the program
342 var $name = 'melted';
345 * Contains all of the units that can be used in
351 var $units = array('U0', 'U1', 'U2', 'U3');
354 * The current unit that operations are being done on
362 * Initializes the MVCP by setting the default unit to U0
367 function _initialize() {
372 * Opens a connection with the MVCP server
378 if( $this->isConnected() ) {
381 $retval = $this->connect(true
, $status);
387 * Closes the connection with the MVCP server
393 if( !$this->isConnected() ) {
397 return !$this->disconnect();
401 * Restarts the MVCP service. This should be done if a connection cannot be made
402 * with the Mvcp Client class
410 exec("/sbin/service {$this->name} restart 2&>1", $output, $return);
419 * Sets the current unit. By default, sets the unit to the default
426 function setUnit($unit = 0) {
427 if( !is_int($unit) ) {
428 $this->_unit
= $this->units
[0];
429 } elseif( $unit < 0 ||
$unit > sizeof($this->units
) - 1 ) {
432 $this->_unit
= $this->units
[$unit];
437 * Sends the appropriate command to the MVCP server.
440 * @param $command - command to run
441 * @param $arguments - array of arguments
442 * @param $response - response to return
443 * @return boolean - status of command
445 function sendCommand($command, $arguments = array(), &$response) {
448 list($key, $value) = $arguments;
449 $_command = "uset {$this->_unit} {$key}={$value}";
452 list($key) = arguments
;
453 $_command = "uget {$this->_unit} {$key}";
456 list($clip, $in, $out) = $arguments;
457 $_command = trim("load {$this->_unit} {$clip} {$in} {$out}");
461 list($clip, $in, $out) = $arguments;
462 $_command = trim("apnd {$this->_unit} {$clip} {$in} {$out}");
466 list($frame) = $arguments;
467 $_command = "sin {$this->_unit} {$frame}";
471 list($frame) = $arguments;
472 $_command = "sout {$this->_unit} {$frame}";
475 $_command = "play {$this->_unit}";
478 $_command = "stop {$this->_unit}";
481 list($frames) = $arguments;
482 $_command = "step {$this->_unit} {$frames}";
485 $_command = "wipe {$this->_unit}";
488 $_command = "clear {$this->_unit}";
494 return $this->runCommand($_command, $response);
498 * Gets the status of the unit
504 if( !$this->isConnected() ) {
507 $this->write("usta {$this->_unit}");
510 $return = $this->read();
511 $status = $this->read();
513 list($unit, $mode, $currentClip, $currentFrame, $speed, $fps, $in, $out,
514 $length, $tailClip, $tailPosition, $tailIn, $tailOut, $tailLength,
515 $seekable, $playlistGenNumber, $clipIndex) = split(' ', $status);
517 return compact(array('unit', 'mode', 'currentClip', 'currentFrame', 'speed', 'fps', 'in', 'out',
518 'length', 'tailClip', 'tailPosition', 'tailIn', 'tailOut', 'tailLength',
519 'seekable', 'playlistGenNumber', 'clipIndex'));
523 * Lists the clips on the unit
528 function listClips() {
529 if( !$this->isConnected() ) {
532 $this->setBlockingMode(0);
533 $this->write("list {$this->_unit}");
536 $response = $this->read();
537 $_list = explode(PHP_EOL
, $response);
538 $response = array_shift($_list);
539 $genNum = array_shift($_list);
540 foreach( $_list as $clip ) {
541 list($index, $file, $in, $out, $realLength, $estimatedLength) = explode(' ', $clip);
542 $list[] = compact(array('index', 'file', 'in', 'out', 'realLength', 'estimatedLength'));
544 $this->setBlockingMode(1);
549 * Writes a command to the miracle server, gets the reponse and returns the
550 * status of the command as well as the command itself and the response code.
554 * @param $response - stores the command and response code
555 * @return boolean true on success, false on failure
557 function runCommand($command, &$response) {
558 if( !$this->isConnected() ) {
559 $response = "command - \"{$command}\" : not connected";
562 $this->write($command);
564 $_response = $this->read();
565 if( !empty($_response) ) {
566 $_codes = explode(" ", $_response);
567 if( isset($_codes[1]) && $_codes[1] != 'OK' ) {
573 $_response = "not connected";
576 $response = "command - \"{$command}\" : {$_response}";