Add Scroogle to your search area in Firefox 2.0 Install the 'Scroogle Scraper' search plugin.

finalImagine you were tasked with a photobooth for your local non-profit’s group valentine’s day party. Imagine you’d need to setup a backdrop, photograph couples and then print out photo prints with a nice graphic overlay. How might you automate this all?

Step 1: with your canon camera, download the EOS utility which allows you to remotely control your camera and save the pictures to your harddrive immediately.
Step 2: create this bash script which combines the last four most recent photos onto a blank 8″x10″ (at 300dpi) and then puts a graphic overlay on top of them:

user@server:~/Pictures$ cat makeprint.sh 
#!/opt/local/bin/bash
Col1X=95
Row1Y=80
Col2X=1400
Row2Y=1270
 
# Assume .JPG
PONE=`ls *.JPG|tail -n 4|head -n 1|sed 's/\.JPG//'`
PTWO=`ls *.JPG|tail -n 3|head -n 1|sed 's/\.JPG//'`
PTHREE=`ls *.JPG|tail -n 2|head -n 1|sed 's/\.JPG//'`
PFOUR=`ls *.JPG|tail -n 1|head -n 1|sed 's/\.JPG//'`
echo "processing pics"
echo "PONE: $PONE"
echo "PTWO: $PTWO"
echo "PTHREE: $PTHREE"
echo "PFOUR: $PFOUR"
 
#resize pics
convert ${PONE}.JPG -resize 1300x867 ${PONE}_resized.JPG
convert ${PTWO}.JPG -resize 1300x867 ${PTWO}_resized.JPG
convert ${PTHREE}.JPG -resize 1300x867 ${PTHREE}_resized.JPG
convert ${PFOUR}.JPG -resize 1300x867 ${PFOUR}_resized.JPG
 
rm -f stage1.jpg
rm -f stage2.jpg
rm -f stage3.jpg
rm -f stage4.jpg
rm -f final.jpg
 
#place resized image onto blank canvas
composite -geometry +$Col1X+$Row1Y ${PONE}_resized.JPG blank_canvas.png stage1.jpg
composite -geometry +$Col2X+$Col1X ${PTWO}_resized.JPG stage1.jpg stage2.jpg
composite -geometry +$Col1X+$Row2Y ${PTHREE}_resized.JPG stage2.jpg stage3.jpg
composite -geometry +$Col2X+$Row2Y ${PFOUR}_resized.JPG stage3.jpg stage4.jpg
 
#add template on top
composite valentine-photo-template.png stage4.jpg final.jpg
 
rm -f ${PONE}_resized.JPG
rm -r ${PTWO}_resized.JPG
rm -f ${PTHREE}_resized.JPG
rm -f ${PFOUR}_resized.JPG
rm -f stage1.jpg
rm -f stage2.jpg
rm -f stage3.jpg
rm -f stage4.jpg
open -a Preview final.jpg
mv ${PONE}.JPG printed/${PONE}.JPG
mv ${PTWO}.JPG printed/${PTWO}.JPG
mv ${PTHREE}.JPG printed/${PTHREE}.JPG
mv ${PFOUR}.JPG printed/${PFOUR}.JPG
 
lp -o landscape -o fit-to-page -o MediaType=hp-premium-photo-paper -o OutputMode=highest final.jpg

Step 3: you’ll need to have installed imagemagick

Here is a picture of my setup:
photoboothsetup

Ubuntu apparently supports blowfish, but an FTP service (pure-ftpd) running on ubuntu stubbornly refuses to either authenticate from a passwd of blowfish passwords or create new users with blowfish. it reverts to MD5.

in order to move an existing ftp service to this new ubuntu server, I wrote this external auth code:

