mplayer web browser remote control

Linux howto's, compile information, information on whatever we learned on working with linux, MACOs and - of course - Products of the big evil....
Post Reply
User avatar
^rooker
Site Admin
Posts: 1484
Joined: Fri Aug 29, 2003 8:39 pm

mplayer web browser remote control

Post by ^rooker »

We've finally built the following setup for watching videos in the living room, although the computer playing them is in the basement (yeeehaaaa!):
(The audio/video signal is sent over a CAT5 cable with homemade Cinch/SVideo adapters at its ends)

- Linux server in the basement running an X11 server (& XFCE).
- Using nvtv to enable the TV out of the nVidia graphic card.
- MPlayer in slave/idle mode connected to a FIFO pipe for receiving commands.
- An HTML based mplayer interface written in PHP.
- Using a PSP (Playstation Portable) for remote controlling mplayer.

The current control features are: play/append, toggle OSD, pause, seek and playlist handling (prev/next). Works like a charm!


1) Enable the TV output:

Code: Select all

nvtv -t -S PAL -r 800,600 -s Medium
2) Create a FIFO file that mplayer will read for commands:

Code: Select all

mkfifo mplayer_control
3) Start mplayer in slave mode, but with "idle" so it won't quit, because we don't feed it a file immediately:

Code: Select all

mplayer -idle -slave -input file=/home/video/mplayer_control
4) Use our PHP code to send commands to the FIFO pipe:

Code: Select all

<?php 
// @author: ^Rooker
// @date:   22.Feb.2008
// @description: 
//   HTML based remote control for mplayer in slave mode. Optimized for PlayStation Portable (PSP).
// @history:
//	rooker	  23.Feb.2008	- Added "append", "percentage-seek" and "OSD".
//				- Limit browsing to below $basepath.
//				- Improved code.
//   	rooker	  22.Feb.2008	- Started.
//				- Directory browsing.
//				- Basic functions: play, pause, seek.
?>
<html>
	<head>
		<meta http-equiv="cache-control" content="no-cache"/>
		<meta http-equiv="expires" content="0"/>
	</head>
	<body>
