[Music Sharing] How To Train Your Dragon Soundtrack

My blog is mainly about programming but I want to tell you: I <3 music also! This time, I want to share you a nice soundtrack called “How To Train Your Dragon”. Let’s enjoy!

What is a router explained

(This article is written for my classmates.)

As everyone knows, the internet is extremely big and it seamlessly connects every people, in the world. But there’s one question: how can the internet knows where to pass the data around? The answer to this problem is the router. The router, by definition, is a device that forwards data between computer networks. To understand what a router actually does, we need to have a basic understanding to the structures of the internet. Continue reading “What is a router explained”

Just changed my server

Recently, my site receives lots of traffic that almost bring my site down. After a few days of downtime, I managed to move my site to a nice dedicated server and now everything is back to normal again.

Besides, you may notice that I am now using a CDN to handle all static files for even better performance.

Stream videos to HTML5 video container using HTTP & PHP

Sometimes we need to feed videos dynamically from the server-side. If you’re feeding the video to a HTML5 <video> element, you may find that the video progress controls freezes and users cannot move it in any ways. (Thought this situation only happens in some browsers like Chrome and Firefox, the user experience hurts a lot.)

With a bit of investigation, I found out that Chrome requested the video with an HTTP range request which, the server-side handle it incorrectly and Chrome falls back to progressive downloading the video. With the little PHP script I wrote below, the server-side can now handle the HTTP range requests normally and the progress controls no longer freezes! (There’s one more benefit: fast forward and backward works much smoother in large video files.)

// Clears the cache and prevent unwanted output
@ini_set('error_reporting', E_ALL & ~ E_NOTICE);
@apache_setenv('no-gzip', 1);
@ini_set('zlib.output_compression', 'Off');

$file = "/path/to/your/media/file"; // The media file's location
$mime = "application/octet-stream"; // The MIME type of the file, this should be replaced with your own.
$size = filesize($file); // The size of the file

// Send the content type header
header('Content-type: ' . $mime);

// Check if it's a HTTP range request
    // Parse the range header to get the byte offset
    $ranges = array_map(
        'intval', // Parse the parts into integer
            '-', // The range separator
            substr($_SERVER['HTTP_RANGE'], 6) // Skip the `bytes=` part of the header

    // If the last range param is empty, it means the EOF (End of File)
        $ranges[1] = $size - 1;

    // Send the appropriate headers
    header('HTTP/1.1 206 Partial Content');
    header('Accept-Ranges: bytes');
    header('Content-Length: ' . ($ranges[1] - $ranges[0])); // The size of the range

    // Send the ranges we offered
            'Content-Range: bytes %d-%d/%d', // The header format
            $ranges[0], // The start range
            $ranges[1], // The end range
            $size // Total size of the file

    // It's time to output the file
    $f = fopen($file, 'rb'); // Open the file in binary mode
    $chunkSize = 8192; // The size of each chunk to output

    // Seek to the requested start range
    fseek($f, $ranges[0]);

    // Start outputting the data
        // Check if we have outputted all the data requested
        if(ftell($f) >= $ranges[1]){

        // Output the data
        echo fread($f, $chunkSize);

        // Flush the buffer immediately
else {
    // It's not a range request, output the file anyway
    header('Content-Length: ' . $size);

    // Read the file

    // and flush the buffer