view recorder.php @ 164:254d8a21bf36

fix: ͽÌóºÑ¤ß¤Î̤¼Â¹ÔÏ¿²è¤Ërecomplete.php¤¬É¬ÍפʤΤÇÌᤷ¤¿
author Sushi-k <epgrec@park.mda.or.jp>
date Tue, 06 Apr 2010 11:03:45 +0900
parents b3095425e613
children 68f6b36e7c01
line wrap: on
line source

#!/usr/bin/php
<?php
$script_path = dirname( __FILE__ );
chdir( $script_path );
include_once( $script_path . '/config.php');
include_once( INSTALL_PATH . "/DBRecord.class.php" );
include_once( INSTALL_PATH . "/Settings.class.php" );
include_once( INSTALL_PATH . "/recLog.inc.php" );
include_once( INSTALL_PATH . "/reclib.php" );

// 後方互æ›æ€§

if( ! defined( RECORDER_CMD ) ) {
	define( "RECORDER_CMD", INSTALL_PATH . "/recorder.php" );
}

$settings = Settings::factory();
$reserve_id = $argv[1];
$msgh_r = null;		// å—信用メッセージãƒãƒ³ãƒ‰ãƒ©
$msgh_w = null;		// é€ä¿¡ç”¨ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ãƒãƒ³ãƒ‰ãƒ©


// ノンブロッキングメッセージå—ä¿¡

function epgrec_get_message() {
	global $msgh_r, $reserve_id;
	
	$r = msg_receive($msgh_r, (int)$reserve_id , $msgtype, 1024, $message, TRUE, MSG_IPC_NOWAIT | MSG_NOERROR);
	if( $r ) return $message;
	
	return null;
}

// メッセージé€ä¿¡

function epgrec_send_message( $msg ) {
	global $msgh_w, $reserve_id;
	
	msg_send( $msgh_w, (int)$reserve_id, $msg );
	sleep(1);	// 相手ãŒå—ä¿¡ã—ã¦ãã‚Œãã†ãªæ™‚é–“ã ã‘å¾…ã¤
}


function epgrec_exec( $cmd ) {
	$descspec = array(
                        0 => array( 'file','/dev/null','r' ),
                        1 => array( 'file','/dev/null','w' ),
                        2 => array( 'file','/dev/null','w' ),
	);
	$p = proc_open( $cmd, $descspec, $pipes );
	if( is_resource( $p ) ) return $p;
	
	return false;
}

// 指定ã—ãŸãƒ—ロセスãƒãƒ³ãƒ‰ãƒ«ãŒç”Ÿæˆã—ãŸå­ãƒ—ロセスã®pidリストを返ã™
// ã“ã†ã„ã†ã‚„ã‚Šæ–¹ã—ã‹ãªã„ã®ã‹ï¼Ÿ
//
function epgrec_childproc( $p )
{
	$st = proc_get_status( $p );
	$ppid = $st['pid'];
	
	// ps を実行ã™ã‚‹
	$d = array(
			0 => array( 'file','/dev/null','r' ),
			1 => array( 'pipe','w' ),
			2 => array( 'file','/dev/null','w' ),
	);
	
	$ps = proc_open( "/bin/ps -o pid,ppid -ax" , $d, $pipes );
	do {
		$st = proc_get_status( $ps );
	}while( $st['running'] );
	
	// 標準出力を読む
	$cpids = array();
	while( ! feof( $pipes[1] ) ) {
		$line = fgets( $pipes[1] );
		$pids = preg_split( "/[\s]+/", $line );
		if( $pids[1] == $ppid ) {
			array_push( $cpids, $pids[0] );
		}
	}
	fclose( $pipes[1] );
	proc_close( $ps );
	
	return $cpids;
}

// 指定ã—ãŸãƒ—ロセスãƒãƒ³ãƒ‰ãƒ«ã‚’å­ãƒ—ロセスをå«ã‚終了ã•ã›ã‚‹

function epgrec_termproc( $p )
{
	$cpids = epgrec_childproc( $p );
	
	@proc_terminate( $p );
	sleep(1);
	@proc_terminate( $p );	// 2度é€ã‚‹
	
	foreach( $cpids as $cpid ) {
		@posix_kill( $cpid, SIGTERM );	// sigterm
		usleep(100);
		@posix_kill( $cpid, SIGKILL );	// sigkill
	}
	
	return true;	// ä¿è¨¼ã§ããªã„
}

////// ã“ã“ã‹ã‚‰æœ¬ç·¨


// メッセージãƒãƒ³ãƒ‰ãƒ©ã‚’å¾—ã‚‹
$ipc_key = ftok( RECORDER_CMD, "R" );
$msgh_r = msg_get_queue( $ipc_key );

$ipc_key = ftok( RECORDER_CMD, "W" );
$msgh_w = msg_get_queue( $ipc_key );

