A dummy's guide to creating a live-streaming platform... with Wordpress

What’s up everyone. I spent quite a bit of time developing my live streaming platform and I thought I’d share what I’ve learned. Why you ask? Well because I spent hours and hours researching this stuff - I must have Googled every possible term, Wordpress plugin, custom module out there… I’m not even kidding! I think my blood-pressure is permanently higher because of all this, and I’m most likely scarred for life. I should also mention a lot of what I learned simply didn’t exist before, at least not publicly or inexpensively. So I either had to code it myself, bootstrap things together, or bug Wowza support and consultants. My only hope is that I can save someone from some of the pain I endured through all this - and as a way to contribute back and help make this community even more awesome. I seriously wish I had all this when I started, so I’m going to do the “nice” (read: crazy) thing and do it myself. Seems like a stupid thing to do seeing as all this is info you literally have to pay for. Well stupid sounds right up my alley! Let’s do it!

Oh yeah, I should also mention that my methods are a bit unorthodox. There is probably a way better way to do things. So, use at your own risk. It’s also going to be long, boring, and confusing. Enjoy.

Let’s start at the beginning…

For some ungodly and idiotic reason I decided to use Wordpress as my content management system. So if you are familiar with Wordpress like I was, not good at coding like I am, you’re probably feeling like you should develop your platform on Wordpress. Makes sense, right? Well I am just going to warn you that Wordpress is definitely NOT made for a project such as this. That much should be obvious. You’re going to have to do a lot of hacking, testing, tweaking, bootstrapping, and hardcore headache medication to get things working. And you’ll end up with a mess of things that might even barely work! If you’re good with all that, feel free to use some of my tips.

I should also mention that I am super poor so I couldn’t just hire anyone (which is what I’d highly recommend you do if you are trying to create your own platform. Seriously, for the love of god and all that is good in this world, email Wowza support and ask for their consultant list).

So a lot of these resources you can use to create your platform up until the point to where you’re nearing launch. After that, you’re going to have to come up with the money to ignite the fuse.

Good? Good.

Ok.

Let’s do a little bit of pre-emptive checking.