#!/usr/bin/php
<?php 
define('LOGFILE','/var/log/ftp_custom_auth.log');
$passwdFile=file('/etc/pure-ftpd/pureftpd.passwd');
$passedInUsername=getenv('AUTHD_ACCOUNT');
$passedInPassword=getenv('AUTHD_PASSWORD');
$match=0;
function WriteLog($msg){
    $date = date('d.m.Y h:i:s');
    $log = $date.'|'.$msg."\n";
    file_put_contents(LOGFILE,$log,FILE_APPEND);
}
foreach($passwdFile as $passwdLine)
{
	$passwdLineArray=explode(':',$passwdLine);
	$username=$passwdLineArray[0];
	if ($username!=$passedInUsername) continue;
	$match=1;
	$blowfish=$passwdLineArray[1];
	$UID=$passwdLineArray[2];
	$GID=$passwdLineArray[3];
	$homeDir=$passwdLineArray[5];
	$salt=substr($blowfish,0,29).'$';
	$saltArray=explode('$',$salt);
	$authType=$saltArray[1]=='2a'?'blowfish':'md5';
	$justTheSalt=$saltArray[3];
	$hash=substr($blowfish,29,31);
	$computedHash=$computedBlowfish=crypt($passedInPassword,$salt);
	if ($computedBlowfish==$blowfish)
	{
		WriteLog("$username authd OK with $authType and $computedHash");
        	echo("auth_ok:1\n");
        	echo("uid:$UID\n");
        	echo("gid:$GID\n");
        	echo("dir:$homeDir\n");
                echo("end\n");
	}
	else
	{
		WriteLog("$username did NOT auth with $authType and $computedHash");
		echo("auth_ok:0\n");
	}
}
if (!$match)
{
	WriteLog("$username did NOT auth");
	echo("auth_ok:0\n");
}
echo("end\n");

Paessler is a company that makes software that monitors hardware assets, like web servers. Not too long ago, their CEO Dirk blogged about how they measure/rank new software feature requests.

I modified their formula slightly to reflect Scrum Story Points, because any formula that attempts to use development hours/days to calculate the value will be innately inaccurate. Instead, we should use a relative measure of complexity of projects and features (this is the idea of story points in Scrum) in place of trying to accurately estimate the amount of time something will take to complete.

To determine the business value of new software features:

  • Users: how many paying (or soon-to-be paying) customers will use and benefit from the requested feature? (also, potentially accounted for: Requested: how many Users asked for the feature?)
  • Thrill: How many (or how likely) will those Users be impressed, happy or relieved by the requested feature?
  • Annoyance: How much pain will be caused to those customers if this feature is NOT implemented (this is squared because an annoying problem is worse than a Thrill is good)
  • DevPoints: number of scrum story points to design, engineer, document, deploy and test the feature

Then, the modified Paessler formula is:
business_value_of_new_feature = ( Users * ( 1 + Thrill ) * ( 1 + Annoyance )² ) / DevPoints

For example:

  1. If we think of a feature that affects 100% of our users, has a Thrill of 100%, has an annoyance factor² of 100% and can be created with 1 story point: This reaches the maximum value of 800. Unfortunately no feature of such greatness is likely to be so easy to implement.
  2. Or think of a problem that affects half of our users (users=50%), with a medium annoyance (50%) and can be fixed in 2 story points: The bang for the buck is 56.

Schedules slip and scope creeps when so-called must-have-features (and even worse when low value features) bloat the original software requirements. 37signals (the creators of Basecamp) had this to say about the avalanche of feature requests.

In general, Feature Requests can be ranked:

  1. Issues related to a recent upgrade or migration (most important).
  2. Security fixes.
  3. Broken functionality of the existing system.
  4. Broken functionality in RC and beta features.
  5. Paid feature requests.
  6. R&D feature requests from a large part of the user base.
  7. R&D feature requests from only one or two users.

How do you decide which features will be implemented into your software?

I took my list of Christmas Card Addresses and put them into a Google spreadsheet. The top row is the header row and has title, address1, address2, city, state and zip.

Then I published that spreadsheet so I could get a URL like: https://docs.google.com/spreadsheet/pub?key=blahblabhblah&output=csv

Then I parsed that csv into an array:

$googleSpreadSheet="https://docs.google.com/spreadsheet/pub?key=blabblahblabh&output=csv";
$handle = fopen($googleSpreadSheet, "r");
$iteration=1;
$row=0;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
{
        if ($iteration++==1)
        {
                foreach($data as $header)
                {
                        $headerArray[]=$header;
                }
                continue;
        }
        $index=0;
        foreach($data as $element)
        {
                $spreadSheet[$row][$headerArray[$index++]]=$element;
        }
        $row++;
}
fclose($handle);

then I downloaded fpdf. (yes, I know that tcpdf is supposed to be better. i don’t care.) Then I grabbed this German dude’s fpdf class: http://www.fpdf.de/downloads/addons/29/
then I called his class, a-like-a-this:

define('FPDF_FONTPATH', 'font/');
require_once('PDF_Label.php');
$pdf = new PDF_Label('5163b', 'mm');
$pdf->Open();
 
foreach($spreadSheet as $row)
{
       $pdf->Add_PDF_Label("\n\n\n".$row['Title'],"\n\n\n".sprintf("%s\n%s, %s %s",$row['Address1'],$row['City'],$row['State'],$row['Zip']));
}
$pdf->Output('Labels.pdf', 'D');

yes, there is some hackery going on. I defined a new page style, 5163b which looks like this:

'5163b'=>array('name'=>'5163b',     'paper-size'=>'letter',     'metric'=>'mm',     'marginLeft'=>25,     'marginTop'=>10.7,         'NX'=>2,     'NY'=>5,     'SpaceX'=>5,     'SpaceY'=>0,     'width'=>101.6,         'height'=>54,         'font-size'=>11),

and I wanted the first line of the address to be bolded, so, I modified function Add_PDF_Label:

function Add_PDF_Label($title,$texte) {
        if (($this->_COUNTX ==0) and ($this->_COUNTY==0)) {
            $this->AddPage();
        }
 
        $_PosX = $this->_Margin_Left+($this->_COUNTX*($this->_Width+$this->_X_Space));
        $_PosY = $this->_Margin_Top+($this->_COUNTY*($this->_Height+$this->_Y_Space));
        $this->SetFont($this->_Font_Name,'B');
        $this->SetXY($_PosX+3, $_PosY-2);
        $this->MultiCell($this->_Width, $this->_Line_Height-1, $title);
        $this->SetFont($this->_Font_Name);

And whammo! Nifty Printed Avery 5163 Labels for Christmas Cards with addresses pulled directly from a Google SpreadSheet.

Merry Christmas!

This is an outline of the present state of the IT world, as I see it, now, in December 2012. No doubt this outline will have a limited useful lifetime as new technologies and companies emerge and as old school tech is discarded.

1. Problem definition (your present PHP/MySQL/Linux is slow, but let's describe it first)
   1.1 System description (where it's hosted, what hardware, etc.) 
       1.1.1 Watch out for Hard to scale processes: sockets, file level operations (exec’ing binaries, etc)
     1.1.2 Scheduled jobs (cronjobs) and database operations can affect websites
     1.1.3 Traffic patterns: Large email marketing blasts can create traffic spikes
     1.1.4 How much of the content is cacheable?
   1.2 IT/Dev resources
   1.3 Budget
   1.4 Planned growth
   1.5 Risk assessment
2. Baseline performance
   2.1 internal monitoring
       2.1.1 system monitoring (nagios)
       2.1.2 use case monitoring (selenium, saucelabs)
   2.2 external monitoring: alertsite, keynote, monitis
3. Control v outsourcing v price
   3.1 own hardware, in colo, physical access (dell,viawest)
   3.2 leased dedicated hardware, in data center (rackspace)
   3.3 virtualized hardware, storage and autoscaling (ec2, s3, rightscale)
   3.4 Paas: heroku, openshift, zend phpcloud
4. Caching/Accelerating
   4.1 CDN (or nginx or lighttpd)
   4.2 queries (memcache)
   4.3 web pages (varnish, eAccelerator)
5. Scaling load
   5.1 db cluster (Master/Slave, Master/Master)
   5.2 distributed/sync'd file systems (rsync, nfs)
   5.3 web load balancing (bigip, linux-ha, amazon elastic load balancing)
   5.4 DNS
   5.5 Session management
6. Scaling server configuration
   6.1 puppet
7. Security/backups/DR
   7.1 patch management
   7.2 vulnerability scans (nessus)
   7.3 virus scan (clamAV)
   7.3 file backups
       7.3.1 onsite rsnapshot
       7.3.2 offsite jungledisk
   7.4 database backups
       7.4.1 daily dumps
       7.4.2 log shipping
Next Steps:
   1. Decision/roadmap
       1.1 best practices
       1.2 industry standards
       1.3 technology tradeoffs
   2. Implementation
   3. Evaluation/assessment
   4. Monitoring

Wouldn’t you think that someone had figured out how to use nagios to test a phone system with a real-live external phone call? you’d be wrong. Am I the only one who wants to know if our phone system is up or ringing busy?!?

This proof of concept rings a number, announces itself, plays some DTMF tones to navigate an IVR, captures response DTMF digits in reply and returns those to nagios as integer characters.

I had to use some undocumented twilio features (e.g. the digits in the play tag.)

Also, twilio xml is kind of wack- <Response></Response> and <Response/> are NOT EQUAL. The first is invalid and will throw an application error. Also the play tag with digits has to be above the gather tag. Way to go, Twilio…

Here are the test files I wrote (sorry, they’re crudely written…) :

[root@server twilio_test]# cat checkNumber.sh 
#!/bin/bash
 
function usage_and_exit()
{
    echo "USAGE: $0 -p <phone number to check>"
    exit 1
}
 
if [ $# -lt 1 ] ; then
   usage_and_exit
fi
cat /dev/null >lastdigits.txt
./call-request.php $2
sleep 1
./call-log.php
echo "Target System Replied: "
cat lastdigits.txt
[root@server twilio_test]# cat index.html 
<?xml version='1.0' encoding='utf-8' ?>
<Response>
<Say>Nagios Test call.</Say>
        <Play digits="*12345" />
<Gather method="POST" numDigits="5" timeout="20" action="http://www.testserver.net/twilio_latest/digits_write.php">
<Say>Waiting.</Say>
</Gather>
<Redirect method="POST">
http://www.testserver.net/twilio_latest/digits_write.php?TIMEOUT=true
</Redirect>
</Response>
[root@server twilio_test]# cat status_write.php 
<?php
echo("<?xml version='1.0' encoding='utf-8' ?> <Response/>\n");
$requestArray=print_r($_REQUEST,true);
file_put_contents("status.txt",$requestArray,FILE_APPEND);
?>
[root@server twilio_test]# cat digits_write.php 
<?php
echo("<?xml version='1.0' encoding='utf-8' ?> <Response/>\n");
$requestArray=print_r($_REQUEST,true);
file_put_contents("digits.txt",$requestArray,FILE_APPEND);
if (isset($requestArray['Digits']))
{
file_put_contents("lastdigits.txt",$_REQUEST['Digits']."\n"); //overwrite file each time
}
?>
[root@server twilio_test]# cat call-request.php 
#!/usr/bin/php
<?php
$targetPhone=$_SERVER['argv'][1];
require 'Services/Twilio.php';
$version = "2010-04-01";
$sid='AC777a7698fc0d37fblahblah';
$token='-----------------------------------';
$phonenumber = '8018675309';
$client = new Services_Twilio($sid, $token, $version);
try {
$options = array("StatusCallback" => "http://www.testserver.net/twilio_latest/status_write.php",
'IfMachine'=>'Continue',
'Timeout'=>'15',
'Record'=>'true'
); 
$call = $client->account->calls->create(
$phonenumber, // The number of the phone initiating the call
$targetPhone,
'http://www.testserver.net/twilio_latest/', // The URL Twilio will request when the call is answered
$options
);
echo 'Started call: ' . $call->sid;
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
[root@server twilio_test]# cat call-log.php 
#!/usr/bin/php
<?php
echo(". waiting for call status.");
$incompleteArray=array('queued','ringing','in-progress');
$problemArray=array('busy','failed','no-answer');
require 'Services/Twilio.php';
$version = '2010-04-01';
$sid='AC777a7698fc0d37fblahblah';
$token='---------------------------------';
$client = new Services_Twilio($sid, $token, $version);
try {
$pollLimit=30;
$pollCounter=0;
do
{
foreach($client->account->calls as $call) {
break;
}
$finished=true;
if (in_array($call->status,$incompleteArray))
{
echo('.');
sleep(1);
$finished=false;
}
}while(!$finished || ($pollCounter++>$pollLimit));
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
echo(" call status: $call->status. ");
if (in_array($call->status,$problemArray))
{
echo("test: failed. \n");
}
else
{
echo("test: success. \n");
}

apache’s mod_security will add the POST variable to it’s log file when it detects a match and maybe you want that POST to be there for debugging, but maybe you’re in a PCI environment and it’s a no-no to store credit cards but the POST contains them. now what?

well, you could have mod_security write to a named pipe instead of the log file directly and then do the strippage. a-like-a-this:

[root@server logdirectory]# mkfifo /root/logdirectory/mod_security_filter.pipe
[root@server logdirectory]# nohup php filter_handler.php>/dev/null &
[root@server logdirectory]# echo "id 213123: credit card: 4111111111111111 nov 27 2012 " >mod_security_filter.pipe 
[root@server logdirectory]# echo "id 213124: credit card: 378282246310005 nov 27 2012 " >mod_security_filter.pipe 
[root@server logdirectory]# echo "id 213125: credit card: 5555555555554444 nov 27 2012 " >mod_security_filter.pipe 
[root@server logdirectory]# echo "id 213125: credit card: 6011000990139424 nov 27 2012 " >mod_security_filter.pipe 
[root@server logdirectory]# cat mod_security.log 
id 213123: credit card: CREDIT_CARD_REMOVED nov 27 2012
id 213124: credit card: CREDIT_CARD_REMOVED nov 27 2012
id 213125: credit card: CREDIT_CARD_REMOVED nov 27 2012
id 213125: credit card: CREDIT_CARD_REMOVED nov 27 2012
[root@server logdirectory]#

where filter_handler is:

[root@server logdirectory]# cat filter_handler.php 
 <?php
define('QUEUESERVER_FORK',false);
 
function process($line) {
global $outputfile;
$line=preg_replace('/(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})/', 'CREDIT_CARD_REMOVED',$line);
file_put_contents($outputfile, $line."\n", FILE_APPEND);
    return;
}
 
$queue = array();
 
//////// fork into a background process ////////
if(QUEUESERVER_FORK) {
    $pid = pcntl_fork();
    if($pid === -1) die('error: unable to fork.');
    else if($pid) exit(0);
 
    posix_setsid();
    sleep(1);
 
    ob_start();
}
 
$pipefile = '/root/logdirectory/mod_security_filter.pipe';
$outputfile = '/root/logdirectory/mod_security.log';
$pipe = fopen($pipefile,'r+');
if(!$pipe) die('unable to open the named pipe');
stream_set_blocking($pipe,false);
 
//////// process the queue ////////
while(1) {
    while($input = trim(fgets($pipe))) {
        stream_set_blocking($pipe,false);
        $queue[] = $input;
    }
 
    $job = current($queue);
    $jobkey = key($queue);
    if($job) {
        echo("\nprocessing new lines in pipe\n");
        process($job);
        next($queue);
        unset($job,$queue[$jobkey]);        
    } else {
        echo("\nno new lines - waiting...\n");
        stream_set_blocking($pipe,true);
    }
 
    if(QUEUESERVER_FORK) ob_clean();
}
 
?> 
[root@server logdirectory]#

thx: http://squirrelshaterobots.com/programming/php/building-a-queue-server-in-php-part-2-building-the-queue-structure/

What if you wanted to run an ftp server, but wanted to authenticate the users from some 3rd party API?

pure-ftp to the rescue! In the below setup, upon an ftp login request, pure-ftp sets some environment variables (username, password, etc) and then runs /usr/bin/ftp-auth-handler (see source and invocation below). That file determines if the user can be permitted ftp access or not.

That ftp-auth-handler creates a JSON-encoded packet of the username and password and then calls a 3rd party API web service. Note, in the example below, the FTP username is of the format subdomain:username so we know which subdomain the user is for. This was a requirement of the 3rd party API. Here is a login example:

user@server:~/$ ftp 192.168.1.2
Connected to 192.168.1.2.
220---------- Welcome to Pure-FTPd [privsep] [TLS] ----------
220-You are user number 1 of 50 allowed.
220-Local time is now 14:35. Server port: 21.
220-IPv6 connections are also welcome on this server.
220 You will be disconnected after 15 minutes of inactivity.
Name (192.168.1.2:user): subdomain:username
331 User subdomain:username OK. Password required
Password: password
230 OK. Current directory is /
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

You’ll note that the user was authenticated and then placed in a directory /, but that is really a chroot jail of /home/ftp/[subdomain]/[username] which was created if it didn’t exist

source of /usr/bin/ftp-auth-handler:

#!/usr/bin/php
<?php
list($subdomain,$username)=explode(':',getenv('AUTHD_ACCOUNT'));		
$password=getenv('AUTHD_PASSWORD');
define('FTP_BASE_DIR','/home/ftp');
define('FTP_USER','ftpuser');
define('FTP_UID','1010');
define('FTP_GROUP','ftpusers');
define('FTP_GID','1011');
$url = "http://{$subdomain}.thirdpartyftpserver.com/api/ftp/";
$authArray=array('type'=>'basic','username'=>$username,'password'=>$password);
$methodArray=array('name'=>'authenticateFtpUser');
$jsonArray=array('auth'=>$authArray,'id'=>15,'method'=>$methodArray);
$jsonStr=json_encode($jsonArray);
$ch = curl_init();
curl_setopt($ch,CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=UTF-8'));
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, $jsonStr);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
$result = curl_exec($ch);
curl_close($ch);
$resultArray=json_decode($result,TRUE);
if ($resultArray['result']=='TRUE')
{
	if (is_dir(FTP_BASE_DIR.'/'.$subdomain))
	{
		if (!is_dir(FTP_BASE_DIR.'/'.$subdomain.'/'.$username))
		{
			mkdir(FTP_BASE_DIR.'/'.$subdomain.'/'.$username);
			chown(FTP_BASE_DIR.'/'.$subdomain.'/'.$username, FTP_USER);
			chgrp(FTP_BASE_DIR.'/'.$subdomain.'/'.$username, FTP_GROUP);
		}
	}
	else
	{
		mkdir(FTP_BASE_DIR.'/'.$subdomain);
		chown(FTP_BASE_DIR.'/'.$subdomain, FTP_USER);
                chgrp(FTP_BASE_DIR.'/'.$subdomain, FTP_GROUP);
		mkdir(FTP_BASE_DIR.'/'.$subdomain.'/'.$username);
		chown(FTP_BASE_DIR.'/'.$subdomain.'/'.$username, FTP_USER);
                chgrp(FTP_BASE_DIR.'/'.$subdomain.'/'.$username, FTP_GROUP);
	}
        echo("auth_ok:1\n");
        echo("uid:".FTP_UID."\n");
        echo("gid:".FTP_GID."\n");
        echo("dir:/home/ftp/{$subdomain}/{$username}\n");
}
else
{
     	echo("auth_ok:0\n");
}	
echo("end\n");

I started pure-ftp service this way:

service pure-ftpd stop
pure-authd -s /var/run/ftpd.sock -r /usr/bin/ftp-auth-handler &
pure-ftpd -A -lextauth:/var/run/ftpd.sock &

the latest version of openSSH for Red Hat Enterprise Linux Server release 5.7 according to yum is openssh-4.3p2-82

but that doesn’t stop us:

cd /usr/local/src
wget http://mirror.esc7.net/pub/OpenBSD/OpenSSH/portable/openssh-6.1p1.tar.gz
tar -xvzf openssh-6.1p1.tar.gz
cp ./openssh-6.1p1/contrib/redhat/openssh.spec /usr/src/redhat/SPECS/
cp openssh-6.1p1.tar.gz /usr/src/redhat/SOURCES/
cd /usr/src/redhat/SPECS
perl -i.bak -pe 's/^(%define no_(gnome|x11)_askpass)\s+0$/$1 1/' openssh.spec
rpmbuild -bb openssh.spec
cd /usr/src/redhat/RPMS/i386
rpm -e openssh-askpass-4.3p2-82.el5.i386
rpm -Uvh openssh-*.rpm
 
[root@server ~]# ssh -v
OpenSSH_6.1p1, OpenSSL 0.9.8e-fips-rhel5 01 Jul 2008

from: http://www.thecpaneladmin.com/upgrading-openssh-on-centos-5/

Step 1: install ffmpeg per http://cumulusclips.org/docs/install-ffmpeg-x264-on-centos/ however, for the libvpx instructions do this (per https://ffmpeg.org/trac/ffmpeg/wiki/UbuntuCompilationGuideLucid):

cd
git clone --depth 1 http://git.chromium.org/webm/libvpx.git
cd libvpx
./configure
make && make install

Step 2: ffmpeg -i FILENAME.avi FILENAME.webm

« Previous PageNext Page »

Send to a friend * Print this page * Join the club * Talk with my robot * Advertise here * Search this Site * Donate * Link to me


Web hosting by Utah Hub *  Powered by CreativeTap *  In association with Segomo
Unless otherwise noted, Copyright 2004-2013, Ryan Byrd. All Rights Reserved.
Ryan Byrd dot net -- probably the coolest site in Utah