try{
	$rrec = new DBRecord( RESERVE_TBL, "id" , $reserve_id );
	
	// 時刻を得る
	$starttime = toTimestamp($rrec->starttime);
	$endtime   = toTimestamp($rrec->endtime);
	
	if( time() > $starttime ) {
		// éŽåŽ»ã®éŒ²ç”»äºˆç´„
		$rrec->complete = 1;	// 終ã‚ã£ãŸã“ã¨ã«ã™ã‚‹
		throw new RecException("recorder:: ãªãœã‹éŽåŽ»ã®éŒ²ç”»äºˆç´„ãŒå®Ÿè¡Œã•ã‚ŒãŸ", EPGREC_ERROR );
	}
	reclog("recorder:: 録画ID".$rrec->id .":".$rrec->type.$rrec->channel.$rrec->title."ã®éŒ²ç”»ã‚¸ãƒ§ãƒ–開始" );
	
	// 録画開始ã¾ã§å¾…ã¤
	while( time() < $starttime ) {
		if( ($message = epgrec_get_message() ) != null ) {
			switch( $message ) {
				case "terminate":			// 終了指示
					epgrec_send_message("success");
					$rrec->complete = 1;	// 終ã‚ã£ãŸã“ã¨ã«ã™ã‚‹
					throw new RecException("recorder:: 録画ID".$rrec->id .":".$rrec->type.$rrec->channel.$rrec->title."ã®éŒ²ç”»ãŒä¸­æ–­ã•ã‚ŒãŸ" );
					break;
				
				case "stat":
					epgrec_send_message("alive");
					break;
					
				default:
					break;
			}
		}
		usleep( 50 * 1000 );				// 50ミリ秒待ã¤
	}
	
	// 録画開始
	
	$proch = false;
	if( ( $proch = epgrec_exec(DO_RECORD) ) !== false ) {
		reclog("recorder:: 録画ID".$rrec->id .":".$rrec->type.$rrec->channel.$rrec->title."ã®éŒ²ç”»é–‹å§‹" );
		// 録画完了待ã¡
		$rec_cont = true;
		while( $rec_cont ){
			$st = proc_get_status($proch);
			if(! $st['running'] ) $rec_cont = false;    // 録画完了
			
			if( ($message = epgrec_get_message() ) != null ) {
				switch( $message ) {
					case "terminate":	// 終了指示
						if( epgrec_termproc( $proch ) == false ) {
							epgrec_send_message("error");
							reclog( "録画コマンドをåœæ­¢ã§ãã¾ã›ã‚“", EPGREC_WARN );
						}
						else {
							epgrec_send_message("success");
							reclog("recorder:: 録画ID".$rrec->id .":".$rrec->type.$rrec->channel.$rrec->title."ã®éŒ²ç”»ãŒä¸­æ–­ã•ã‚ŒãŸ" );
							$rec_cont = false;
						}
						break;
					
					case "stat":
						epgrec_send_message("alive");
						break;
				
					default:
						break;
				}
			}
			sleep(1);
		}
		proc_close( $proch );
		$proch = false;
	}
	else {
		$rrec->complete = 1;	// 終ã‚ã£ãŸã“ã¨ã«ã™ã‚‹
		throw new RecException("recorder:: 録画コマンドã®å®Ÿè¡Œã«å¤±æ•—ã—ãŸ", EPGREC_ERROR );
	}
	
	// 予定より短ã„よã†ãªã‚‰çµ‚了時間をç¾åœ¨ã«æ›¸ãæ›ãˆã‚‹
	if( time() < $endtime ) {
		$rrec->endtime = toDatetime( time() );
	}
	
	// 完了フラグを立ã¦ã¦ãŠã
	$rrec->complete = '1';
	
	// ã¡ã‚‡ã£ã¨å¾…ã£ãŸæ–¹ãŒç¢ºå®Ÿã£ã½ã„
	sleep(15);
	@exec("sync");
	
	if( file_exists( INSTALL_PATH .$settings->spool . "/". $rrec->path ) ) {
		// 予約完了
		reclog( "recorder:: 予約ID". $rrec->id .":".$rrec->type.$rrec->channel.$rrec->title."ã®éŒ²ç”»çµ‚了" );
	
		// サムãƒãƒ¼ãƒ«ä½œæˆ
		if( $settings->use_thumbs == 1 ) {
			$gen_thumbnail = INSTALL_PATH."/gen-thumbnail.sh";
			if( defined("GEN_THUMBNAIL") ) 
				$gen_thumbnail = GEN_THUMBNAIL;
			@exec($gen_thumbnail);
		}
		
		if( $settings->mediatomb_update == 1 ) {
			$dbh = mysql_connect( $settings->db_host, $settings->db_user, $settings->db_pass );
			if( $dbh !== false ) {
				$sqlstr = "use ".$settings->db_name;
				@mysql_query( $sqlstr );
				// 別ã«ã‚„らãªãã¦ã‚‚ã„ã„ãŒ
				$sqlstr = "set NAME utf8";
				@mysql_query( $sqlstr );
				$sqlstr = "update mt_cds_object set metadata='dc:description=".mysql_real_escape_string($rrec->description)."&epgrec:id=".$reserve_id."' where dc_title='".$rrec->path."'";
				@mysql_query( $sqlstr );
				$sqlstr = "update mt_cds_object set dc_title='".mysql_real_escape_string($rrec->title)."(".date("Y/m/d").")' where dc_title='".$rrec->path."'";
				@mysql_query( $sqlstr );
			}
		}
	}
	else {	// 予約失敗
		reclog( "recomplete:: 予約ID". $rrec->id .":".$rrec->type.$rrec->channel.$rrec->title."ã®éŒ²ç”»ã«å¤±æ•—ã—ãŸæ¨¡æ§˜", EPGREC_ERROR );
	}
}
catch( Exception $e ) {
	reclog( "recorder:: ".$e->getMessage(), $e->getLevel() );
}

msg_remove_queue( $msgh_r );	// メッセージãƒãƒ³ãƒ‰ãƒ©é–‹æ”¾
msg_remove_queue( $msgh_w );	// メッセージãƒãƒ³ãƒ‰ãƒ©é–‹æ”¾
?>