You should know what kind of platform you want to make.

  • Is it just going to be you streaming?

  • Is it going to be a video conferencing service?

  • Are you going to let other people stream?

  • Are you going to charge them, or have it be free and monetize another way?

    You need to know all this, because it’s going to really affect what you have to do.

    Here’s what I wanted:

    -A live streaming platform “one-to-many” model

    -Let new people sign up and stream for free (this is important because if you charge, you can set things up a little differently)

    -Have it generate a unique “channel” for each person that they can customize, but only they can stream to

    -Include a live-chat for each channel

    That is the gist of it. So if you are wanting something similar, it’s your lucky day.

    Now, before I continue I should mention there are some pre-made solutions floating around. One in particular is a plugin called Video Whisper. You can actually install it from the Wordpess repository for free and see if it’s right for you. For me, it was definitely not right. If you’re wondering why, I found it way too confusing. It also seems to be more oriented for a “just you streaming” type of plugin, which is not what I wanted. It’s also like $500. I recommend you check it out anyway because hey, it might work for you. And kudos to them for making it.

    Tip #1: licensing

    The first thing you’ll want to do is get yourself a Wowza license if you don’t already. You are allowed to use their trial on Amazon EC2. I just got a small instance, but make sure you choose the Bring Your Own License Key (BYOL) AMI instance, or else your trial key will not work. Yeah, I actually chose the standard version and wondered why I was suddenly broke, so don’t do that. You could alternatively just install Wowza yourself, but there’s really no point in that when you could just do it in a couple clicks.

    So head on over to the AWS Marketplace and create your instance. I just chose an m1.small because I didn’t know what I was doing and I’m retarded, but it served me pretty well for development. Later on when you want to get serious, you’re going to want the c1.medium instance as it’s the best bang for your buck - or so I’ve heard.

    I’m actually not going to walk you through setting up the instance. Sorry. There’s plenty of Wowza documentation on that which is much better than anything I could write. And you know, if you’re going to be setting up a live-streaming platform you may as well familiarize yourself with the technology. You poor bastard, I feel sorry for you already.

    Tip #2: plan for scaling

    This was another thing I seriously messed up. When creating your platform, you’re going to be doing a lot of linking-it-with-your-server. And if you ignore that fact, when you’re done you realize that you need a CDN. The result? You have to go back through all your source code and relink everything with your CDN. Yeah, don’t do that. Sign up for your CDN now and get Wowza to work with it. The downside? You need a full Wowza license to do it. Whatever. You’ll need one sooner or later.

    The next thing you want to do is install Wordpress. Big surprise there right? Go ahead and do that. But you also have to think about your web-host. I just did it on a shared hosting account because I’m a cheap bastard, so if you have a similar constitution to me a shared host is perfectly fine… for development. Later on you’re going to want at least a VPS. Since you’re on Wordpress you could even get with some glorious managed-hosting. One of the plus-sides for Wordpress. My favorite is WP-Engine, but you can do whatever you please.

    Tip #3: your theme

    So this was something I recently have been battling head-on with Wordpress. Your theme. Yeah, Wordpress is cool that you can make it look all pretty with relative ease. But it sucks for trying to implement custom PHP, which is really odd seeing as it’s made with PHP. So if you don’t know how to code, like I do, you’re in for a ride. My super-duper magic solution, which is going to save you so much time is… drumroll… Headway Themes.

    Why Headway.

    Well, it’s cool drag and drop, easy to learn for dummies like me, easy to customize. But the most important aspect is that you can implement PHP blocks. That saves you from having to use a plugin (the best undoubtedly being XYZ PHP by the way), and without it you’ll have to implement the code directly into your theme. That’s fine if you’re a developer / programmer / superstar, but if you aren’t – this is going to be your best option. The downside? It’s $59. Whatever, totally worth it.

    Tip #4: channel creation

    I spent like 3 whole months trying to figure out how I was going to do this. I needed a way for Wordpress to automatically create a channel for each person that only they can customize. It also needed to be locked-in to their username - so yoursite.com/username. At the end I finally decided that the best way would be to force Wordpress to make a new page every time a user signs up. I did that with this code (which you should place in your functions.php):

    //this function creates a new page (or "channel") when a person signs up. only they have the ability to edit
    /* CREATE NEW POST WITH USER, GIVE POST USER'S NAME*/
    function my_create_page($user_id){
    	$the_user = get_userdata($user_id);
    	$new_user_name = $the_user->user_login;
    	$my_post = array();
    	$my_post['post_title'] = $new_user_name;
    	$my_post['post_type'] = 'page';
    	$my_post['post_content'] = '';
    	$my_post['post_author'] = $user_id;
    	$my_post['post_status'] = 'publish';
    	wp_insert_post( $my_post );
    }
    add_action('user_register', 'my_create_page');
    

    About that. It grabs their username and sets it as the title. This effectively makes the permalink correct (yoursite.com/username). Oh yeah, you’ll want to make sure you have permalinks set to /%postname%/ (settings > permalinks).

    Tip #5: permissions

    Alright so now you might be wondering “hey schu, what’s to stop everyone from messing up each other’s channel?” A great question, Billy!

    Here’s a big thing it does that you must understand. You know that code above? It sets the page to published. Why is this a big deal? Well if the page is already published, you can 1. deny people from creating new pages, and 2. only allow them to edit their own page.

    I did all that by enforcing Wordpress roles. Basically, I set all new people as contributors with a handy plugin called WPFront User Role Editor (free):

    http://i.imgur.com/FqnW7g5.png

    Make sure you uncheck everything, EXCEPT for “read”, “upload_files”, “edit_published_pages”:

    http://i.imgur.com/YQeqgev.png

    And then the next thing I did was use the plugin Adminimize (also free).

    So what you want to do with Adminimize is go through and deactivate EVERYTHING for contributors. Pay attention to the “page” section as that’s the most relevant, seeing that all our new users will get a page to serve as their channel. So go through and tick every. single. box. for contributors. Oh yeah, everything except “title”. They could get away with updating titles.

    I didn’t like letting them see the dashboard at all, so I deactivated that for them too. You can do that with Adminimize. But thing you also want to do, especially if you’re using Headway is to drop all this into global custom class options:

    #headway-admin-meta-box-template
    #headway-admin-meta-box-alternate-title
    #headway-admin-meta-box-post-thumbnail
    #headway-admin-meta-box-seo
    #headway-admin-meta-box-display
    

    If you don’t do that, when they go to edit their channel they can seriously mess up your whole site. Basically Headway will include some “boxes” as extra functionality for admins making a new post. So things like seo, alternate titles, thumbnails. But there’s some key stuff in there that could really do damage if you leave it.

    Pro-tip for Adminimize: you can literally disable ANY feature that you don’t want your users to see. You can do this by right-clicking and choosing inspect element (if you use Chrome), and then scrolling through all the code on the side until it highlights the feature you want to remove. Then you just copy the class-name and paste it into Adminimize:

    http://i.imgur.com/HvQ0il4.png

    Tip#6: check uploads

    So I probably don’t have to tell you that you’re going to want to use Amazon S3 to store your files. But your people will also need to upload their own stuff. That also messes things up because they’ll be able to see everyone elses uploads, including YOURS and delete everything. People are jerks, they will do that. We fix that by adding this code into your functions.php:

    // this function allows streamers to only see their own uploaded media
    add_filter( 'posts_where', 'devplus_attachments_wpquery_where' );
    function devplus_attachments_wpquery_where( $where ){
    	global $current_user;
    	if( is_user_logged_in() ){
    		// we spreken over een ingelogde user
    		if( isset( $_POST['action'] ) ){
    			// library query
    			if( $_POST['action'] == 'query-attachments' ){
    				$where .= ' AND post_author='.$current_user->data->ID;
    			}
    		}
    	}
    	return $where;
    }
    

    Hopefully that’s self-explanatory.

    Tip#7: check profile

    So since we are using the users username as their channel name and permalink, we want to keep it that way. So that means we do not want them to be allowed to change their name, at all, ever.

    You can do that by adding in all THIS code to your functions.php as well:

    //remove fields from profile
    function add_twitter_contactmethod( $contactmethods ) {
      unset($contactmethods['aim']);
      unset($contactmethods['jabber']);
      unset($contactmethods['yim']);
      return $contactmethods;
    }
    add_filter('user_contactmethods','add_twitter_contactmethod',10,1);
    //remove 'change display name' from profile
    add_action('show_user_profile', 'remove_display_name');
    add_action('edit_user_profile', 'remove_display_name');
    function remove_display_name($user) { ?>
    	<script>
    		jQuery(document).ready(function() {
    			jQuery('#display_name').parent().parent().hide();
    		});
    	</script>
    <?php }
    // remove nickname
    function prefix_hide_personal_options() {
            if (current_user_can('manage_options')) return false;
    ?>
    <script type="text/javascript">
      jQuery(document).ready(function( $ ){
        $("#nickname,#display_name").parent().parent().remove();
      });
    </script>
    <?php
    }
    if (is_admin()) add_action('personal_options', 'prefix_hide_personal_options');
    ?>
    

    What that does is removes nickname, username changes, and a couple other personal options. Word up.

    Tip#7: channel content

    So now you have a new page that’s made every time a user registers. That’s neat. But nothing is on their channel yet. You can fix that by adding JW Player on their channel. So the cool part is that since you’re hopefully using Headway themes, you can control what content goes there, even though you gave the user rights to edit the content. You can prevent them from removing things you don’t want, such as an instance of JW.

    Why JW Player? Well it’s the best, and literally ONLY thing I managed to get working on Wordpress that supports RTMP streaming. Don’t even bother looking up anything else, seriously.

    So on Headway themes what you want to do is create a new layout for PAGE (first I would create a new header for the front-page though, so your pages will automatically inherit it):

    http://i.imgur.com/mkEDXIX.png

    Then you can customize the page for how you want your channels to appear. Without going into too much depth, you do this by creating new “wrappers”, and then adding new “blocks” on those wrappers. If that didn’t make sense and I know it didn’t, you’ll have to read up on the Headway documentation.

    So this is what my channel looks like:

    http://i.imgur.com/mcCYsfB.png

    Basically I just created a new block and selecting “custom code”:

    http://i.imgur.com/GCjrWV3.png

    And then you can do various fun things. The first is that I wanted the title to show so the user can update it:

    <?php echo get_the_title(); ?>
    

    The second is I wanted the content to appear for the users edits:

    <?php the_content(); ?>
    

    So basically that will pull their content but only to their specific block, but they won’t be able to edit or remove the other blocks.

    Tip#8: mapping JW player

    If you made it this far, you’re probably wondering how you can only make sure that the correct stream appears for each channel. So you don’t want Joe’s stream to appear on Bob’s channel. We do that with this custom code:

    <?php 
    global $post;
    $author_id=$post->post_author;
    $author = get_the_author_meta('user_nicename',$author_id);
    $link = "rtmp://yourwowza:1935/live/";
    $video = $link . $author;
    ?>
    <div id="container"></div>
    <script src="/jwplayer/jwplayer.js"></script>
    <script type="text/javascript">
    jwplayer("container").setup({
      file: "<?php echo $video; ?>",
      width: "100%",
      aspectratio: "16:9",
      autostart: false
    });
    </script>
    

    What that does is it grabs the current author of the post, so Bob. Then it appends it to the end of the link. Anything else that is NOT Bob will not appear. But one thing you have to do is place the JW plugin on your host and set the path. Then take this line and put it in your header:

    <script src="/jwplayer/jwplayer.js"></script>
    

    Tip#9: the chat

    So this is one of those things that there are a ton of options but not many work because not many people made chat options for Wordpress. Trust me, I’ve looked at every single plugin there is regarding chat and Wordpress.

    So you really have 3 good options:

  • Ejabberd

  • IRCv3

  • Firechat / Firebase

    The first 2 are a pain because you have to set up, run, and manage a server. But they also give you the most customization options. But you’re going to really struggle finding a front-end chat plugin that’s compatible with Wordpress. Which is why I personally decided to use Firechat:

    https://firechat.firebaseapp.com/

    The cool thing about Firechat is that it’s pretty easy to get running on your site:

    <html>
      <head>
        <meta charset="utf-8" />
        <!-- jQuery -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <!-- Firebase -->
        <script src="https://cdn.firebase.com/js/client/2.0.2/firebase.js"></script>
        <!-- Firechat -->
        <link rel="stylesheet" href="https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.css" />
        <script src="https://cdn.firebase.com/libs/firechat/2.0.1/firechat.min.js"></script>
        <!-- Custom CSS -->
        <style>
          #firechat-wrapper {
    height: auto;
            background-color: #fff;
            text-align: center;
          }
        </style>
      </head>
      <!--
        Example: Anonymous Authentication
        This example uses Firebase Simple Login to create "anonymous" user sessions in Firebase,
        meaning that user credentials are not required, though a user has a valid Firebase
        authentication token and security rules still apply.
        Requirements: in order to use this example with your own Firebase, you'll need to do the following:
          1. Apply the security rules at https://github.com/firebase/firechat/blob/master/rules.json
          2. Enable the "Anonymous" authentication provider in Forge
          3. Update the URL below to reference your Firebase
          4. Update the room id for auto-entry with a public room you have created
       -->
      <body>
        <div id="firechat-wrapper"></div>
        <script type="text/javascript">
          var chatRef = new Firebase("https://your-firebase.firebaseio.com");
          var chat = new FirechatUI(chatRef, document.getElementById("firechat-wrapper"));
          chatRef.onAuth(function(authData) {
            if (authData) {
              chat.setUser(authData.uid, "Anonymous" + authData.uid.substr(10, 8));
            } else {
              chatRef.authAnonymously(function(error, authData) {
                if (error) {
                  console.log(error);
                }
              });
            }
          });
        </script>
      </body>
    </html>
    

    That’s all it takes. The bad is that customizing it can get confusing if you aren’t a programmer. I don’t really have a solution for you as I’m actually still working on this part. Sorry (but if you ask nicely I might include it later).

    Tip#10: stream protection

    Now this is something that is pretty complex, and there’s a lot of answers. I may be even doing it wrong. There’s a lot of custom modules you can buy, and different ways to achieve this. But really in this situation you have to force Wowza to authenticate with your MySQL database. The reason is because we only want Bob to be able to stream to Bob’s channel, and not Joe. You see? So we have to give Bob some kind of password that’s unique to him that he can plug into his encoder. Wowza by default publisher passwords, but that doesn’t help us because it’s not automated. Your best bet is some kind of token, and adding a custom Wowza module to authenticate with your MySQL.

    I’m going to go ahead and list the best options I found:

    http://www.synapse.ws/wowza-flash-applications/#6 - $??

    http://www.solid-thinking.com/product/sti-streaming-protection-for-wowza/ - $30 (this is by a guy name Graeme Bull. He’s great)

    https://streamtoolbox.com/wrench - $200 (by Balazs. He is super cool and actually got on Skype with me to help)

    http://www.clavain.com/wowzasolutions.html - $15 (note: it’s JUST the custom module, there is no authentication provided, so you’ll have to make it yourself)

    I ended up going with STI as it was more in my price range and already had what I need right from the box. Your mileage may vary. I would highly recommend you look into Wrench as well. It is the most flexible and well documented, and Balazs is helpful. Unfortunately it didn’t end up working for me as I needed a custom PHP mechanism for authentication.

    Things to look out for

    -You’ll probably want a custom-login feature that uses the front-end of your site rather than Wordpress default. There are so many plugins for this, just check out codecanyon.

    -You might want something to get connection information in order to show who is connected per each stream. I haven’t found a way to do this yet, but am playing with some options.

    Summary

    Well that pretty much wraps it up. I’m sure I’m forgetting some things, but all the important parts are here. Lesson learned? You probably shouldn’t use Wordpress.

    I hope this helped someone, and if anyone has input for me I would LOVE to hear it. Thank you and have a good day.

