embedMedia Version 1.0 - 2009.12.11
-=- ABOUT -=-
embedMedia is a php class for generating a standards compliant method of
embedding multimedia content in a web page that will work in the vast
The class uses DOMDocument and json_encode to generate the code and
therefore generates code suitable for either HTML or XHTML documents that
lends itself to further server side manipulation via DOMDocument tools
before inclusion in the actual web page. The downside to using DOMDocument
and json_encode is that you must have PHP 5.2.x or newer compiled against
You *might* be able to get away with php 5.0.x or 5.1.x if you have built
the json_encode PECL extension.
Three methods for embedding media are available from the class:
1) (X)HTML 5 Media with Flash (Flowplayer) as fallback
2) Flash (Flowplayer) with (X)HTML 5 Media as fallback
3) Windows Media with one of above as fallback
-=- DEPENDENCIES -=-
php 5.2.x or newer compiled against libxml2
Flowplayer 3.x (works with GPL or Commercial)
Flowplayer audio plugin
With the free GPL version of Flowplayer, the Flowplayer logo will appear
on video content when Flowplayer is used. Purchase a commercial license
to Flowplayer if you do not want this.
Flowplayer can be downloaded from
Audio plugin can be downloaded from
Unlike some plugins, the audio plugin does NOT require commercial license.
Flowplayer and the audio plugin are installed on your server. The end user
does not need to install anything as long as they have flash.
-=- Initiating Class and Usage -=-
$foo = new DOMDocument("1.0","UTF-8");
$foo->preserveWhiteSpace = false;
$foo->formatOutput = true;
$media = new embedMedia($foo,'mySong','/media/mysong.mp3','/media/mysong.ogg','/media/mysong.wma');
$media->public = 'whatever'; // where public is the public variable you are
// setting to whatever
$mObject = $media->auto();
To create an HTML fragment:
$string = preg_replace('/<\/source>/','',$foo->saveHTML());
The preg_replace is not absolutely necessary. The issue is that libxml2 does
not know about the (X)HTML 5 media source tag, that it never has child nodes
and thus (like meta) should not have a closing tag.
To create an XHTML fragment:
$string = preg_replace('/.+\n/','',$foo->saveXML(),1);
The preg_replace removed the
<?xml version="1.0" encoding="UTF-8"?>
that results from the DOMDocument->saveXML() function
Of course if you are already using DOMDocument to construct your web page,
you can just use your existing DOM object as the first argument and
append $mObject to your existing DOM and not have to worry about that.
-=- $media = new embedMedia($foo,'mySong','/media/mysong.mp3','/media/mysong.ogg','/media/mysong.wma');
The first argument to embedMedia is the handle for your DOMDocument object.
Required, must be a DOMDocument object.
The second argument is an identifier. Should not contain spaces. It is used
to create ID tags in the (X)HTML 5 media tag, the Flowplayer tag, and the
optional Windows Media tag. Required.
* The (X)HTML 5 media id attribute will be h5_ plus the id string.
* The Flowplayer media id attribute will be fp_ plus the id string.
* The windows media id attribute will be wmp_ plus the id string.
- Remember that in HTML/XML, id tag must be unique, so when embedding
multiple pieces of media on the same page, make sure the second argument
is always unique.
The third argument is the path to either MP4 or MP3 version of media.
Required. For video The MP4 version should be H.264/AVC. For audio
the MP3 version should be MPEG 1 Layer 3.
The fourth argument is the path to the ogg version of the media. Optional.
For video it should be Ogg Theora. For audio it should be Ogg Vorbis.
The fifth argument is the path to the windows media version. Optional.
-=- Public Variables -=-
public $width - integer, the width of the embedded media.
Defaults to 384
public $height - integer, the height of the embedded media.
Defaults to 24.
For (X)HTML 5 audio, the value is meaningless.
public $cbarheight - integer, the height of the control bar. Only
meaningful to Flowplayer. Defaults to 24.
public $autoplay - boolean, determines whether or not the media
starts playing on page load. Defaults to
public $autobuffer - boolean, determines whether or not the media
starts buffering on page load. Defaults to
false. Safari seems to ignore this with (X)HTML 5
media and uses QuickTime preferences instead.
public $controls - boolean, determines whether or not to show
control bar. Defaults to true.
public $type = - audio or video. Specifies whether the media
is audio content or video content.
public $poster = - URL, Specifies path to image to use as a
poster for media. If the type is audio, the
poster will be displayed in Flowplayer while
audio plays. Meaningless for (X)HTML 5 audio.
public $fullscreen - boolean, whether or not Flowplayer control
bar should have full screen button. Meaningless
to (X)HTML 5 media. Defaults to false.
// change these to your environment (extend class)
public $fplayer - URL, path in web root to Flowplayer. Defaults
public $faplayer - URL, path in web root to Flowplayer audio
plugin, defaults to
// leave if you don't have commercial
public $fpkey - string, if you have the commercial version
of Flowplayer, used to specify your license
// path for download wrapper
public $dnlWrap - URL, see section on 'Download Wrapper'
// trigger windows media
public $wmpClassID - string, the classid for Windows Media Player.
See section on Windows Media Player. Defaults
// style sheet hook
public $h5class - string, CSS class to use with (X)HTML 5 media.
Defaults to empty.
public $fpclass - string, CSS class to use with Flowplayer.
Defaults to empty.
public $wmclass - string, CSS class to use with Windows Media
Player. Defaults to empty.
public $fbclass - string, CSS class to use with plain text
fallback if the browser does not support any
of the embedded media options. Defaults to empty.
As you can see, there are a lot of public variables. You will probably want to
define a custom class that extends this class to suit your needs and predefines
the public variables. For an example of how to do this, see the extend.embedMedia.inc
file included with this distribution.
-=- Public Functions -=-
public function embedMedia($dom,$id,$mpg,$ogg="",$wma="")
After using the constructor function when initiating the object, use one of the
following functions to generate your code fragment as a DOMDocument object:
public function (X)HTML 5()
Generates HTML 5 media tags with flash (Flowplayer) as fallback.
public function flow()
Generates flash (Flowplayer) object tags with (X)HTML 5 media as fallback.
public function auto()
If ogg version of file is given, returns same as (X)HTML 5()
Otherwise, returns same as flow()
public function windowsMedia()
I recommend against using this function unless you really must.
Generates object code for Windows Media, uses auto() to
generate fallback to Windows Media.
-=- Download Wrapper -=-
For direct download of media, including hyperlinks used as fallback in this
class, I prefer not to link directly to media. Some browsers will not start
a download but either try to play the file in a browser window or show binary
On my server, I create a directory where a download wrapper lives. In that directory
is a single php script and a .htaccess file that uses mod_rewrite to link all requests
to media files to the php script. The php script figures out what media is requested
by the filename that calls it, and then serves the file with the necessary headers to
instruct the browser to treat it as a download and not try to handle it directly.
If you use a similar system, you can specify the directory used for the download
wrapper with the $dnlWrap public variable. It should be set to full path and if a
directory like what I use, it should contain the trailing /, IE
$media->dnlWrap = '/media/dnl/'
Another option that does not use mod_rewrite is to use a php script with a GET variable
to let the script know what file to serve. In that case, $dnlWrap should be set to the
URL of the script plus the get variable name and the =, IE
$media->dnlWrap = '/media/wrapper.php?file='
If you do not use any kind of download wrapper, just don't set the variable.
-=- Mime Types -=-
Some HTML 5 media browsers seem to be sensitive of Ogg mime types, and some server
installs do not send mime types that make them happy. Put the following in a .htaccess
file in the directory that serves ogg files to make sure it works properly.
AddType application/ogg .ogx
AddType audio/ogg .ogg
AddType video/ogg .ogv
-=- Flowplayer Notes -=-
Flowplayer code is done using the "Pure OBJECT tag" method detailed at
Flowplayer is updated with some frequency. I suggest you check their web site regularly
for updates. The updates primarily fix issues that crop up with Internet Explorer from
time to time, but since IE is the only major browser that does not at least have (X)HTML
5 media support in development versions, you want to make sure the version of Flowplayer
you have is up to date, especially after MS releases an IE update.
By extending the class, when you do update Flowplayer you can just update the extended
class and do not need to update the class distributed here.
If you use the commercial version of Flowplayer, see the extend.embedMedia.inc file for
example of how to reference the commercial player and specify your license key.
Note that for Flowplayer to play H.264/AVC media, the browser needs to have flash 9.115
or newer installed. That usually is not a problem.
-=- HTML 5 Media Notes -=-
Unfortunately, there is no defined standard media type for HTML 5 media. If you include
both MP3 and ogg versions of audio, any (X)HTML 5 media browser should handle it. If you
only include MP3, then some browsers (IE FireFox) will not handle it, and unfortunately
will not use the fallback either.
If you include both H.264/AVC (MP4) and Ogg Theora versions of video, any (X)HTML 5
media browser should handle it. If you only include the MP4, then some browsers (IE
Firefox) will not handle it, and unfortunately will not use the fallback either.
For this reason, if you do not have Ogg versions of the media, it is suggested that you
use the flow() function instead of html() function.
You can also use auto() function, and it will use flow() by default if an ogg file is
not specified, html() if one is.
-=- H.264 Streaming Notes -=-
Most video encoders that produce H.264/AVC content do not properly set up the media for
streaming. Additionally, many H.264/AVC meta data taggers break them for streaming.
The result is poor user experience, streaming media players will not begin to play the
file until it has been completely downloaded.
The solution comes from ffmpeg, which has a program called qt-faststart in its contrib
directory. Most distributions of ffmpeg should have that compiled for you. To use it:
cp yourfile.MP4 tmp.MP4
qt-faststart tmp.MP4 yourfile.MP4
Now yourfile.MP4 is properly set up for streaming, allowing playback to start before the
media player has finished buffering the file.
-=- Windows Media Notes -=-
I only wrote the windowsMedia() function because I know of cases where the boss tells the
web developer that Windows Media is to be used as the default media player, period. My
suspicion is that this is to deal with corporate environments where IE on Windows is
always the browser and Flash is removed from the computers for security and/or productivity
If you have such a mandate, use the windowsMedia() function. It will generate code that
should trigger Windows Media Player if available, and it uses auto() to generate fallback
code for non IE browsers. I have not actually tested how well it works, I do not run
Windows, but the generated code looks to me like it "should" do what I intended.
Unfortunately, some non IE browsers (IE Opera on Linux) will try to handle the media and
fail, but also not use a fall back, so I really suggest against using that function unless
your job depends upon it.
Please note that not all versions of Windows Media Player support MP3 or H.264 playback
out of the box. If you use this function, it is best to specify a Windows Media version of
the file when you initialize the class.
-=- Class In Action -=-
Web pages that use this class to embed multimedia:
http://www.shastaherps.org/herps/AmericanBullfrog (audio and video)
-=- Donations -=-
Donations are much appreciated but not required. You can PayPal them to firstname.lastname@example.org
Thank you for checking out my class,
Michael A. Peters