Dreambox-NetworkRecorder

From MythTV Official Wiki
Jump to: navigation, search

Description

With this document i would like to help how to connect one or more dreamboxes (Dreambox/Enigma2 DVB receiver) as a "network recorder/FreeBox" to MythTV. In this configuration the dreambox acts as a tunercard in the MythTV enviroment.

Requirements

  • A running MythTV installation (I tested it with 0.21 + 0.22)
  • One or more dreamboxes with Enigma2 OS/Firmware
  • Skills to install and configure scripts on linux

Base facts

  • The dreambox has the ability to stream a TV-Channel over http protocol.
  • MythTV offers an IP/TV Network Recorder called FREEBOX.
  • IP/TV Network Recorder supports UDP and RTSP protocols, but not HTTP streaming! RTSP has not worked for me.
  • MythTV supports external channel change script
  • VLC is able to read the http stream and send it over udp to the MythTV Network recorder.

In theory, with the above it should be possible to implement everything we need.

Installation/Configuration

Create a directory on your MythBackend to store most of your work. Example: /opt/dreambox

Configure the dreamboxes

Make sure that your dreambox has a static ip-address in your network. On the webinterface of the dreambox you will find the streaming urls for each channel you want to add.

Example URL: http://DREAMBOX_IP:8001/1:0:1:140:39:1:FFFF0222:0:0:0:

Feel free to test it with a VLC player.

Setting up VLC in daemon mode

Create a vlm config file for the vlc daemon. Example: /opt/dreambox/dreambox.vlm This example shows the configuration for 3 Dreambox receivers and two channels. Output goes to your Mythbackend. For each dreambox you should use a different UDP port.

I know, this will get a big config file. Don't worry, read on, later you will find a script that generates this file.

The naming of the broadcast vlc resources is important. D1_1 stands for: Dreambox 1, Channel 1. D2_2 stands for Dreambox 2, Channel 2

# Channel 'SF1' on Dreambox #1
new D1_1 broadcast enabled
setup D1_1 input http://DREAMBOX1_IP:8001/1:0:1:2:45:1:FFFF0292:0:0:0:
setup D1_1 output udp://MYTHBACKEND_IP:1234
# Channel 'SF1' on Dreambox #2
new D2_1 broadcast enabled
setup D2_1 input http://DREAMBOX2_IP:8001/1:0:1:2:45:1:FFFF0292:0:0:0:
setup D2_1 output udp://MYTHBACKEND_IP:1235
# Channel 'SF1' on Dreambox #3
new D3_1 broadcast enabled
setup D3_1 input http://DREAMBOX3_IP:8001/1:0:1:2:45:1:FFFF0292:0:0:0:
setup D3_1 output udp://MYTHBACKEND_IP:1236

# Channel 'SF2' on Dreambox #1
new D1_2 broadcast enabled
setup D1_2 input http://DREAMBOX1_IP:8001/1:0:1:3:45:1:FFFF0292:0:0:0:
setup D1_2 output udp://MYTHBACKEND_IP:1234
# Channel 'SF2' on Dreambox #2
new D2_2 broadcast enabled
setup D2_2 input http://DREAMBOX2_IP:8001/1:0:1:3:45:1:FFFF0292:0:0:0:
setup D2_2 output udp://MYTHBACKEND_IP:1235
# Channel 'SF2' on Dreambox #3
new D3_2 broadcast enabled
setup D3_2 input http://DREAMBOX3_IP:8001/1:0:1:3:45:1:FFFF0292:0:0:0:
setup D3_2 output udp://MYTHBACKEND_IP:1236

You can now start/test your vlc daemon on your backend with the following command:

su - ACCOUNT_NAME -c 'vlc -I telnet --vlm-conf /opt/dreambox/dreambox.vlm --daemon'

ACCOUNT_NAME: Your account, because root is a bad choice.

Telnet to your VLC daemon and check your channels:

telnet MYTHBACKEND_IP 4212

The default password is 'admin'. Type 'show' to list your VLC streams. 'quit' to logout.

Configure MythTV

Creating the .m3u files

Each IP/TV Networkrecorder (FREEBOX), requires a .m3u playlist as a channel list. The channel scanner on Myth fetches the config file via HTTP. Create a new directory on your local webserver:

mkdir /var/www/dreambox

create the config files in there:

>:/var/www/dreambox# ls -l
total 12
-rw-r--r-- 1 root root 2444 2010-01-02 22:15 dreambox1.m3u
-rw-r--r-- 1 root root 2444 2010-01-02 22:15 dreambox2.m3u
-rw-r--r-- 1 root root 2444 2010-01-02 22:15 dreambox3.m3u

It should have the following format:

dreambox1.m3u:

#EXTM3U
#EXTINF:0,1 - SF1
#EXTMYTHTV:xmltvid=1.sfdrs.ch
udp://MYTHBACKEND_IP:1234
#EXTINF:0,2 - SF2
#EXTMYTHTV:xmltvid=2.sfdrs.ch
udp://MYTHBACKEND_IP:1234

dreambox2.m3u:

#EXTM3U
#EXTINF:0,1 - SF1
#EXTMYTHTV:xmltvid=1.sfdrs.ch
udp://MYTHBACKEND_IP:1235
#EXTINF:0,2 - SF2
#EXTMYTHTV:xmltvid=2.sfdrs.ch
udp://MYTHBACKEND_IP:1235

dreambox3.m3u:

#EXTM3U
#EXTINF:0,1 - SF1
#EXTMYTHTV:xmltvid=1.sfdrs.ch
udp://MYTHBACKEND_IP:1236
#EXTINF:0,2 - SF2
#EXTMYTHTV:xmltvid=2.sfdrs.ch
udp://MYTHBACKEND_IP:1236

Take care that the UDP Ports are corresponding to the VLC configuration. The Channel Number 1,2 should also correspond to the VLC Stream Name.

VLC Config: D1_1 -> dreambox.m3u: 0,1 VLC Config: D1_2 -> dreambox.m3u: 0,2

Again, this will be a big config file. Read ahead, you will receive a script to generate this config file too.

Try to fetch it in your browser: http://MYTHBACKEND_IP/dreambox/dreambox1.m3u

Add the IP/TV Network Recorder

Startup your MythTV Backend Setup.

If you like, you may create a new video source for the dreamboxes:

"3. Video sources" -> "New video source"

For each dreambox you have to add a Network Recorder:

"2. Capture cards" -> "New capture card"

Card Type: Network Recorder

M3U URL: http://MYTHBACKEND_IP/dreambox/dreambox1.m3u

Scan the channels:

"4. Input connections" -> "Select the new "FREEBOX..."

Select the video source and "Scan for channels"

Repeat this for each dreambox.

The channel change script

Each Network Recorder must have its channel change script. I have implemented it in two scripts. Put this scripts in your /opt/dreambox directory

The first one is an expect script that talks to the VLC daemon via telnet and drops commands to it. It is called "VLC_CMD"

#!/usr/bin/expect
log_user 0
set timeout 50
set cmd1 [lindex $argv 0]
set cmd2 [lindex $argv 1]

spawn telnet localhost 4212

expect "Password: "
send "admin\n"

expect "> "
send "$cmd1\n"

expect "> "
send "$cmd2\n"

expect "> "
send "quit\n"

The second script is written in PHP. With help of the first script it changes the channel by stopping the current running stream and starts the new one. The current channel will be stored as well. If you don't have the php interpreter you have to installed it:

apt-get install php-cli

The main script, VLC_CONTROL:

#!/usr/bin/php
<?
	$DEBUG=0;
// Log entry witch shows us, that a recorder has stopped.
	$MYTH_LOG_PATTERN="/.*TVRec\(%d\): Changing from Watching .* to None.*/";
// Encodernumbers for all dreamboxes/enimga2
 	$DBOX_IDS=array(1,2,3,4);
// Nothing to change below

	$info=pathinfo($argv[0]);
	$DBOX=$info["basename"];
	$DIR=$info["dirname"];

	if($DEBUG==1) { echo "Starting as ".$DBOX."\n"; print_r($argv); }

	if($argv[1]=="SCAN_SWITCH_OFF")
	{
		if($DEBUG==1) { echo "Mythtv scan log mode\n"; }
	 
		$fp2=fopen("php://stdin","r");
                while(!feof($fp2))
                {
                        $line=fgets($fp2,256);
                        // For each dreambox

			for($i=0;$i<count($DBOX_IDS);$i++)
			{
				$scan=sprintf($MYTH_LOG_PATTERN,$DBOX_IDS[$i]);
				if(preg_match($scan,$line)==1)
				{
					$DBOX="D".$DBOX_IDS[$i];

					if($DEBUG==1) { echo "Matched: ".$scan."\nStopping ".$DBOX."\n"; }

					## Get previous channel
					list($prev_channel)=file($DIR."/.".$DBOX);
					if($DEBUG==1) { echo "Prev. Channel ".$prev_channel."\n"; }
					$cmd1="control ".$DBOX."_".$prev_channel." stop";
					$ex=$DIR."/VLC_CMD '".$cmd1."'";
					if($DEBUG==1) { echo "exec ".$ex."\n"; }
					system($ex);
					if($DEBUG==1) { echo "done\n"; }
				}
			}
		}
		exit;
	}
	else
	{
		## Get previous channel
		list($prev_channel)=file($DIR."/.".$DBOX);
		if($DEBUG==1) { echo "Prev. Channel ".$prev_channel."\n"; }

		$cmd1="control ".$DBOX."_".$prev_channel." stop";
		$cmd2="control ".$DBOX."_".$argv[1]." play";

		$ex=$DIR."/VLC_CMD '".$cmd1."' '".$cmd2."'";
		if($DEBUG==1) { echo "exec ".$ex."\n"; }
		system($ex);

		if($DEBUG==1) { echo "Storing Channel\n"; }
		$fp2=fopen($DIR."/.".$DBOX,"w");
		fputs($fp2,$argv[1]);
		fclose($fp2);
	}