This one is very helpfull topcic for people who just want to start a streaming website. I am one of these people and i appreciates your post and will to help.

I read very carefully the whole post i found some solutions for me, but i dont want to use wordpress anyway. however i just want to know wich plugin do you use for the live broadcast? i tried videwhisper months ago and i didn’t like it cuz it is so boring and not customizable as i needed to be.

If you need some help too, i am always open to help.

Anyway, thank you for your great post.

i too have recently modified a wordpress for livestreaming. i modified the videotube theme which already supports user channels, static uploads, iframes, and urls to yt/vimeo/etc. i also added support for ‘pro’ members, which adds transcoding, multicasting to twitch or youtube livestreaming or any rtmp livestreaming service, and also have the ability to create live events, streams, and go live via the websites youtube account. the chat was pretty easy as you can use any irc network and any web irc client… but since i was already running my own ircd i used that. stream protection came in the form of unique stream names/keys which were auto generated, like the way twitch.tv does it… and just used aliasmap.play to hide the real stream name. added items to the dashboard which have record start and stop buttons which send get requests to the livestreamrecord module, start and stop buttons for each of the multicast publish points, etc. files are stored on the server in a separate directory created for each user, and can only be downloaded or accessed if the user is logged in. there is also a button to export the video to youtube or export just the audio to soundcloud. jwplayer was also my choice for players as it has native support for rtmp and hls using a fallback method between flash and html5.