<?php
	// Read URL parameters:
	$value =  $_GET['value'];
	$action = $_GET['action'];
	$path =   $_GET['path'];

	$basepath = '/media/';
	$mpCtrlFile = '/home/video/mplayer_control';


	// Allows to browse a file structure conveniently:
	function dirlist ($path) {
		global $basepath;

		//using the opendir function
		$dir_handle = @opendir($path) or die("Unable to open $path");

		echo "<h1>Directory Listing</h1>";
		echo "<i>\"$path\"</i> <br/>";
		echo "<br/>";

		// Iterating through all files/folders:
		while ($file = readdir($dir_handle)) 
		{
			if ($file != '.') {
				$fullname=$path.$file;

				if (is_dir($fullname)) {
					$fullname = realpath($fullname);
					if (($file != '..') || (($file == '..') && ($path != $basepath))) {
						echo "<a href='?path=$fullname/&uid=".uniqid()."'><$file></a> <br/>";
					}
				} else {
					echo "$file ";
					echo "<a href='?path=$path&action=loadfile&value=".$fullname."&uid=".uniqid()."'>play</a>";
					echo "&nbsp;|&nbsp;";
					echo "<a href='?path=$path&action=append&value=".$fullname."&uid=".uniqid()."'>append</a>";
					echo "<br/>";
				}
			}
		}

		closedir($dir_handle); 		//closing the directory
	}


	// Writes commands to mplayer's FIFO pipe (slave mode):
	function ctrl_player ($command) {
		global $mpCtrlFile;

		$command = $command."\n";		
		echo "<hr/>Command: $command";
		file_put_contents( $mpCtrlFile, $command );
	}

	
	function show_controls () {
		global $_SERVER, $path;

		// "uniqid" is necessary to force PSP to reload the page. :)
		?>
		<hr/>
		<table border="0" width="100%">
			<tr>
				<td align="left"><a href='?path=<?php echo $path; ?>&action=seek&value=-5 0&uid=<?php echo uniqid(); ?>'><<<</a>&nbsp;</td>
				<td align="center"><a href='?path=<?php echo $path; ?>&action=pause&uid=<?php echo uniqid(); ?>'>pause</a>&nbsp;</td>
				<td align="right"><a href='?path=<?php echo $path; ?>&action=seek&value=+5 0&uid=<?php echo uniqid(); ?>'>>>></a>&nbsp;</td>

				<td rowspan="4" align="right" valign="middle">
					<b>Das Werkstatt TV</b><br/>
					v1.1<br/>
					<i><font size="-3">Powered by MPlayer (Linux)</font></i>
				</td>
			</tr>
			<tr>
				<td colspan="3" align="center">
					<a href='?path=<?php echo $path; ?>&action=seek&value=0 1&uid=<?php echo uniqid(); ?>'>0</a>-----
					<a href='?path=<?php echo $path; ?>&action=seek&value=25 1&uid=<?php echo uniqid(); ?>'>25</a>-----
					<a href='?path=<?php echo $path; ?>&action=seek&value=50 1&uid=<?php echo uniqid(); ?>'>50</a>-----
					<a href='?path=<?php echo $path; ?>&action=seek&value=75 1&uid=<?php echo uniqid(); ?>'>75</a>
				</td>
			</tr>
			<tr>
				<td align="left"><a href='?path=<?php echo $path; ?>&action=pt_step&value=-1&uid=<?php echo uniqid(); ?>'>prev</a></td>
				<td align="center"><a href='?path=<?php echo $basepath; ?>'>BasePath</a></td>
				<td align="right"><a href='?path=<?php echo $path; ?>&action=pt_step&value=+1&uid=<?php echo uniqid(); ?>'>next</a></td>
				<td></td>
			</tr>
			<tr>
				<td colspan="2" align="left">
					OSD: 
					<a href='?path=<?php echo $path; ?>&action=osd&value=on&uid=<?php echo uniqid(); ?>'>on</a>&nbsp;|&nbsp;
					<a href='?path=<?php echo $path; ?>&action=osd&value=off&uid=<?php echo uniqid(); ?>'>off</a>
				</td>
				<td align="right">
					<a href='?path=<?php echo $path; ?>&action=quit&value=0&uid=<?php echo uniqid(); ?>'>quit</a>
				</td>
				<td></td>
			</tr>
		</table>
		<hr/>
		<?php
	}


	function show_filename ($filename, $text='') {
		$duration = 5000;    // how long to show the text (in msec).
		ctrl_player("osd_show_text \"".$text.str_replace('_', ' ', basename($filename))."\" $duration");
	}


	show_controls();
	dirlist( $path );	// Always display the directory listing. It's more convenient.
	

	switch ($action) {
		case "loadfile":
			echo "<h1>Playing: ".basename($value)."</h1>";
			ctrl_player( "loadfile \"$value\"" );
			show_filename($value);
		break;

		case "append":
			echo "<h1>Appended: ".basename($value)."</h1>";
			ctrl_player( "loadfile \"$value\" 1" );
			show_filename( $value, 'Appended: ' );
		break;

		case "pause":
			ctrl_player( "pause" );
		break;

		case "seek":
			ctrl_player( "seek $value" );
		break;

		case "pt_step":
			ctrl_player( "pt_step $value" );
		break;

		case "osd":
			if ($value == "on") $command = "osd 3";
			if ($value == "off") $command = "osd 1";
			ctrl_player($command);
		break;

		case "quit":
			ctrl_player( "quit" );
		break;

		default:
			// start with the basepath:
			if ($path == "") $path = $basepath;
		break;
	}
?>
</body>
</html>

The code is not really optimized or super-clean, but it's straightforward so it should work with *any* browser. Even lynx. ;)

Notes:
1) I'm passing a generated unique-ID with every action, in order to have the PSP load the file from the server instead of using its cached version.

2) Unfortunately, mplayer closes itself after having played a file. So I've wrapped a small loop (bash script) around it to start a new instance automatically:

Code: Select all

while true; do
    mplayer -idle -slave -input file=/home/video/mplayer_control
done
Jumping out of an airplane is not a basic instinct. Neither is breathing underwater. But put the two together and you're traveling through space!
Post Reply