function getMetadata( $image, $path ) { global $wgffmpeg2theora; $metadata = array( 'version' => self::METADATA_VERSION ); //if we have fffmpeg2theora if( $wgffmpeg2theora && is_file( $wgffmpeg2theora ) ){ $mediaMeta = wahGetMediaJsonMeta( $path ); if( $mediaMeta ){ foreach($mediaMeta as $k=>$v){ if( !isset( $metadata[ $k ])) $metadata[ $k ] = $v; } }else{ $metadata['error'] = array( 'message' => 'could not parse ffmpeg2theora output', 'code' => 2 ); } }else{ $metadata['error'] = array( 'message' => 'missing ffmpeg2theora<br /> check that ffmpeg2theora is installed and that $wgffmpeg2theora points to its location', 'code' => 1 ); } return serialize( $metadata ); }
/** * process the submitted job: */ function doProccessJobKey( $job_key ){ global $wgRequest, $wgUser; //check if its a valid job key (job_number _ sh1(job_json) ) list($job_id, $json_sha1) = explode( '_', $job_key ); //get the job object $job = WahJobManager::getJobById( $job_id ); if( !$job || sha1($job->job_json) != $json_sha1){ //die on bad job key return $this->dieUsage('Bad Job key', 'badjobkey') ; } $jobSet = WahJobManager::getJobSetById( $job->job_set_id ); //check if its a valid video ogg file (ffmpeg2theora --info) $uploadedJobFile = $wgRequest->getFileTempname('file'); $mediaMeta = wahGetMediaJsonMeta( $uploadedJobFile ); if( !$mediaMeta ){ //failed basic ffmpeg2theora video validation return $this->dieUsage("Not a valid Video file", 'badfile'); } //gab the ogg types from OggHandler.php global $wgOggVideoTypes, $wgOggAudioTypes; //check for theora and vorbis streams in the metadata output of the file: if( isset($wgOggVideoTypes) && isset($wgOggAudioTypes) ){ $isOgg = false; foreach ( $mediaMeta->video as $videoStream ) { if(in_array( ucfirst( $videoStream->codec ), $wgOggVideoTypes)) $isOgg =true; } foreach ( $mediaMeta->audio as $audioStream ) { if(in_array( ucfirst( $audioStream->codec ), $wgOggAudioTypes)) $isOgg = true; } if(!$isOgg){ return $this->dieUsage( 'Not a valid Ogg file', 'badfile' ); } } //all good so far put it into the derivative temp folder by with each piece as it job_id name //@@todo need to rework this a bit for flattening "sequences" $fTitle = Title::newFromText( $jobSet->set_title, $jobSet->set_namespace ); $file = wfLocalFile( $fTitle ); $thumbPath = $file->getThumbPath( $jobSet->set_encodekey ); $destTarget = $thumbPath .'/'. $job->job_order_id . '.ogg'; if( is_file( $destTarget ) ){ //someone else beat this user to finish the job? or out-of-sync file system? //kind of tricky to tie the old file to a particular user so lets just: unlink($destTarget); //compare the oshashes? take the later file if they don't match /*$metaDest = wahGetMediaJsonMeta( $destTarget ); if( $mediaMeta->oshash == $metaDest->oshash ){ return $this->dieUsage( 'The target upload file already exists', 'alreadydone' ); }else{ //old exipred file? or someone order a job to override? remove old chunk and continue proccessing: unlink($destTarget); }*/ } //move the current chunk to that path: //@@todo use Repo methods (this is failing atm) /*$status = RepoGroup::singleton()->getLocalRepo()->store( $uploadedJobFile, 'thumb', $destTarget ); if( !$status->isGood() ){ return $this->dieUsageMsg( array('code'=>'fileerror', 'info'=>'Could Not Move The Uploaded File') ); }*/ wfMkdirParents( $thumbPath, null, __METHOD__ ); if( !move_uploaded_file($uploadedJobFile, $destTarget) ){ return $this->dieUsage( 'Could Not Move The Uploaded File', 'fileerror' ); } //issue the jobDone to the Manager: WahJobManager :: updateJobDone($job, $wgUser->getId()); $dbw = wfGetDB( DB_SLAVE ); //check if its the "last" job shell out a Join command $wjm = WahJobManager::newFromSet( $jobSet ); $percDone = $wjm->getDonePerc(); if($percDone != 1){ //the stream is not done but success on chunk return $this->getResult()->addValue( null, $this->getModuleName(), array( 'chunkaccepted' => true, 'setdone' => false ) ); }elseif( $percDone == 1 ){ //all the files are "done" according to the DB: //make sure all the files exist in the $fileList = array(); for( $i=0; $i < $jobSet->set_jobs_count ; $i++ ){ //make sure all the files are present: if(!is_file( "$thumbPath/{$i}.ogg" )){ wfDebug('Missing wikiAtHome chunk $i'); //unset the job complete state $dbw->update( 'wah_jobqueue', array( 'job_done_time = NULL', 'job_done_user_id = NULL' ), array( 'job_set_id' => $jobSet->set_id, 'job_order_id' => $i ), __METHOD__, array( 'LIMIT' => 1 ) ); //make sure jobset is not tagged done either: $dbw->update( 'wah_jobset', array( 'set_done_time = NULL' ), array( 'set_id' => $jobSet->set_id, ), __METHOD__, array( 'LIMIT' => 1 ) ); //return missing files (maybe something is ~broken~) wfDebug("WikiAtHome database out of sync with file system?\nFile: $thumbPath/{$i}.ogg missing, re-adding job"); return $this->getResult()->addValue( null, $this->getModuleName(), array( 'chunkaccepted' => true, 'setdone' => false ) ); } //else add it to the combine list: $fileList[] = "{$thumbPath}/{$i}.ogg"; } $finalDestTarget = "{$thumbPath}.ogg"; //make sure we have a set of thumbs to merge: if( count( $fileList ) > 1 ){ //do merge request //@@todo do this in a background shell task //( if the files are very large video could take longer than 30 seconds to concatenate ) wahDoOggCat( $finalDestTarget, $fileList); }else{ //rename to $finalDestTarget $curThumbPath = current( $fileList ); rename($curThumbPath, $finalDestTarget); } //if the file got created tag the jobset as done: if( is_file( $finalDestTarget )){ //@@do some more checks (like length is accurate and is ogg video) //update jobSet done: WahJobManager :: updateSetDone( $jobSet ); //send out stream done return $this->getResult()->addValue( null, $this->getModuleName(), array( 'chunkaccepted' => true, 'setdone' => true ) ); }else{ wfDebug( "Concatenation Failed. Tag job as failed?"); //tag the job as failed ( also put in the fail time ) $dbw->update('wah_jobset', array( 'set_done_time' => time(), 'set_failed' => 1 ), array( 'set_id' => $jobSet->set_id ), __METHOD__, array( 'LIMIT' => 1 ) ); //send join failed return $this->dieUsage("Concatenation Failed: $curThumbPath to $finalDestTarget" . count( $fileList ) . ' ' .print_r( $fileList ), 'catfail'); } } //return success }