mostly it was all just a proof of concept… and im not entirely sure its all still working 100% because i used the same site to dev a few other things like timeline comments for the videos (soundcloud style) =]

This one is very helpfull topcic for people who just want to start a streaming website. I am one of these people and i appreciates your post and will to help.

I read very carefully the whole post i found some solutions for me, but i dont want to use wordpress anyway. however i just want to know wich plugin do you use for the live broadcast? i tried videwhisper months ago and i didn’t like it cuz it is so boring and not customizable as i needed to be.

If you need some help too, i am always open to help.

Anyway, thank you for your great post.

Hey alloces. I’m glad you found this helpful. I’ve actually changed a lot of things but that basic setup will work. Wordpress was not meant to be used this way, but one of the perks is that it’s really good at managing users and the content. Anyway as for what plugin I use, the short answer is… none!

The way it’s set up is to give each person their own page, only they can edit and only they can broadcast to. The basics of that setup are explained above. I think you meant what encoder I use? Well there a huge number of encoders available but my personal favorite is Open Broadcaster Software. It’s free & open source, supports multiple scenes and even chroma keys. But you can go with whatever you want as the setup I described is encoder agnostic. Once you embed JW player with the correct URL, you can broadcast to it via your encoder. When you get into it and eventually want to support multiple protocols, such as streaming or viewing to an Ipad or something, JW player can do that too. It will just take a change in the code to make JW recognize what protocol the Wowza Engine is broadcasting.