?>

Edit the bold line. Replace the numbers with your recordernumbers. It could be taken from your "backend status" on your mythweb. This will be used later in the stop channel script.

Don't forget to make the scripts executable to mythtv:

chmod 755 /opt/dreambox/VLC*

We don't want a copy of this scripts for each dreambox. We use "VLC_CONTROL" as the master script and create a symbolic link for each box.

cd /opt/dreambox
ln -s VLC_CONTROL D1
ln -s VLC_CONTROL D2
ln -s VLC_CONTROL D3

The script stores the current channel number in a file with the same name but with a leading dot. Create this files and make it writeable for myth.

cd /opt/dreambox
touch .D1
touch .D2
touch .D3
chmod 777 .D*

The directory looks now like this:

> ls -la /opt/dreambox
total 64
drwxrwxrwx 2 root root  4096 2010-01-04 13:28 .
drwxr-xr-x 4 root root  4096 2009-12-27 19:55 ..
lrwxrwxrwx 1 root root    11 2010-01-01 14:22 D1 -> VLC_CONTROL
-rwxrwxrwx 1 root root     1 2010-01-04 12:55 .D1
lrwxrwxrwx 1 root root    11 2010-01-01 14:22 D2 -> VLC_CONTROL
-rwxrwxrwx 1 root root     1 2010-01-04 12:55 .D2
lrwxrwxrwx 1 root root    11 2010-01-01 14:22 D3 -> VLC_CONTROL
-rwxrwxrwx 1 root root     1 2010-01-04 12:55 .D3
-rw-r--r-- 1 root root 17691 2010-01-02 22:15 dreambox.vlm
-rwxr-xr-x 1 root root   244 2010-01-02 00:14 VLC_CMD
-rwxr-xr-x 1 root root  1755 2010-01-02 18:26 VLC_CONTROL

Summary: By invoking the script /opt/dreambox/D1 with the channelnumber as its argument it will stop the current VLC streaming and starts the new one.

Example:

Mythtv starts the script for the networkrecorder #1 to change the channel from #1 to channel #2

The scripts will telnet to VLC with the following command:

LOGIN
control D1_1 stop
control D1_2 play
quit

You may test this by invoking the script manual. Check the status on the vlc server:

/opt/dreambox/D1 2

To check:

telnet localhost 4212
admin

show

Attaching the script

In the MythTV Backend Setup you are not able to attach the script to the Network Recorder. The GUI for this is still missing. Stop your MythTV Backend and change it directly in the database:

> mysql -umythtv -p mythconverg

Select your cardinputs:

mysql> select cardinputid,displayname,inputname,externalcommand from cardinput;
+-------------+-------------+-----------+------------------+
| cardinputid | displayname | inputname | externalcommand  |
+-------------+-------------+-----------+------------------+
|           1 | DBox1       | MPEG2TS   |                  | 
+-------------+-------------+-----------+------------------+
1 row in set (0.00 sec)

Enter your new script:

mysql> update cardinput set externalcommand='/opt/dreambox/D1' where cardinputid=1;

After staring your Mythtv Backend a channel change should now be initiated.

Config file generation

With 30-40 channels and a few dreamboxes typing the configurationfiles by hand is a nightmare ! I have created a script witch uses my own configfile to generate both files the .vlm file and the *.m3u files. The benefit is that you only have to edit one file.

Centralized configfile

I called it channel_sources and is is located in /opt/dreambox too.

Example file:

DREAMBOX_URLS,192.168.68.91,192.168.68.92,192.168.68.90
UDP_PORTS,1234,1235,1236
MYTH_BACKEND,192.168.68.13
CHANNEL,1,SF1,1.sfdrs.ch,1:0:1:2:45:1:FFFF0292:0:0:0:
CHANNEL,2,SF2,2.sfdrs.ch,1:0:1:3:45:1:FFFF0292:0:0:0:
CHANNEL,3,SFinfo,info.sf.tv,1:0:1:4:45:1:FFFF0292:0:0:0:
CHANNEL,4,SFF,,1:0:1:4F:52:1:FFFF0302:0:0:0:
CHANNEL,5,Telebasel,telebasel.ch,1:0:1:17:49:1:FFFF02C2:0:0:0:
CHANNEL,6,3+,544,1:0:1:F:49:1:FFFF02C2:0:0:0:
CHANNEL,7,StarTV,startv.ch,1:0:1:1E:4C:1:FFFF02DA:0:0:0:

The format is intuitive. IPs of the dreamboxes, corresponding UDP ports and the cannel informations. The CHANNEL lines has the following format:

CHANNEL,mythtv_channelnumber,mythtv_EPG_xmltv_string,dreambox_url

Configfile generation script

The following script generates your dreambox.vlm (VLC) config file and all your dreambox[X].m3u files in one step.

#!/usr/bin/php
<?
       $dreambox_ip=array();
       $mythbackend="";
       $udp_ports=array();

       $f=file($argv[1]);

       if(!isset($argv[2])) { echo "Second argument should be the output .vlm file\n"; exit; }
       if(!isset($argv[3])) { echo "Third argument should be the name of the output .m3u files\n"; exit; }

       $fp1=fopen($argv[2],"w");

       for($i=0;$i<count($f);$i++)
       {
               $v=explode(",",$f[$i]);
               if(trim($v[0])!="")
               {
                       if($v[0]=="DREAMBOX_URLS")
                       {
                               array_shift($v); $dreambox_ip=$v;
                               for($j=0;$j<count($dreambox_ip);$j++)
                               {
                                       $fp2=fopen($argv[3].($j+1).".m3u","w");
                                       fputs($fp2,"#EXTM3U\n");
                                       fclose($fp2);
                               }
                       }
                       if($v[0]=="UDP_PORTS") { array_shift($v); $udp_ports=$v; }
                       if($v[0]=="MYTH_BACKEND") { $mythbackend=trim($v[1]); }

                       if($v[0]=="CHANNEL")
                       {
                               for($j=0;$j<count($dreambox_ip);$j++)
                               {
                                       //
                                       // VLC config file part
                                       //
                                       fputs($fp1,"# Channel '".trim($v[2])."' on Dreambox #".($j+1)."\n");
                                       fputs($fp1,"new D".($j+1)."_".trim($v[1])." broadcast enabled\n");
                                       fputs($fp1,"setup D".($j+1)."_".trim($v[1])." input http://".trim($dreambox_ip[$j]).":8001/".trim($v[4])."\n");
                                       fputs($fp1,"setup D".($j+1)."_".trim($v[1])." output udp://".trim($mythbackend).":".trim($udp_ports[$j])."\n");
                                       //
                                       // Mythtv m3u file.
                                       //
                                       $fp2=fopen($argv[3].($j+1).".m3u","a");
                                       fputs($fp2,"#EXTINF:0,".trim($v[1])." - ".trim($v[2])."\n");
                                       fputs($fp2,"#EXTMYTHTV:xmltvid=".trim($v[3])."\n");
                                       fputs($fp2,"udp://".trim($mythbackend).":".trim($udp_ports[$j])."\n");
                                       fclose($fp2);
                               }
                               fputs($fp1,"\n");
                       }
               }
       }
       fclose($fp1);
?>

Store this script in /opt/dreambox. I called it "gen_files". Don't forget to chmod 755 on that file.

Use this script to generate the needed files:

./gen_files channel_sources /opt/dreambox/dreambox.vlm /var/www/dreambox/dreambox

It creates the /opt/dreambox/dreambox.vlm file and all .m3u files in the your directory /var/www/dreambox/dreambox.

You have to restart your VLC daemon. You have also to scan your channels in your Mythtv backend.

Automation

If you have done everything and you would like to change something, you have to do the following:

  • Edit the centralized configfile
  • Generate your VLC and m3u files with the script
  • Restart VLC daemon
  • In Mythbackend Setup execute a "scan channel" on each Network recorder

Script to stop vlc streaming if needed

Mythtv has no hook to stop streaming. We would like to stop the UDP streaming if not needed anymore. The VLC_CONTROL script is able to scan the standard input for mythbackend log entries and stops the streaming.

tail -f /var/log/mythtv/mythbackend.log | /opt/dreambox/VLC_CONTROL SCAN_SWITCH_OFF

will do the job. You may test this but you don't have to start this here.

System startup additions

Finally we need to add two lines to your /etc/rc.local file:

su - LOGINNAME -c 'vlc -I telnet --vlm-conf /opt/dreambox/dreambox.vlm --daemon'
tail -f /var/log/mythtv/mythbackend.log | /opt/dreambox/VLC_CONTROL SCAN_SWITCH_OFF &

Before the "exit 0" line.

After a reboot your vlc daemon sould running as well as the VLC_CONTROL script in the monitoring mode.