<?php

// Code to extract programme details from a .rec file
// Nigel Whitfield, 2006

foreach ( $_SERVER['argv'] as $filename ) {

if (( $filename == $_SERVER['PHP_SELF'] ) || ( ! file_exists($filename))) { continue ; }

$filesize = filesize($filename) ;

printf( "Reading header from %s, file size is %s\n", $filename, $filesize ) ;

// now open the file and read the header

$recFile = fopen($filename, 'rb') ;

$tfTag = fread($recFile, 4) ;

if ( $tfTag == 'TFrc' ) {
print "Looks like a Topfield file...\n" ;
} else {
die_gracefully("Not a Topfield .rec file") ;
}

$tfVersion = unpack('n',fread($recFile, 2));
printf("File version is %04X\n", $tfVersion[1]) ;

fseek($recFile, 2, SEEK_CUR) ;

$minutes = unpack('n',fread($recFile, 2)) ;

printf("Duration of recording is %d minutes\n", $minutes[1] ) ;

$channel = unpack('n',fread($recFile, 2)) ;
$serviceType = unpack('n',fread($recFile, 2)) ;
if ( $serviceType[1] == 0 ) { $sType = 'tv' ; } else { $sType = 'radio' ; }

printf("Recording type is %s, made from Topfield channel %d\n", $sType, $channel[1] );

// now, seek to the start of the service info, 14 bytes in

fseek($recFile, 14, SEEK_SET) ;

// skip over 32 bits of reserved space and tuner info

fseek($recFile, 4, SEEK_CUR) ;

// now we're at the start of the Service Info

$serviceId = unpack('n',fread($recFile, 2)) ;
$pmtPID = unpack('n',fread($recFile, 2)) ;
$pcrPID = unpack('n',fread($recFile, 2)) ;
$videoPID = unpack('n',fread($recFile, 2)) ;
$audioPID = unpack('n',fread($recFile, 2)) ;

$serviceName = preg_replace('/\0.*/','',fread($recFile, 24)) ;

printf("Item originated on %s, service id: %d, video pid: %d, audio pid: %d\n",
$serviceName, $serviceId[1], $videoPID[1], $audioPID[1] ) ;

// skip over TP info, to start of the EVT_INFO, 70 bytes in

fseek($recFile, 70, SEEK_SET ) ;

print "Reading event information from file...\n" ;

// skip 32 bits of 'Reserved' information

fseek($recFile, 4, SEEK_CUR ) ;

$evtDurH = unpack('c',fread($recFile, 1)) ;
$evtDurM = unpack('c',fread($recFile, 1)) ;
$evtID = unpack('N',fread($recFile,4)) ;
$evtBegin = unpack('n',fread($recFile, 2)) ;
$evtBh = unpack('c',fread($recFile, 1)) ;
$evtBm = unpack('c',fread($recFile, 1)) ;
$evtEnd = unpack('n',fread($recFile, 2)) ;
$evtEh = unpack('c',fread($recFile, 1)) ;
$evtEm = unpack('c',fread($recFile, 1)) ;

// skip 8 reserved bits

fseek($recFile, 1, SEEK_CUR ) ;

$nameLength = unpack('c',fread($recFile,1)) ;
$rating = unpack('c',fread($recFile,1)) ;

$eventName = fread($recFile, $nameLength[1] ) ;
$eventDesc = fread($recFile, 257 - $nameLength[1] ) ;

// truncate description at the null byte, and convert the date

$eventDesc = preg_replace('/\0.*/','',$eventDesc) ;


$recordedOn = mjdConvert($evtBegin[1]) ;

printf("%s (%d minutes), event id %d\n%s\n", $eventName, $evtDurH[1]*60 + $evtDurM[1], $evtID[1], $eventDesc ) ;
printf("Recorded on %02d/%02d/%d\n", $recordedOn[0], $recordedOn[1], $recordedOn[2]) ;
printf("Start time %02d:%02d, end time %02d:%02d\n", $evtBh[1], $evtBm[1], $evtEh[1], $evtEm[1] ) ;

// skip to start of EVT__EXT_INFO bytes in

fseek($recFile, 366, SEEK_SET ) ;

$extLength = unpack('n',fread($recFile, 2)) ;
$extId = unpack('N',fread($recFile,4)) ;

if ( $extLength[1] > 0 ) {
$eventDetails = fread($recFile, $extLength[1] ) ;
printf("\n%s\n", $eventDetails ) ;
} else {
print "No extended information.\n" ;
}

// the bookmarks are found at offset 1038
// fseek($recFile, 1034, SEEK_SET ) ;

// we're not interested in bookmarks here, so we're done

fclose($recFile) ;
}

print "End of processing\n" ;

exit ;

function die_gracefully($reason) {

printf ("*** Unable to continue: %s\n", $reason) ;
exit ;

}

function mjdConvert($mjd) {
// quick and dirty hack to convert MJD info back to a normal month

$jan2kMJD = 51544 ;
$jan2k = mktime(12,00,00,0,1,2000) ;

$offsetDays = $mjd - $jan2kMJD ;
$RecordDate = localtime($jan2k + $offsetDays * 60 * 60 * 24 ) ;
return ( array($RecordDate[3], $RecordDate[4]+2, $RecordDate[5]+1900)) ;

}
?>