i too have recently modified a wordpress for livestreaming. i modified the videotube theme which already supports user channels, static uploads, iframes, and urls to yt/vimeo/etc. i also added support for ‘pro’ members, which adds transcoding, multicasting to twitch or youtube livestreaming or any rtmp livestreaming service, and also have the ability to create live events, streams, and go live via the websites youtube account. the chat was pretty easy as you can use any irc network and any web irc client… but since i was already running my own ircd i used that. stream protection came in the form of unique stream names/keys which were auto generated, like the way twitch.tv does it… and just used aliasmap.play to hide the real stream name. added items to the dashboard which have record start and stop buttons which send get requests to the livestreamrecord module, start and stop buttons for each of the multicast publish points, etc. files are stored on the server in a separate directory created for each user, and can only be downloaded or accessed if the user is logged in. there is also a button to export the video to youtube or export just the audio to soundcloud. jwplayer was also my choice for players as it has native support for rtmp and hls using a fallback method between flash and html5.

mostly it was all just a proof of concept… and im not entirely sure its all still working 100% because i used the same site to dev a few other things like timeline comments for the videos (soundcloud style) =]

Sorry for the late response, I haven’t checked here in a while. And wow, I commend you for not only using Wordpress but for achieving all those cool features. I for one just went through a lot of that and can say that it’s no easy task to set up a live-streaming platform, but also hacking Wordpress into one on top of it.

