get_start(); $end = $interval->get_end(); } if( $_GET['id'] ) { $id = $_GET['id']; $row = db_fetch_object(db_query("SELECT `start`, `end` FROM {acidfree_cmml_clips} WHERE `nid`={$node->nid} AND id='$id';")); $start = $row->start; if( $row->end && $row->end != 0.0 ) { $end = $row->end; } } $anx = new AnnodexWriter(); $anx->import($media_file, NULL, NULL, $start, $end); output_annodex_headers( $anx ); foreach( make_clips($node) as $start=>$clip ) { $anx->insert_cmml( $start, $clip ); } while( $buffer = $anx->write_output() ) { echo $buffer; } $anx->close(); return; } /* Serve raw Ogg Theora */ function output_ogg( $node, $output_headers=TRUE ) { $media_file = realpath(_acidfree_get_large_path( $node, true )); if( $output_headers ) { header("Content-Type: application/ogg"); header(""); } readfile( $media_file ); } /* Serve cmml */ function output_cmml( $node, $output_headers=TRUE ) { $media_file = realpath(_acidfree_get_large_path( $node, true )); output_cmml_headers(); echo ''; echo ''; echo make_head( $node ); $clips = make_clips( $node ); foreach( $clips as $clip ) { echo $clip; } echo ''; return; } /* Make a cmml head element */ function make_head( $node ) { $head .= ""; $head .= ""; $head .= $node->title; $head .= ""; $head .= ""; return $head; } /* Create a cmml clip. */ /*FIXME add everything to clip, not just id and desc */ function make_clip( $id, $start, $description=NULL, $img=NULL ) { $clip .= "set_start( $start ); $clip .= " start=\"{$npt->toString(FALSE)}\""; } $clip .= ">"; if( $description ) { $clip .= "$description"; } if( $img ) { $clip .= ""; } $clip .= ""; return $clip; } /* Return an array of cmml clips from info in the database */ function make_clips( $node ) { $result = db_query("SELECT * FROM {acidfree_cmml_clips} WHERE nid={$node->nid} ORDER BY `start`;"); $clips = array(); while( $row = db_fetch_object($result) ) { $clip = make_clip( $row->id, $row->start, $row->desc, $row->img ); $clips[(string) $row->start] = $clip; } return $clips; } /* Output the appropriate headers for when cmml is being served. */ function output_cmml_headers() { header("Content-Type: text/x-cmml"); return; } /* Output the appropriate headers for when annodex is being served. */ function output_annodex_headers( AnnodexWriter $anx ) { header("Content-Type: application/x-annodex"); header("X-Content-Bitrate-Average: {$anx->get_bitrate()}"); header("X-Content_Duration: {$anx->get_duration()}"); return; } /* Examine the Accept field of the request and determine which of ogg, annodex * or cmml is prioritised. The default is annodex. */ function get_accept_type() { foreach( explode(",",$_SERVER['HTTP_ACCEPT']) as $mime) { $tuple = explode(";",$mime); if( trim($tuple[0])=="text/x-cmml" ) { /* Found cmml. */ if( count($tuple) == 2 ) { $cmml_priority = trim($type_tuple[1]); } else { $cmml_priority = 1; } } else if ( trim($tuple[0])=="application/x-annodex" ) { /* Found annodex. */ if( count($tuple) == 2 ) { $anx_priority = trim($tuple[1]); } else { $anx_priority = 1; } } else if ( trim($tuple[0])=="application/ogg" ) { /* Found ogg. */ if( count($tuple) == 2 ) { $ogg_priority = trim($tuple[1]); } else { $ogg_priority = 1; } } } if( $ogg_priority > $anx_priority && $ogg_priority > $cmml_priority ) { return "ogg"; } else if ( $cmml_priority > $anx_priority ) { return "cmml"; } else { /* If it's a draw, choose annodex */ return "annodex"; } }