Forwarding a Range of Ports in VirtualBox

virtualbox_logo

Doesn't allow forwarding a range of ports through the UI

I recently had to forward a range of ports to a VirtualBox instance. The VirtualBox GUI doesn’t provide a method for forwarding a range of ports. The VirtualBox Manual describes a way for adding the rule via the command-line:

VBoxManage modifyvm "VM name" --natpf1 "guestssh,tcp,,2222,,22"

This forwards any traffic arriving on port 2222 to port 22 on the virtual instance. We can use this to create a short bash loop. In the example below, we’re forwarding ports 2300-2400 to ports 2300-2400 on the virtual instance (both TCP and UDP):

for i in {2300..2400}; do
VBoxManage modifyvm "windows" --natpf1 "tcp-port$i,tcp,,$i,,$i";
VBoxManage modifyvm "windows" --natpf1 "udp-port$i,udp,,$i,,$i";
done

You can verify this by going back into the VirtualBox port forwarding page and seeing the newly configured ports. It’s just as easy to delete them:

for i in {2300..2400}; do
VBoxManage modifyvm "windows" --natpf1 delete "tcp-port$i"; 
VBoxManage modifyvm "windows" --natpf1 delete "udp-port$i"; 
done

This should suffice until the capability is added to the VirtualBox UI.

Tweeting Tweetable Bible Verses

Tweet tweet

Tweet tweet

I follow several Twitter feeds that tweet verses from the Bible. I whipped up the KJVTweeter Twitter account when I realized that the accounts I followed had some common afflictions:

  • tweeting popular verses only
  • selecting verses over 140 characters
  • tweeting one verse at a time from the beginning

The popular verses are nice, but doesn’t help me learn. Longer verses require a click-through, which isn’t always desirable. They might be lesser-known verses, but for a medium like Twitter, you really want to focus on the tweet-friendly verses. Another account is beginning in Genesis and is estimated to be done in 83 years. I just need a simple account that tweets short verses in random order. KJVTweeter (github) does all of these things.

Behind the Scenes:

I found a copy of the King James Translation in text format. I wanted to find a version with shortened names of the books (tweet-friendly). The copy available at av1611.com had the book, chapter, and verse number, a newline, and then the verse. Some quick perl transforms the file into verses contained in a single line, and only prints if the verse is under 141 characters.

The transformation process after obtaining the file is short and sweet:

unzip -p KJV.zip | ./parser.pl | sort -R -o random_bible.txt

One interesting point is that the unzip program doesn’t accept STDIN, so prepending this pipeline with wget or curl won’t work.

kjvtweeter-twitter

Still pretty new!

It’s also been a while since I’ve come across a file with carriage returns. I was having a hard time figuring out why I couldn’t do something as simple as joining two strings. In the original version, I just used dos2unix, but it was just as easy to substitute out the return.

The tweeting shell script is run every hour. It takes the very first line from the verse file, tweets it, then removes the first line from the file. I was having difficulty figuring out how I’d select a random line from the file (shuf -n1) and later remove it. I originally pulled a random line, then used grep to get the line number, then used sed to remove that line number. It is much more efficient to sort the file upfront, then pull from the top. The perl to tweet the verse itself is a modified copy of the code available here: lukesthoughtdump.blogspot.com.

For this file, 16758 of the 31102 verses are tweetable — 53.88% of the Bible. The cronjob is set up to tweet once an hour, which means that it will finish after 699 days (1.91 years or 1 year and 334 days). It’ll be very easy to kick it off again at that time!

Building a Streaming Radio Station, Part 3: Streaming Analytics

stk.fm in action

This is the final segment of my blog post about building a streaming radio station. Part 1 can be found here, and part 2 can be found here.

Streaming Analytics

The station was just about ready to launch. Just one part was missing – analytics. It’s difficult to keep track of analytics for streaming audio simply due to the nature of the content. I couldn’t find an existing solution that fit my needs, so I built my own.

I was only majorly concerned with a few different metrics – namely, how many people were listening, what they listened to, and how long they listened. I added a new table to the MySQL database that the rest of the site had been running on to keep track of these metrics. In the player’s check-in process, I added an include for a script which would register analytics. This script would add or update a row for that particular session (identified by PHP session ID) which stored:

  • Timestamps for the first and most recent check-ins
  • The first and most recently listened to songs
  • The number of seconds of music that were streamed

It wasn’t possible to derive the length of time the user was actually listening from the start and end times, as the player wouldn’t check in if the stream was paused. However, I of course knew that the player checked in every five seconds, so I could use this to get a fairly close approximation of how much audio was actually streamed.

 

Between now and the time that I started writing this series of blog posts, I unfortunately had to take stkbuzz down entirely. However, I do intend on making the previously mentioned Python script open source soon – I’d hate to see it go to waste!

Building a Streaming Radio Station, Part 2: iframe hacks and jPlayer

This is a continuation of my blog post about building a streaming radio station – the first part can be found here. The first post was related to the server side aspects of the project. In this post, I’ll talk about the client-side player I built for stkbuzz.com.

Client Side – iframe hacks and jPlayer

With the Python script complete, the Icecast station was streaming and maintaining its own playlist – it could be streamed by pasting a link into your media player of choice. However, I wanted the station to be as accessible as possible. Ideally, there would be a persistent player embedded into the bottom of the website. Of course, the best way of accomplishing this is by building the website with this idea in mind, using AJAX to load new content without ever navigating away from the player. It was a little late for that, however.

The next best solution was to get hacky with iframes. I decided to implement this solution. The idea is that every page on the site is marked as either child or parent (the parent page being the page with the MP3 player and an iframe, which will show the rest of the site’s content; the children being everything else). If a child page is loaded outside of an iframe, we redirect to the parent page, while pushing the original URL so that it knows what page to load into the iframe. We also use Javascript to update the URL in the browser’s location bar so that it’s still possible to link to a specific page externally. The only downside is the addition of a # to every URL – not a terrible tradeoff, considering that the solution worked more or less flawlessly.

Building the player itself was easy. I used jPlayer, a jQuery library that implements cross-browser audio streaming. It’ll attempt to use HTML5 to stream media if it is available; if it’s not, it can fall back to Flash. Fortunately, it works without a hitch with Icecast – just set Icecast’s MP3 mount point as the source media file.

Once the user hits the play button to start streaming audio, I had the player check in with the Icecast server every five seconds to grab the artist and title of the currently playing song (I used  jCycle to build a ticker to display various information). Icecast doesn’t make it particularly easy to get the currently playing song’s metadata, but I wrote a few tiny PHP scripts that output the desired information by calling MPC. Part of the five second check-ins involved curling these scripts.

 

In the third and final post of this series, I’ll talk about how I implemented analytics for the station. Stay tuned!

Building a Streaming Radio Station, Part 1: Icecast, MPD, and Python

I run an anonymous message board for Stockton College – stkbuzz.com. It’s fairly active, and due to the nature of the site, it gets some pretty amazing posts. I had the idea of recording dramatic readings of some select posts, but the problem was that I didn’t have a good way of delivering audio content to my audience. After bouncing some ideas off of my co-workers, I decided that the best way of doing so would be via an online streaming radio station, accessible from a player embedded into the bottom of the website – enter stk.fm, the Buzz.

Icecast and MPD

I researched my options for streaming audio in a radio-like fashion, and it seemed like Shoutcast and Icecast were the two most popular. After previously having a less-than-stellar experience with Shoutcast, I decided to give Icecast a shot. I’m happy to report that so far, it’s working great – I haven’t had a single problem with it yet.

I planned the “structure” of the content that would be played fairly early on. The structure looked something like this:

  • An intro segment (sometimes known as a radio bump)
  • A talk segment (such as a dramatic reading)
  • Another bump
  • Either one or two songs
  • Repeat!

This would obviously require a rather fine-grained level of control. The nice thing about Icecast is that it can use MPD as an audio source. MPD (Music Player Daemon) is, as the name might suggest, simply a daemon that plays music from a library. It doesn’t play music directly, however; it acts as a server which requires a client. In this case, Icecast is our client (this was incredibly easy to configure). Icecast streams whatever the source gives it, and since we can control MPD directly, we can essentially control Icecast directly.

Serving Content

The next step was to automate adding tracks to the MPD playlist. I wrote a Python script that acts as a DJ, playing tracks in the structure I originally settled on. The script does the following:

  • First, it looks at a set of directories that I’ve specified and generates a “segment” for each MP3 it finds – a segment simply being an ordered list of MP3s that will be added to the MPD playlist. Typically, a segment will consist of a randomly chosen bump, followed by the content. However, I built in a simple regex check that looks at the filename of the content and can prepend or append specific bumps (for example, any filename that begins with the string “read_” is a dramatic reading, and should therefore always be prepended by the bump that says “and now, a dramatic reading…”).
  • After the segments are generated, they are dumped into a pool with segments of their own type (talk or music) to be later pulled out and copied into the MPD playlist when MPD is playing the last song in the list (from within Python, I used MPC to interact with MPD). At that point, the segment is put into a queue and will be placed back into the pool of playable content after a certain number of other segments have been played (this allows for the content to be continuously shuffled).

 

Part 2 of this blog post will cover the client side player as well as streaming analytics. For now, you can check out stk.fm on stkbuzz.com!