I ended up going with IRCd as well and it wasn’t so difficult, my biggest problem was finding support for problems I couldn’t solve.

Couple questions for you if you don’t mind:

  • Why did you use aliasmap to hide the stream name if you’re using secure tokens? Just an added layer of security?

  • You mention storing files for each person in a directory on the web-server - why not harness something like S3?

  • You also mentioned using IRC, and I am assuming that each “channel” will get their own IRC channel as well. If this is the case, how did you achieve registering channel names (or setting the correct owner as the IRC channel “founder”)?

  • What IRCd services are you using?

    Anyway congrats on building something like this, and thanks for responding here with those useful tidbits :cool:

I’m about to break ground on this exact project (with the help of experienced wordpress php programmers and hosting techs), but prior to that I sourced a quote from a private agency.

They quoted Backend ONLY at $325,000…Why given your scalable explanation and set up would their figures be so astronomically high?

Your model seems to include everything I would need to construct a scalable TWITCH, correct?

What am I missing?

  • I explained the need to support multi-user live streaming events to the extent Twitch does

I don’t really see that price being justified. You may spend that much in a year to get the entire business going, including your own servers / CDN, bandwidth, and paying all your technicians to keep things updated. I’d imagine a fair bit of other business related expenses as well such as marketing & PR, live-chat and servers, and what not.

But $325k just to build the website? You probably wouldn’t even spend that much on bandwidth for a long time, which I’d say is the most expensive thing regarding this type of project. Of course I do not know exactly what their offer entails.

@Schuyler Davis I have a similar project that I am recruiting for at this time. If you are willing to discuss your experience and ability to assist, I would be willing to discuss owner shares in the company. Please let me know how I can contact you if you would like to discuss this further.

Hello @Phil Burk,

I’d be delighted to talk about your project.
I can’t find how to send you a message on here, but you can send me an email:

wowza [at] broadcasterfm.com

Hi Schuylerm, do you have a email I could reach out to you?

Thanks a lot for sharing your experience!

You made my day with this:

“And you know, if you’re going to be setting up a live-streaming platform you may as well familiarize yourself with the technology. You poor bastard, I feel sorry for you already.”

There’s just a “few” acronyms to learn. haha . Thanks for sharing this tutorial in our forums @Alkis Kastrisios- it’s great to have contributions like this.