Ogg.class.php v1.3g

http://opensource.grisambre.net/ogg

[Examples] [Class Reference] [Download] [History] [Links]


Ogg.class.php is a PHP class for PHP>= 4 designed to offer on the server-side a few basic fonctionnalities (currenly: only for Vorbis Audio and Theora Video streams encapsulated inside the Ogg container):
Altogether, for an example, with Itheora, it allows to broadcast easily audio or video on your web site.
Ogg.class.php is free and "open source", and is licensed under the GNU GPL 3 - copyleft Nicolas Ricquemaque 2008 [contact: opensource (arobase) grisambre dot net].

Quick examples

A few quick examples is the best way to show how it works ! However, only minimal error detection is made here. For a more comprehensive example, just have a look into the demo.php included with the library archive.

Example(1): Reading information from an OGG file

Code:

<?php require_once("ogg.class.php"); $video=new Ogg ("myfile.ogv"); if ($video->LastError) { echo $video->LastError; exit; } print_r($video->Streams); ?>

Result: (values from header - Computed value - For internal use)

Array
(
[oggfile] => myfile.ogv
[cachefile] => myfile.ogv.cache
[size] => 1250920
[source] => file
[picturable] => 1
[encoding] => ansi
[summary] =>  myfile.ogv (1221 kB)
Video (theora): 16s 320x240 29.97fps Q=32
ENCODER=ffmpeg2theora 0.20

Audio (Vorbis 30kb/s): 16s mono 22kB/s
ENCODER=ffmpeg2theora 0.20


[theora] => Array ( [serial] => 19370 [vmaj] => 3 [vmin] => 2 [vrev] => 1 [fmbw] => 20 [fmbh] => 15 [picw] => 320 [pich] => 240 [picx] =>0 [picy] => 0 [width] => 320 [height] => 240 [frn] => 30000 [frd] => 1001 [frate] => 29.97 [parn] => 1 [pard] => 1 [cs] => 1 [nombr] => 0 [qual] => 32 [kfgshift] => 6 [pf] => 0 [vendor] => Xiph.Org libTheora I 20071025 3 2 1 [comments] => Array ( [0] => ENCODER=ffmpeg2theora 0.20 ) [commentlen] => 99 [commentpos] => 128 [commentnext] => 2879 [commentleftSegments] => ÿÿÿÿÿÿÿÿÿÿ? [framecount] => 584 [duration] => 16 )

[vorbis] => Array ( [serial] => 141 [channels] => 1 [samplerate] => 22050 [maxbitrate] => 0 [nombitrate] => 30444 [minbitrate] => 0 [bitrate]=> 30444 [vendor] => AO; aoTuV b5 [20061024] (based on Xiph.Org's libVorbis) [comments] => Array ( [0] => ENCODER=ffmpeg2theora 0.20 ) [commentlen] => 120 [commentpos] => 2879 [commentnext] => 6297 [commentleftSegments] => ÿÿÿÿÿÿÿÿÿÿÿÿÅ [duration] => 16

[duration] => 16
)

Example(2): Adding a comment to the same Ogg file to both vorbis and theora streams if they exist

Code:

<?php require_once("ogg.class.php"); $video=new Ogg ("myfile.ogv"); if ($video->LastError) { echo $video->LastError; exit; } // Does this file have a vorbis stream ? if (isset($video->Streams['vorbis'])) $video->Streams['vorbis']['comments'][]="ARTIST=Nicolas"; // Does this file have a theora stream ? if (isset($video->Streams['theora'])) $video->Streams['vorbis']['comments'][]="ARTIST=Nicolas"; $video->WriteNewComments(); print_r($video->Streams); ?>

Result: (values from header - Computed value - For internal use)

Array
(
[oggfile] => myfile.ogv
[cachefile] => myfile.ogv.cache
[size] => 1250920
[source] => file
[picturable] => 1
[encoding] => ansi
[summary] =>  myfile.ogv (1221 kB)
Video (theora): 16s 320x240 29.97fps Q=32
ENCODER=ffmpeg2theora 0.20

Audio (Vorbis 30kb/s): 16s mono 22kB/s
ENCODER=ffmpeg2theora 0.20


[theora] => Array ( [serial] => 19370 [vmaj] => 3 [vmin] => 2 [vrev] => 1 [fmbw] => 20 [fmbh] => 15 [picw] => 320 [pich] => 240 [picx] =>0 [picy] => 0 [width] => 320 [height] => 240 [frn] => 30000 [frd] => 1001 [frate] => 29.97 [parn] => 1 [pard] => 1 [cs] => 1 [nombr] => 0 [qual] => 32 [kfgshift] => 6 [pf] => 0 [vendor] => Xiph.Org libTheora I 20071025 3 2 1 [Ogg.class.php v1] [comments] => Array ( [0] => ENCODER=ffmpeg2theora 0.20 [1] => ARTIST=Nicolas ) [commentlen] => 99 [commentpos] => 128 [commentnext] => 2879 [commentleftSegments] => ÿÿÿÿÿÿÿÿÿÿ? [framecount] => 584 [duration] => 16 )

[vorbis] => Array ( [serial] => 141 [channels] => 1 [samplerate] => 22050 [maxbitrate] => 0 [nombitrate] => 30444 [minbitrate] => 0 [bitrate]=> 30444 [vendor] => AO; aoTuV b5 [20061024] (based on Xiph.Org's libVorbis) [Ogg.class.php v1] [comments] => Array ( [0] => ENCODER=ffmpeg2theora 0.20 [1] => ARTIST=Nicolas ) [commentlen] => 120 [commentpos] => 2879 [commentnext] => 6297 [commentleftSegments] => ÿÿÿÿÿÿÿÿÿÿÿÿÅ [duration] => 16 )

[duration] => 16
)

Class reference

Constructor: object Ogg (string $file[, integer $options=ANSI+CACHING [, string $cachedir="/cache.ogg"]])
UTF8 or ANSI, defines the strings encoding of the extracted ogg information (for instance: comments, vendor, summary). Please note that this does NOT affect the way new comments will eventualy be written to the file later, which will automaticaly be converted (if necessary) to UTF8 by format standard.

CACHING or NOCACHING allows or disables caching the information of the file. Enabling will improve dramaticaly performances. Basicaly, the first time the constructor is parsing a file "/IMG/ogg/myfile.ogv", it will create a file "/$cachedir/myfile.ogv.cache", that can be reused the next time. When a file is parsed, about 128kb of the file (64kb at the begnning and 64kb at the end) must be analysed to extract information.

UPDATECACHE (only if CACHING is enabled) is forcing the cache file to be overwritten (if existing) with up-to-date information fresh from the file. Warning: any previously user added information using the CacheUpdate() function will be lost.

NOVENDORTAG disables the automatic tagging of the vendor field with the version of this class, for reference or future debugging.

After the creation of the Ogg object or after any call of a public method of this class, it is strongly advised to check the public variable LastError. If LastError is false everything is fine; else, LastError will contain a string describing the problem.

If no problem occured, the public variable Streams will be an array with all king of information the library was able to retrieve, as shown in the previous example. The subarrays ['theora'] and ['vorbis'] will only be set if such stream was detected in the ogg file; therefore, checking for their presence will allow the user to see if the file is audio/video or only audio or only video.



Public method: integer WriteNewComments ([integer $refresh=5])
$refresh is an optional value in seconds after which the function will return (even if the writting is not complete). The interest of not writting the file is dual; in fact, the writting can take verrrrryyyyyy long, is the file is BIG. It is common to see video files with a size over 100++ MB. Unfortunately, it is not possibe with Ogg files just to "change" the comments in the middle of the file wihtin one shot : the whole file must be rewritten every time, taking a variable time. So splitting it in several calls in as many sessions will allow: So calling this function Will begin to re-write the file with the comments you would have previously updated in the public array "Streams" described below.

Return value: false if a problem occured (then check the LastError string to understand what went wrong) or the position in the file where the fonction ended. If the this value equals Streams['size'], then the file is complete (and the cache has been updated). Else, the calling script will have to call the other function "ContinueWrite()" (see below) in another session to continue the writting...



Public method: integer ContinueWrite ()
As explain before, this conction must be called as many times as necessary to complete the writting of the file started with the function "WriteNewComments()" previously described.

Return value: false if a problem occured (then check the LastError string to understand what went wrong) or the position in the file where the fonction ended. If the this value equals Streams['size'], then the file is complete (and the cache has been updated). Else, the calling script will have to call the same function again in another session to continue the writting...



Public method: string GetPicture ([int $framepos=1, [string $where=false]])
This functions extracts a jpeg picture from the frame '$framepos' of the video. if $framepos is omitted, the first frame of the video is extracted. The second parameter allows to specify where the picture will be stored; if omitted, this will store the picture in the cache folder with a name like 'myvideo.ogv.f1.jpg' (f1 designating the frame number). For future use, each extracted picture will be shown in the Streams[theora][pictures] array (see below). Before calling this function, user should check if the variable Streams[picturable] is true.

Return value: false if a problem occured (then check the LastError string to understand what went wrong) or the picture location.



Public method: bool CacheUpdate ()
It may be useful for the user to add his own fields to the Streams array and save it in cache for future use. This function simply allows to update the cache file with whatever the user added/modified in the Streams array.
Warning ! If you change existing values, it will not really update the Ogg file, just the information displayed. Furthermore, Changing existing values like [commentlen] and [commentpos] could permanently damage the Ogg file if trying later to rewrite the comment tags !

Return value: false if a problem occured (then check the LastError string to understand what went wrong) or true and the cache file is updated.



Public variable: bool/string LastError
Contains either false if no error recently occured, or a string explaining the error in full text and in english.



Public variable: array Streams
This is the location where the class is storing whatever information it was able to get from the ogg file. While some parameters may be very useful from the calling application or the user, some are very technical and will most likely not be used. Anyway, all the information is here, and the variables have the same name as in the xiph.org documentation, and the same meaning. The most important variables will be described below, but don't hesitate to make a "print_r($this_array);" call to php to get an exhaustive list. However, some parameters will only appear in the array if they have a meaning for this file. For an example, you won't find vorbis related information if this is a pure video file !

Download

Contents : Actual version (1.3g): ogg.class.zip


History

v1.0 (August 2007)
First release, based mostly on the File_OGG pear package
http://pear.php.net/package/File_Ogg by David Grant. Added basic Theora support and caching, but kept same structure. This file was included with Itheora v0.9 and later.
v1.1
Still based on the File_Ogg pear library, but with big structural changes and improved theora support.
v1.2
Intermediate version, to rewrite entirely the class, with first comment tags rewrite function, first ability to calculate Theora stream duration. This version was never published.
v1.3 (May 2008)
Complete rewritting of the class for performance improvement; now, only 64kb at the beggining and 64kB at the end is sufficient to get all the data. Added support to analyse remote http files (if server supports it). Separation from the Itheora project (which is still using it), new own website and first official documentation.
v1.3e (June 2008)
Added picture extraction if php modules ffmpeg and gd2 are available.
Added CacheUpdate() fonction for user to add his own data to the Streams array and save it inside cache.
Added basic Ogg Skeleton and CMML MetaData handling capability
v1.3f (September 2008)
Corrected a bug for picture size not always accurate.
Corrected a bug for calculating duration with files written as streaming (with VLC, for an example)
Corrected a bug with the picture extraction when caching is disabled or cache was lost and picture is already existing
Added the option UPDATECACHE to force analysing the file again and rewrite the cache file.
Note: If you use also the cortado java applet, you better use the wikimedia forked version, with cmml-skeleton support and less bugs, as it looks like fluemotion has given up since 2006 on developping and updating their applet. See links below.
v1.3g (November 2008)
Corrected a bug in cache handling

Links