A Drupal youtube Site Recipe

Please see the Media Mover annoucement and check out the Media Mover module suite on Drupal.org

updated for drupalcon | Download the .odp presentation

Overview
This describes a Drupal project to create a youtube style video sharing site. There are two major pieces that this project dealt with that stretch the project:

  • converting users' uploaded files into a multi-platform format (FLV Flash videos)
  • hosting the uploaded content with amazon's s3 services
  • The cross platform requirement is an obvious target. Flash does pose some problems for linux users, however, for our client, Flash was deemed the best solution. Amazon's s3 solution offered a low cost bandwidth and storage solution with a high degree of scalability that we have not found a competitive alternative solution to- since Amazon's fee structure is based a flat rate usage, and appears to scale extremely well, our client didn't have to invest into a media serving infrastructure. We considered scripting a processing script that would publish to YouTube, however, given that the client had specific regulations for who could participate, we decided that not using existing video services made sense.

    Both of these requirements necessitated an approach that would involve software outside of the Drupal framework since neither currently exists. To implement, the project ended up breaking the upload process apart from the conversion and media hosting processes. Since Drupal already does a good job of easily getting media onto a machine, what seemed an appropriate way to conserve hardware cycles was to break the conversion process out in a separate script run by cron. This script uses the Drupal database to find out what files it needs to process, processes them, then moves them, pushes them over to the s3 servers, and then updates the Drupal database with urls to the media.

    This project had an extremely tight turnaround- two weeks from beginning to launch so limiting custom functionality and programing was a priority. This meant limiting the number of custom programing points in the project.

    The Drupal Video Module
    When we first started the project, we considered extending the Drupal video module. It does a good job of embedding in media in the page and is quick to install. There are a few reasons why we decided to write custom software to handle our media:

    1) we needed to convert the uploaded media
    2) we wanted to host the media in a different location
    3) we wanted to auto generate a thumbnail from video upload
    4) we were concerned about the overhead on drupal if the conversion and management was done inside of drupal
    5) we were concerned about the amount of data that the video module requires.
    6) we initially thought we might use an additional machine to process media

    All of the reasons steered us in the direction of considering writing our own module to meet our projects need.

    Using CCK
    CCK gave us pretty much everything we needed for getting our data set off the ground. We needed our data set to be small- title, description, tags, the video file, and agreement with the rules of the site. CCK gave us all of this by connecting taxonomy and file attachments. This gave us a simple form for a user to upload video.

    Some Customization
    We did end up writing a small custom module to specifically to modify some of the presentation aspects for the end user experience. Utilizing the form_alter hook, we removed several fields where we store the url for the video file on amazon and the url of the thumbnail that we generate from the video. We also change the file upload field set to always be open and present some different text which is customizable by the admin.

    We also have a small tweak to how the user registration system works. We use the profile module to collect some additional data when the user registers. The client had an unusual request that they wanted any one to be able to enter, but only people with complete profile data to be able to post video. Thus the profile data wasn't required for all users, but was required for the upload process. We interrupted the node/add/content_video form, checking tif the user had filled out all the necessary profile data. If it wasn't found, we return the user to their profile edit screen.

    The Media Mover Script
    Since we were using CCK to get the content into Drupal, we decided to write an external script to be responsible for the conversion and movement of the files to Amazon. We wanted to do this because:

    1) we could run the conversion process in a que, making it easy stop if load on the machine is high.
    2) we avoid the additional load on Drupal and possibilities for timeouts.

    This introduces a few issues
    1) we have to be careful that we're not converting or moving data that already has been
    2) conversion and or moving processes could overrun themselves.

    We wanted to use straight forward tools that were easily accessible to run the script. This resulted in writing the script in php so users without low level access to servers could easily run the script with cron. We also came up with some process flow conditions that allowed us to meet some of these challenges without to much difficulty.

    We decided that all videos being uploaded to the site would have their status set to not be published and not be in the moderation que. After the media conversion process, the media would be set to published and in the moderation que. These settings gave us ways to pick out which files needed to be processed and a mechanism to re-run the processing. This could be done with just the published flag, though in our case, we needed moderation.

    Interact with the Drupal Database
    It's fairly simple to generate a list of nodes and their files if these rules are maintained:


    $query = "SELECT files.filepath, files.nid FROM files " .
    "LEFT JOIN node ON files.nid = node.nid ".
    "WHERE ((node.type = '". $drupal_cck_content_type ."') AND (node.status != 1) AND (node.moderate != 1))";

    There are a number of ways this could be done- in our case we could have used the Amazon URL field and the Thumbnail path field that we're using since both of these would be empty for a un-processed node, however, we wanted an easy way for the client to re-run the processing, so this was our solution.

    Process the Files
    Once we have a list of files, we just need to start processing them with ffmpeg. Note that you should have the --enable-mp3lame and --enable-faad support compiled into ffmpeg to be able to convert avi and mov files into flash. You may find that this page and this are helpful if you need to install ffmpeg on a debian or ubuntu server.

    We also need to be a bit careful about the file that the user uploads. Since we're running commands from php, we have to be sure that the user can't craft a file name that might allow them to execute code locally. The file should probably be completely renamed with a hash of the node id and the file name.


    // replace scary characters
    $pattern = "/[^a-zA-Z0-9_\.]/";
    $flv_output = $output_path . preg_replace($pattern, "_", basename($file_path). ".flv");

    $command = "$path_to_ffmpeg -i '$file_path' -acodec mp3 -ar 22050 -ab 32 -vcodec flv -s " . $output_width . "X" . $output_height ." '$flv_output'";$output_height ." $flv_output";
    exec($command, $data );

    Once a file has been converted, our script moves the original file to an archive directory to keep the Drupal files directory manageable.

    We should also create a thumbnail for this video at the same time:

    $command = "$path_to_ffmpeg -y -i '$file_path' -vframes 1 -ss $thumb_time -an -vcodec mjpeg -f rawvideo -s " . $thumb_width . "X" . $thumb_height ." $thumb_path";
    exec($command, $data);

    Moving to S3
    Now we need to move the flv file to amazon's s3. I used the storage3 php library which made this straight forward:


    $s3=new storage3($myAccessKeyId, $mySecretAccessKey, $url);
    // put file on amazon
    $s3->putFile($file_path, $bucket, $file_name);
    // set the ACL
    $s3->setACL($bucket, $file_name);
    return "http://s3.amazonaws.com/" . $bucket . "/" . $file_name;

    Updating Drupal
    Now the Drupal database needs to be updated with the URL from Amazon and the thumbnail. This is pretty straight forward as we've stored all our new data in a array $files:


    // update files directory with the new path
    $query = "UPDATE files SET filepath = '". $file['archived_file'] . "' WHERE nid = '". $file['nid'] . "'";
    query_db($query);
    $query = "UPDATE $drupal_cck_content_table SET $drupal_cck_amazon_url_field = '" . $file['amazon_url'] . " WHERE nid = '". $file['nid'] . "'";
    query_db($query);
    $query = "UPDATE $drupal_cck_content_table SET $drupal_cck_thumbnailpath_field = '". $file['thumb']."' WHERE nid = '". $file['nid'] . "'";
    query_db($query);
    $query = "UPDATE node SET status = 1 WHERE nid='". $file['nid'] . "'";
    query_db($query);
    $query = "TRUNCATE cache";
    query_db($query);

    Unfortunately, we're truncating the cache here. It is probably possible to remove all of the cache only related to this specific node, however, we choose the brute force method. This should be fixed. We're running this script off of cron and run it every five minutes. We also have a lock file to prevent the script from overrunning itself.

    At this point the admin can go in and use the moderation que and make the new content visible.

    Theming the Node
    Using the swfObject library and the flash flv player to create a node with an IE Flash compatible player. We use a custom template to theme the specifics for the video nodes:


    $the_path_to_player = base_path() . path_to_theme() . "/flash_flv_player/flvplayer.swf";
    $the_movie = "$the_path_to_player?file=". $node->field_amazon_flv_file_url[0][value] . "&autostart=trueℑ=" . base_path() . file_directory_path() . "/" . $node->field_thumbnail_path[0][value];

    $params = array(
    "allowScriptAccess" => "sameDomain",
    "quality" => "high",
    "height" => "240",
    "width" => "320",
    "movie" => "$the_movie" ,
    );

    drupal_add_js(drupal_get_path('module','swfobject') . "/swfobject.js");
    print swfobject_create($the_movie, $params);

    Once you stitch all this together, you get a pretty nice system.

    Drupal modules in use

  • CCK
  • Views
  • Voting API
  • UserReview
  • swfObject
  • upload
  • a custom module that modifies the cck fields for uploading
  • References

  • ffmpeg
  • php s3 library
  • flash flv player
  • Video Blogging using Django and Flash(tm) Video (FLV)
  • hi all, i just want to know

    hi all,
    i just want to know how to deal with video library in drupal

    Thanks for this nice site

    Thanks for this nice site recipe!

    I am having problem

    I am having problem installing ffmpeg-php. It seems like an overkill. Can you send me some instructions.

    what system are you trying

    what system are you trying to install ffmpeg on? You should be able to download the source and follow the instructions in the install file. It is a bit complicated, but it is needed to make things work.

    So I'm assuming S3 streams

    So I'm assuming S3 streams the FLV file sufficiently?

    I was under the impression that this wasn't a current capability of the S3 servers so have held off a similar implementation.

    Actually, I'm not using S3

    Actually, I'm not using S3 to stream- it's a straight download. This obviously isn't ideal for folks with lower bandwidth. It's been suggested that you could use Amazon Elastic Compute Cloud to pull off an on demand streaming service without having to run a machine yourself.

    Dude you rock for posting

    Dude you rock for posting this. We're working on THIS EXACT problem with Drupal right now, and I think you just saved me about 2 days of research.

    s3's cool, but it's actually cheaper for us to host it off our SAN (we're have big pipe), but that part is really cool too. Good stuff!

    hello, can i use my own

    hello, can i use my own server and software and not the amazon web???
    it will be cheaper i think,,,, what software is need it to transform the files??
    thanks

    I would like some help in

    I would like some help in setting up a social network site, with video upload capabilities. Please could you help. Thanks Klay

    [...] spam: the other white

    [...] spam: the other white meat » A Drupal youtube Site Recipe This describes a Drupal project to create a youtube style video sharing site. There are two major pieces that this project dealt with that stretch the project: (tags: drupal video youtube cck amazon howto module webdev) [...]

    [...] This has to be one of

    [...] This has to be one of the most informative Video with Drupal sites I’ve come accross in many moons. [...]

    This is an awsome post. Are

    This is an awsome post. Are you interested in rolling out another one? I am looking for this solution but don't have the time to do it myself. I am looking for a developer..

    I ditto Jim. Are you

    I ditto Jim. Are you available for consulting work?

    I'd be happy to do

    I'd be happy to do consulting via email or phone, but I'm pretty busy these days. Give me a shout and we can work something out.

    Hi I am a newbe in

    Hi
    I am a newbe in drupal.... I need some help, Can you give me help? I have the problem that I do not know where to put the code you discribed....

    Greetings Ruud

    OpenPackage Software

    OpenPackage Software (openpackage.biz) has begun development of an OSS (open source software) Flash video module for Drupal. The primary objective of this software is to enable any Drupal website to have YouTube-style functionality with complete codec compatibility, including encoding to VP6 (the highest quality Flash codec), without the need to purchase video decoding / encoding software. This is achieved through the use of the OSS packages MPlayer and ffmpeg, along with the free binary codec pack provided by MPlayer.

    Full instructions on how to setup MPlayer and ffmpeg will be provided for Ubuntu, openSUSE, Fedora, Debian and Gentoo. Only IA-32 and x86-64 architectures have high codec availability. It can be especially tricky to install MPlayer's binary codecs on x86-64, so this will covered in depth.

    Our development of this module is being funded through the use of bounties (using the ChipIn system). Initially, the module will be developed in two phases, version 1 and version 2 (each with its own bounty of $8000 USD). Once these have been completed, various other additions to the module (see the site) will be implemented in the order that their respective bounties are fulfilled.

    Every feature implemented will be fully configurable via a comprehensive settings page, e.g. bitrate, frames per second, etc...

    The module has already been developed to a functional level, as a proof of concept, providing compatibility with all major codecs including Windows Media Video 9. The module is installed on openpackage.biz for demonstration and testing purposes. You can view uploaded videos and submit your own. The module is not yet encoding to VP6, so although the quality is very good, it will get even better (equal to YouTube).

    The following codecs are supported:

    * MPEG-1 (VCD) and MPEG-2 (SVCD/DVD/DVB) video
    * MPEG-4 in all variants including DivX Eye-wink, OpenDivX (DivX4), DivX 5 (Pro), XviD
    * Windows Media Video 7/8 (WMV1/2)
    * Windows Media Video 9 (WMV3) (using x86 DLL)
    * RealVideo 1.0, 2.0 (G2)
    * RealVideo 3.0 (RP8), 4.0 (RP9) (using Real libraries)
    * Sorenson v1/v3 (SVQ1/SVQ3), Cinepak, RPZA and other QuickTime codecs
    * DV video
    * 3ivx
    * Intel Indeo3 (3.1, 3.2)
    * Intel Indeo 4.1 and 5.0 (using x86 DLL or XAnim codecs)
    * VIVO 1.0, 2.0, I263 and other H.263(+) variants (using x86 DLL)
    * MJPEG, AVID, VCR2, ASV2 and other hardware formats
    * FLI/FLC
    * HuffYUV
    * various old simple RLE-like formats

    Once the bounty for version 1 has been met, the source code for the module will be released in its current form and a CVS account on drupal.org will be applied for. The project will be managed through openpackage.biz until a drupal.org CVS account has been obtained.

    Not all the details have been fleshed out. Investor input is extremely important in defining exactly what form this module should take. Please make your views known on the relevant pages.

    Hi. I'd like to know why is

    Hi. I'd like to know why is it important to TRUNCATE the cache upon every cron run, and if there is really a way to do if selectively ?

    FatFish- The reason to

    FatFish-

    The reason to truncate is because when the user uploads the origional file, drupal caches the node. Unfortunately, when you update drupal from outside of drupal (ie: manipulate msql is we are here), the cache does not update. In drupal 5.0 there might be a cleaner way to do this, but because the node can be cached in multiple places it's probably better to truncate the whole thing.

    You might want to check out my latest post on this. I'm moving toward producing something that is much more friendly to deal with.

    [...] building a youtube in

    [...] building a youtube in drupal (tags: drupal youtube video howto) [...]

    Are there any live sites

    Are there any live sites using this recipe? I noticed flunkarnold.com is gone...

    I was just curious if you

    I was just curious if you have any plans of releasing your alternative to the Drupal Video Module as a self-contained module for others to use in conjunction with this recipe.

    Cheers!

    www.tunaspecial.com - the

    www.tunaspecial.com - the best site

    Good night

    Thank for your help for us!
    I think it wasnt easy to post here so much information.

    best regards

    Mark

    Sorry, it work in last

    Sorry, it work in last version? Thanks.

    be good to package this into

    be good to package this into something that can be grabbed as a distro. Do you know about the filmforge project? Its trying to do exactly this with drupal. http://wiki.koumbit.net/FilmForge
    http://plumi.org is a similar type project for plone
    http://showinabox.tv/ - wordpress

    I want this, but It's too

    I want this, but It's too hard for me (.

    Unfortunately, video is

    Unfortunately, video is complicated, but there is lots of really good information out there to help you figure out what your issues are. Good luck!

    This is great. I have

    This is great. I have searched so hard to find something like this. I'm working on a fitness training website. The only difference with this is that users won't be able to upload their own videos. However, they can watch and download the videos to play on their computers and/or in other portable video formats according to their preferences.

    Storing the videos on my website is my best move due to copyright issues.

    Hello, I just read your

    Hello,

    I just read your post here. This is exactly what I need. I prepared a scope with some customization and was wondering if you are interested in doing the web development for me.

    Thank you up front.

    Best,

    Tansel

    Check out the Media Mover

    Check out the Media Mover modules- they do this in a much more drupally way. If you're looking for a development team, please check with CivicActions.

    helpful thks

    helpful thks

    Post new comment

    The content of this field is kept private and will not be shown publicly.
    • Web page addresses and e-mail addresses turn into links automatically.
    • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
    • Lines and paragraphs break automatically.

    More information about formatting options