flash video on web pages and PHP

    This article is a reprint of the article dated November 16, 2007 from my blog, the link to which can be found in my own profile - but since it just so happened that this topic seems to be still interesting to many, besides not so long ago I read a report on this topic at the PHPConf conference ... in general - judge for yourself.

    Introduction


    Recently, the technology of broadcasting video via the web has become increasingly widespread - without the need to download media content to the user's machine, with viewing directly from the browser. Thus, you can view a fairly large number of different video formats, however, this requires the presence of certain plug-ins on the user side. Obviously, the most common plug-in of this kind is flash-player (well, good: to be precise, of course, it cannot play video by itself - but it makes it easy to create an application that can play video content). A striking example of this approach is youtube.com. I’ll try to talk about how to independently organize flash video broadcasts on my web page and what approaches exist to this problem.


    It should be noted that the article does not pretend to be at least somehow innovative and is a pure compilation from sources available in open form. I hope, however, that this compilation will provide many with the necessary minimum knowledge about the subject of the report, which will lay the foundation for their own development and research.

    1. About FLV format


    So, flash-player plays video in FLV format, does not understand other formats.
    More information about the format itself can be found, for example, here: en.wikipedia.org/wiki/FLV , as well as, of course, on the website of Adobe, the manufacturer of flash-player . In the framework of this report, we will not need detailed knowledge of the format, but those that are needed are listed below.
    The FLV file consists of the title and the movie itself.
    The title contains certain meta-information about the film: duration, size, etc., etc. In fact, you and I will be interested in this meta-information only one circumstance - namely, that it contains data on key movie frames (their position on the time and byte scales). The meta-information itself is an arbitrary nesting associative array serialized in the AMF format, which is one of the accepted standards when developing flash applications.
    Note : for PHP, there are several libraries that allow you to (de) serialize to / from AMF.

    2. How to organize the translation of FLV files on web pages


    To consider the broadcast successful, two conditions must be met: the server successfully displayed the content, and the client watched it no less successfully. Accordingly, two parts of the application are needed - the server and the client. The client is a flash application that can play a video stream from a specified URL. There are many similar programs, and we will not dwell on them here in detail. Let's talk about the server side. So, what are the possible implementation paths?

    2.1. Download - Download


    This is the easiest way. It requires a simple client that simply requests a video stream at a given URL and plays it. The server only needs to process the HTTP request and display the corresponding content. No specific software is needed.
    “Then why any other way?” - Such a question is difficult not to ask. However, not everything is so smooth with this method ... The fact is that if it is great for showing small video fragments up to 2-3 minutes long, then it’s better not to show movies like that: in order for the user to watch any piece of the film, it is necessary that this piece has already been downloaded to his computer. In other words, being at the beginning of the film, we cannot move the timer “slider” to the end and watch the final credits. This method also does not provide any opportunities to protect video content from downloading.

    2.2. Streaming - Streaming Video


    This method is perhaps the most advanced. There is the possibility of rewinding to an arbitrary place in the stream, certain mechanisms for protecting content (frankly, these mechanisms only make it difficult to obtain content, being, in essence, protection only from an inept cracker). Another useful feature is the organization of live video broadcasts. If you need live broadcasts - you need to stream, you have no other choice.
    Well, the same question arises as with the previous method: “if streaming is so good, then what are some other other ways?”. Streaming is good, but not everyone can afford it. For a media server (for example, "Flash Media Server") will have to pay a tidy sum. However, there are open source solutions, for example, ffserver(which, however, does not quite fit the topic of the report, since it cannot stream files), as well as Red5 , which is written in Java and therefore also not suitable for everyone.

    2.3. HTTP streaming (emulating streaming video over HTTP)


    From the name one can guess that the third method is a combination of the first two. In some approximation, we can assume that this is so. As we have already noted, the biggest drawback of the 1st method (download) is the inability to rewind to any place in the movie. In HTTP-streaming, this problem is solved as follows: when rewinding to a place that has not yet been downloaded to the user's machine, the current download stops and a new request is sent to the server containing a pointer to where to download from the movie. There are certain subtleties here, which we will discuss in more detail in the next chapter. As for the advantages and disadvantages of this approach ... In my opinion, for broadcasting files - this is the best option. It is simple enough to implement it in any language (scripted, like PHP or Ruby - or compiled like C), so you can decide what to use based on the requirements for development speed, speed of the resulting application, existing software and other, other. Also for common fast web servers likeNginx and Lighttpd have ready-made modules for translating FLV files written in C and working very smartly.
    On this method, I will dwell a little more ...

    3.Http-streaming


    So, let's take a closer look at the option of broadcasting flash video using Http-streaming. As we have already said, in order to play the movie from an arbitrary place, the client sends an HTTP request to the server containing the "coordinate" of the place from which the video stream should be output. well, for example: localhost / flv / film.php? start = XXXXX . What is this coordinate? This is just the byte number from which the desired frame begins. By the way, you should always start playing an FLV file with a key frame.
    “However, allow me! How does the client know this byte number from which the frame begins? Yes, and certainly the key? ”
    I answer. Remember, at the beginning, when I briefly talked about what the FLV file consists of, I mentioned the meta information contained in the header? This meta-information contains data on the key frames of the film (their position on the time and byte scales). Thus, the client can always find the closest key frame to the position in the stream that the user requested - and translate it into bytes, which are sent to the server.
    But what about the server? Well, actually, his task is now minimal: process the request, read the value of the parameter (in our case it is the variable $ _GET ['start']), and issue the required video file, starting with the requested byte. This is almost the case. Almost, but not quite. The FLV file must contain a header. If the byte requested by the user is not null, then before issuing the contents of the file, starting with this byte, you need to insert the minimum possible header (to be honest, I did not understand in detail what it is, but I guess that it is an empty array or object, serialized in AMF and preceded by the characters “FLV”).

    3.1. Ready-made solutions: lighttpd , nginx + http_flv_module , flv4php .


    Http-streaming support is implemented in the popular lighttpd and nginx web servers . In the case of using these solutions, you just need to put the FLV files in a place accessible to the web server, everything else is up to the server and the client, you won’t have to write any code for the server side. The client will have to request the FLV files by adding the “start” GET parameter to the URL, for example, local-nginx / sample.flv? Start = 12345 .
    There is also a free solution (maybe there are more) based on PHP - flv4php. Its big plus is that in this project there is a ready-made player - a client for HTTP-streaming. The downside is that this solution is rather heavyweight, and, according to my tests on my working machine, it loads the processor heavily (a strange phenomenon, which we did not find an adequate explanation for, however, we hastened to refuse to use the server side of flv4php and we limited ourselves to borrowing a player from them, which, after modification to our needs, began to serve us faithfully). Another drawback is that the first frame of the film is used as the “pedestal” (the picture that the user sees when opening the page on the player’s screen), and this behavior is not customizable. I admit that flv4phpYou can configure it in the best way, and make it still do what you need, and without wild loads on the processor. Nevertheless, the small snippet of PHP code below does almost the same thing as flv4php - and is guaranteed to have good performance :)

    3.2. Do it yourself or everything just seems complicated.



    $start = (int) filter_input(INPUT_GET, 'position', FILTER_VALIDATE_INT);
    if ($start < 0) die("Incorrect request");
    // open file for reading
    $fp = fopen('sample.flv', 'r');
    $fsize = filesize($file);
    if ($start > 0)
    {
    // seek to requested position
    fseek($fp, $start);
    // FLV header for the movie part. Magic. Trust me ;)
    // Header code is completely taken from flv4php project
    $header = "FLV" . pack('C', 1 ) . pack('C', 5 ) . pack('N', 9 ) . pack('N', 9 );
    header("Content-Length: " . (strlen($header) + $fsize - $start));
    echo $header;
    } else {
    header("Content-Length: " . $fsize);
    }
    while(!feof($fp)) {
    print(fread($fp, 1024));
    }
    fclose($fp);

    ?>


    As you can see, everything is extremely simple, I think the explanations are superfluous.

    4. Convert to FLV from other formats. The basics of ffmpeg & mencoder . Meta information and how to cram it into a FLV file.



    Uff, practically, we're done. In this chapter, I’ll talk a little about how to convert video content to FLV format and how to shove the meta information that is necessary for HTTP streaming into finished movies. I will not dwell on the software available under MS Windows, instead I will focus on * nix solutions (it is no secret that most web projects run on servers running * nix / Linux / FreeBSD, and this information may be useful).
    The most famous and powerful projects are ffmpeg and mencoder. Both programs work with most of the currently known video formats, have an extensive database of codecs and / or the ability to connect custom codecs. Both work at a good speed (however, you understand that video processing is a thankless task and consumes a lot of resources and time).
    To convert an existing movie to FLV format, you need to run approximately the following commands:
    ffmpeg :
    $ ffmpeg -i sample.avi sample.flv
    (see the documentation for ffmpeg - ffmpeg.mplayerhq.hu/ffmpeg-doc.html for additional options)
    mencoder :
    $ mencoder sample.avi -of lavf -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames -ovc lavc -lavcopts vcodec=flv:vbitrate=500:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -oac mp3lame -lameopts abr:br=56 -srate 44100 -o sample.flv
    (see the documentation for mencoder - www.mplayerhq.hu/DOCS/HTML/en/index.html for more options).
    And again about the meta information.
    Neither ffmpeg nor mencoder insert meta-information about key frames into the header of the resulting FLV file. Meanwhile, this information is absolutely necessary in order to organize HTTP-streaming. How to be They again come to the aid of developers - open source products :). For example, a small program called Yamdi (Yet Another Meta-Data Injector): sourceforge.net/projects/yamdi . With its help, even large FLV files (well, say, in gigabytes) can be supplied with the necessary meta-data in a very short time.

    Literature and references:


    flv streaming with lighttpd : blog.lighttpd.net/articles/2006/03/09/flv-streaming-with-lighttpd
    Streaming Flash Video with Nginx :
    blog.kovyrin.net/2006/10/14/flash-video-flv -streaming-nginx

    This section is not complete, in fact, of course, I had to crawl a little more :)

    Also popular now: