TV Scrobbling

Having seen Dale Lane’s work with VDR to build something similar to Last.FM for the TV he’s been watching, I’ve been looking to see if I could do the same with MythTV.

MythTV 0.23 has shipped recently and with it came a new event system. Having had a quick look at the feature for this it looked like it would be a good starting point for this. The following events looked like they may be able to provide what I needed.

  • Playback started
  • Playback stopped
  • Playback changed

To use events you specify a command to run when each fires. You can set these up with the mythtvsetup command. As well as specifying a command you can also pass arguments, these arguments are passed using the same tokens used for the MythTV job system. The following is not the full list, but should be enough to do what I’m looking for.

  • %TITLE% – Title
  • %SUBTITLE% – Episode subtitle
  • %CHANID% – MythTV channel id
  • %DESCRIPTION% – The blurb from EPG
  • %PROGSTART% – The listed started time for the programme
  • %PROGEND% – The listed end time for the programme

There is also an option to add a command that fires on every event which you can also pass a %EVENTNAME% argument, this is very useful for debugging event ordering. Not all of the events support all of the arguments as the data is not relevant.

After a bit of playing I managed to get most of what I needed, but there where a few problems

  1. No way to tell the difference between watching recorded and live TV
  2. No way to tell when you change channel when watching live TV
  3. No way to tell when one live programme ends and a new one starts with live TV

I raised a bug in the MythTV tracker (#8388) to cover the first 2 (since the 3rd one didn’t occur to me until I got a bit further). Which the guys very quickly added. So there is now a LiveTV Started event fired when a frontend starts watching live tv followed by a Playback Started event with the details of the programme. I’ll raise a ticket for the last one and assuming I can get sign off from the boss I’ll see about submitting a patch to add it in. In the mean time with a little extra work I can infer the programme change from the Record Started and Record Finished events.

Acting on the events

So with all these events which may be reported on either the backend or frontend it’s looking good for another messaging solution. Luckily I already broker up and running for my home power monitoring and security setup. So now I just needed to run up a script or two to publish the events and a consumer with a state machine to act on them.


#!/bin/sh
#
# playStarted.sh %TITLE% %SUBTITLE% %DESCRIPTION% %CHANID%

/home/mythtv/bin/sendMessage TV/watching/start “$1/$2 ($3) on $4”

mythtvsetup events screen

Where sendMessage is a small script that publishes the second argument to the topic in the first. The other end is Java JMS application that keeps the state machine up to date and update the database when a show ends. Dale was kind enough to send me his database schema, so the data should look the same.

What next

Now I’ve got my data logging to a local database I need to come up with a front end to present it all. Next time I get 5mins to chat to Dale when we are both in the office I will see if I can borrow some of his code and if he wants to look at if we can build a site where we can all share what we’ve been watching?

Along with the events for the internal workings of the front and backends there are 10 user configurable events that can be bound to key presses, assuming I can find a spare button on the remote it should be possible to bind one of these to something like Favourite.


Resources

IPv6

It’s been coming for a while, but we really are getting close to running out of IPv4 addresses. The rate of growth of the internet continues to accelerate with not just more and more people getting online but items such as appliances and sensors. This internet of things has been talked about before (small corporate plug) here, all these things need an IP address in order to interact with the rest of the world.

There are a number of technologies that have been deployed try and help eek out the finite pool of IPv4 addresses such as CIDR and NAT. NAT works well when connections are initiated from behind the NAT gateway, but don’t work when the remote end needs to open the connection, e.g. FTP data connections.

The long term solution is to move to IPv6, this new iteration of the protocol has a much larger pool of addresses (capable of supplying 6.67 * 10^27 addresses per square meter of the planet) which should last a while longer.

Playing

Since we are all going to have to move to IPv6 at some point I thought I’d have a play. My ISP at home does not offer IPv6 support yet but there are companies that offer IPv6 over IPv4 tunnels. Wikipedia has a list here, I picked Hurricane Electric who offer free 6in4 tunnels and have multiple end points in Asia, Europe and the US.

Once you have signed up there is a “Create Regular Tunnel” link in the left hand side bar. To use a tunnel from Hurricane Electric you need a static IPv4 address that can be pinged from the internet. When you have entered your IPv4, the site will suggest the closest end point.

By default Hurricane hand out a IPv6 subnet with a /64 prefix, this means that the top 64bits of the address are considered the network mask and the rest of the address can be used for up to 18,446,744,073709,551,616 hosts. With that many addresses to go at I don’t think I’m likely to run out any time soon. It is possible to get /48 subnets assigned as well if for any reason you think that a /64 will not be enough (actually there are good reasons why you might want this which I’ll mention later).

Once you have completed the tunnel request form you should end up with a page which has information similar to this.

Account: hardillb
	Global Tunnel ID: 53560 	Local Tunnel ID: 1701
	Description:
	Registration Date: 	Tue, Apr 13, 2010
Tunnel Endpoints
	Server IPv4 address: 	216.66.80.26
	Server IPv6 address: 	2001:470:xxxx:xxx::1/64
	Client IPv4 address: 	93.97.xxx.xxx
	Client IPv6 address: 	2001:470:xxxx:xxx::2/64
Available DNS Resolvers
	Anycasted IPv6 Caching Nameserver:	2001:470:20::2
	Anycasted IPv4 Caching Nameserver:	74.82.42.42
Routed IPv6 Prefixes and rDNS Delegations
	Routed /48: 	Allocate /48
	Routed /64: 	2001:470:xxxx:xxx::/64
	RDNS Delegation NS1: 	none
	RDNS Delegation NS2: 	none
	RDNS Delegation NS3: 	none

Hurricane also provide helpful little feature at the bottom of the page that details the configuration details for a bunch of different operating systems. There are 2 different sets for Linux depending which tool chain you are using.


modprobe ipv6
ifconfig sit0 up
ifconfig sit0 inet6 tunnel ::216.66.80.26 # Server IPv4 address from above
ifconfig sit1 up
ifconfig sit1 inet6 add 2001:470:xxxx:xxx::2/64  # Client IPv6 address from above
route -A inet6 add ::/0 dev sit1

Configuration

The configuration hints on the Hurricane page are useful for testing but don’t match up with the various distros methods for establishing the tunnel at startup. The following instructions apply to Fedora 12

The first step is to enable IPv6, this is easily done by adding the last line to /etc/sysconfig/network file:


NETWORKING=yes
HOSTNAME=tiefighter
NETWORKING_IPV6=yes

Next the tunnel interface needs setting up. To do this create the following file as /etc/sysconfig/network-scripts/ifcfg-sit1.


DEVICE=sit1
BOOTPROTO=none
ONBOOT=yes
IPV6INIT=yes
IPV6TUNNELIPV4=216.66.80.26       # the IPv4 addres of your ISP's tunnel server
IPV6TUNNELIPV4LOCAL=192.168.1.5     # your host's local IPv4 address
IPV6ADDR=2001:470:xxxx:xxx::2/64         # your host's public IPv6 address

Once these where set restarting the networking component brought up the tunnel. This now means that this machine can send and receive traffic via IPv6, but that doesn’t get me any further than I had with the static IPv4 address I already had. The next step is to enable the other machines on my network so they can route via IPv6 as well. IPv6 has support for automatic address configuration built in called Stateless address autoconfiguration, the specification allows hosts to generate their own addresses based on the MAC address of the network card that it will use to send the packets over. This generates a 64bit number which acts as the host part of the address, the network part is supplied by the local router using the router announce protocol, as long as network part of the address is larger than /64 then it all works fine. . This all works because of IPv6’s hierarchical routing means that all packets with my prefix will be will be directed to tunnel and from then on it becomes my networks job to route them to the end hosts.

Back to the comment earlier about a /64 network not being enough for some people, if you have multiple network segments behind your tunnel then having a /48 network then you can assign different /64 networks to each segment to allow you to use Stateless address autoconfiguration on each.

To make the tunnel machine act as a router for all the other machines on the network it needs to be configured to forward packets and to make router announcements so the other machine can form correct addresses. Setting up the packet forwarding is easy enough, it’s just a case of adding another line to /etc/sysconfig/network file.


NETWORKING=yes
HOSTNAME=tiefighter
NETWORKING_IPV6=yes
IPV6_ROUTER=yes

To enable Router Announce we need the radvd app, once installed edit the /etc/radvd.conf file


interface eth0 {
	AdvSendAdvert on;
	MinRtrAdvInterval 30;
	MaxRtrAdvInterval 100;
	prefix 2001:470:xxxx:xxx::/64
	{
		AdvOnLink on;
		AdvAutonomous on;
	};
};

The last thing that needs doing is assigning a IPv6 address to the eth0 interface by adding it to /etc/sysconfig/network-scripts/ifcfg-eth0.


DEVICE=eth0
TYPE=Ethernet
BOOTPROTO=none
HWADDR=00:1B:FC:10:0E:E5
ONBOOT=yes
DHCP_HOSTNAME=tiefighter
USERCTL=no
IPV6INIT=yes
PEERDNS=no
IPADDR=192.168.1.5
NETMASK=255.255.255.0
GATEWAY=192.168.1.254
DNS2=213.162.97.66
SEARCH=loc
DNS1=127.0.0.1
IPV6ADDR=2001:470:xxxx:xxx::3
NM_CONTROLLED=no

That should be it, I now have a fully functional IPv6 subnet at home. For Linux machines running NetworkManager it should just be a case of enabling IPv6 for the connection.

The only bit that is missing is DNS because remebering IPv6 addresses is even harder than IPv4 addresses, I’ll save that for the next post.


Resources