Streaming With PHP

How to stream audio and video from PHP files.

4049 views
d

By. Jacob

Edited: 2020-01-23 02:02

streaming, php

You can stream video from PHP by outputting a files content in chunks. In addition, it is a good idea to support the HTTP range request header in your PHP script. Doing this on your own requires knowledge of the HTTP protocol, and how to work with the file system from PHP.

The range header is not only useful for video files, it can also be used when streaming audio, and indeed, just about any file type. It basically enables a client to request only specific parts of a resource, which is useful when you want to support pausing and resuming downloads.

Another benefit from supporting the range header in your application is that you can easily place files behind a HTML form based login. Ideally, you would just redirect all HTTP requests to your PHP application, and then either prevent or allow access depending on whether a user is logged in.

See also: Redirect Everything to Index.php With Mod_rewrite

If you are using the Beamtic File Handler library, you could stream a file by doing this:

define('BASE_PATH', rtrim(preg_replace('#[/\\\\]{1}#', '/', realpath(dirname(__FILE__))), '/') . '/');

require BASE_PATH . 'lib/php_helpers/php_helpers.php';
require BASE_PATH . 'lib/php_helpers/superglobals.php';
require BASE_PATH . 'lib/file_handler/file_types.php';
require BASE_PATH . 'lib/file_handler/file_handler.php';
    
require BASE_PATH . 'lib/file_handler/file_handler_factory.php';
    
$file_handler = (new doorkeeper\lib\file_handler\file_handler_factory())->build();
    
$file_path = BASE_PATH . 'my-video-file.mp4';
    
$file_handler->http_stream_file(array('path' => $file_path));

An easier way to include Beamtic's File handler would be to use an outoloader:

define('BASE_PATH', rtrim(preg_replace('#[/\\\\]{1}#', '/', realpath(dirname(__FILE__))), '/') . '/');

// --------------------------
// -Include the autoloader--
// ---------------------------
require BASE_PATH . 'shared/Psr4AutoloaderClass.php';
$loader = new phpfig\Psr4AutoloaderClass;
// Add the path for the doorkeeper namespace (location of all doorkeeper classes)
$loader->addNamespace('doorkeeper\lib', BASE_PATH . 'lib');
$loader->register(); // Registers the autoloader

// -------------------------
// -Start the File Handler--
// -------------------------
$file_handler = (new doorkeeper\lib\file_handler\file_handler_factory())->build();
$file_handler->http_stream_file(array('path' => BASE_PATH . 'my-video-file.mp4'));

See how we got rid of a bunch of require statements (includes)? This is why using an autoloader is recommended.

Note. You could probably also add Doorkeeper as a private repository in composer, but that is beyond this Tutorial.

Installing the File Handler is a simple matter of downloading it, and adjusting the paths so to correspond with your own file system hierarchy.

Benefits to using the File Handler

The first benefit to using the File Handler is that caching is handled automatically. Typically, large video files are not cached by browsers, but this is still useful for other file types, such as images and HTML and CSS files.

Using the bare file functions in PHP is also not recommended, since it can lead to loss of data if you have concurrent users accessing the same file. File handling can be complex!

I am specifically trying to solve this problem with the file handler by implementing file locking before doing read and write actions on files.

File locks for reading should be shared, meaning that users are allowed to read from a file at the same time, while blocking write actions. Writing to a file should trigger an exclusive lock, preventing both reads and writes until the lock is released.

Streaming Video from PHP

Why stream video from PHP when it is more efficient to let your Web Server serve up the files directly? Well, the first reason that comes to mind is the flexibility it gives you.

If you want to protect files behind a HTML based login form, one way to do this is to redirect all requests to a PHP file, typically your index.php.

Finally, the performance hit from using PHP is actually not that big. Most sites do not handle many concurrent users, and it is therefor not the first of your concerns.

What do you need

While you could use the HTML5 video element, this is not required. You could just link directly to the PHP script that delivers the file.

All multimedia files are basically supported, as long as you deliver them with the correct mime type. It only depends on browser support. Generally, wav, mp3, and ogg should work for audio, while mp4 is a common choice for video. Other formats might work as well, and support for different codecs is likely to improve with time.

If your video does not work, you can convert it to mp4 with a free, open source, tool such as Handbrake. There is absolutely no need to buy expensive editing software.

Most browsers will automatically show standard controls on multimedia files, both for audio and video files.

If you want to give your users a more unique experience, then you could design your own media player using JavaScript and HTML5. It is very easy to make your own controls, such as start, stop and even a location indicator.

You no longer need any complex JavaScript or Flash as everything is handled by the browser automatically. The only things you need to focus on is on the server-side. Basically supporting the range request header. Apache automatically does it for static files, but for PHP, you will have to do this yourself.

Links

  1. Beamtic's File Handler - github.com

Tell us what you think:

YOSYP

Hi! Thanks for the library, i install it but when i try to use it, theres a lot of errors in the code which cant let run my code... does this library have been tested? probably it, so, what i must to change to run it? there are errors like this (first): Argument 2 passed to doorkeeper\lib\file_handler\file_handler::__construct() must be an instance of doorkeeper\lib\php_helpers\php_helpers in doorkeeper\lib\file_handler\file_handler_factory.php on line 38

Jacob

> ...theres a lot of errors in the code...

Hey YOSYP, those errors tell you that you must first instantiate "php_helpers" and provide it to the "file_handler" when instantiating that.

My local code base has changed a lot. I am not even sure I use the file_handler factory class anymore. But, I will update the GitHub repository asap.

Keep in mind, the code is actually running here on beamtic.com, so I am sure that it works. If you know enough about errors, and what they mean, then it is easy to solve those dependency issues.

The code should work with PHP 7+

  1. In this Tutorial, it is shown how to redirect all HTTP requests to a index.php file using htaccess or Apache configuration files.
  2. How to create a router in PHP to handle different request types, paths, and request parameters.
  3. Tutorial on how to use proxy servers with cURL and PHP
  4. When using file_get_contents to perform HTTP requests, the server response headers is stored in a reserved variable after each successful request; we can iterate over this when we need to access individual response headers.
  5. How to effectively use variables within strings to insert bits of data where needed.

More in: PHP Tutorials