MM and SqueezeBox Script

Post a reply

Smilies
:D :) :( :o :-? 8) :lol: :x :P :oops: :cry: :evil: :roll: :wink:

BBCode is ON
[img] is ON
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: MM and SqueezeBox Script

Re: MM and SqueezeBox Script

by Gingernut63 » Sat Jul 23, 2011 4:18 pm

Hi all

Just to let you know that the script mentioned in this topic is still being improved. It has been renamed MonkeySqueeze and more info can be viewed here:

http://www.mediamonkey.com/forum/viewto ... =2&t=59515

Gingernut63

Re: MM and SqueezeBox Script

by Van der C. » Mon May 02, 2011 2:31 am

Does this work in Windows 7? (what about the 64 bit flavor?)

Thank you for your time and help.

Re: MM and SqueezeBox Script

by gpzbc » Sat Feb 06, 2010 3:16 pm

check out this thread http://www.mediamonkey.com/forum/viewto ... 99#p243199

Edit: I just realized you already have. :D

Re: MM and SqueezeBox Script

by kalowski » Sat Feb 06, 2010 12:25 pm

"guest" was me.
Any news on this or similar scripts??

Re: MM and SqueezeBox Script

by Guest » Fri Jan 22, 2010 1:26 pm

:(

I've tried to install this, calling it squeezebox.vbs but when I start MM I always get "illegal character in Squeezebox.vbs" and I have no idea what the illegal character is!

Re: MM and SqueezeBox Script

by gpzbc » Wed Apr 22, 2009 5:31 pm

Yes!
I would love to be able to integrate MM and my squeezebox! :wink:

Re: MM and SqueezeBox Script

by Simon Chick » Sat Apr 04, 2009 8:37 am

Can we start a petition? :D

Re: MM and SqueezeBox Script

by zoomster » Sat Apr 04, 2009 12:09 am

Simon Chick wrote:Any likely date when a more finished release for those illiterate in scripting (like me) might appear?
I will second this one, too. MediaMonkey is such a great programme but so is the squeezebox setup. Both make up a terrific combination.
Please come up with something to help us enjoy both.

Re: MM and SqueezeBox Script

by Nonreality » Fri Apr 03, 2009 3:12 am

Simon Chick wrote:Any likely date when a more finished release for those illiterate in scripting (like me) might appear?
I'll second that. Just not sure if it's one script or a script plus an addon that you put in the SC folder. Maybe some install instructions would help. Plus what you have to edit to make it work for our setups. Sounds like it's working pretty well now.

Re: MM and SqueezeBox Script

by Simon Chick » Sun Mar 08, 2009 4:45 am

Any likely date when a more finished release for those illiterate in scripting (like me) might appear?

Re: MM and SqueezeBox Script

by debacle » Fri Mar 06, 2009 12:07 am

Solved: convert to short file paths. Use this snippet in the script in MediaMonkey, then you don't have to do anything on the SqueezeBox side. The OnPlay and OnSeek can do "TrackPath = CurrentSong" and you're set.

Code: Select all

Function ShortFilePath(LongFilePath)
  Dim FSO : Set FSO = CreateObject( "Scripting.FileSystemObject" )
  ShortFilePath = FSO.GetFile(LongFilePath).ShortPath
End Function

Function CurrentSong
  CurrentSong = ShortFilePath( CheckPath(SDB.Player.CurrentSong) )
  CurrentSong = Escape( CurrentSong )
  CurrentSong = Replace(CurrentSong,"%5C","%2F")
End Function

Re: MM and SqueezeBox Script

by Guest » Mon Mar 02, 2009 10:24 pm

Ugh, VBScript Escape() encodes some characters differently than Perl uri_escape()... So far I've encountered one of these in my library: the cross symbol. So now my SqueezeCenter plugin's FixFile() looks like:

Code: Select all

sub FixFile($)
{
	my $file = shift;

	$file =~ s/%u2020/%86/g;
	$file = uri_escape(uri_unescape($file));
	$file =~ s/'/%27/g;
	$file =~ s/%2C/,/g;
	$file =~ s/%26/&/g;
	$file =~ s/%5B/[/g;
	$file =~ s/%5D/]/g;
	$file =~ s/%3A/:/g;
	$file =~ s/%2F/\//g;

	return $file;
}
There *must* be a nice way to do this that handles all cases properly. But I'm not too familiar with the escaping formats, or the libraries available for Perl and VBScript to do this kind of thing. Maybe we want to re-write the MediaMonkey script in Perl, and just have a little VBScript file to call the new Perl script?

Re: MM and SqueezeBox Script

by debacle » Sun Mar 01, 2009 8:43 pm

Fixed some more character issues, where uri_escape escapes things that SqueezeBox doesn't want escaped (and vice versa).

Snippet:

Code: Select all

sub FixFile($)
{
	my $file = shift;

	$file = uri_escape(uri_unescape($file));
	$file =~ s/'/%27/g;
	$file =~ s/%2C/,/g;
	$file =~ s/%26/&/g;
	$file =~ s/%5B/[/g;
	$file =~ s/%5D/]/g;
	$file =~ s/%3A/:/g;
	$file =~ s/%2F/\//g;

	return $file;
}

# our 'playlistPlay' wrapper function
sub MediaMonkey_playlistPlayCommand
{
	my @args = @_;

	my $request = $args[0];
	my $item = $request->getParam('_item');
	my $escape = FixFile($item);

Re: MM and SqueezeBox Script

by debacle » Sun Mar 01, 2009 4:54 pm

I've been working on this MediaMonkey <--> SqueezeCenter concept and thought I'd share some stuff. Thanks to everyone who contributed and got us started on this! I've added:
  • OnSeek handler
  • some error handling / stability
  • a SqueezeCenter plugin that:
    • Deals with '#' number signs in filenames (which was broken for me with the script - I assume everyone else would have the same problem).
    • Allows you to control MediaMonkey from any client (at the moment, "Play", "Rew" (previous track), "Pause", and "Fwd" (next track) are supported).
    • Changes Mute to toggle properly (before, my SqueezeBox clients would just mute every time, instead of toggling - I assume everyone else has this problem). Also, clients will be unmuted when they're powered off, so their volume is restored next time they power on.
Here's my SqueezeBox.vbs at the moment:

Code: Select all

'==========================================================================
' NAME: SqueezeBox Controller
'
' ORIGINAL AUTHOR: Todd Nemeth /revel
' DATE STARTED: 26.09.2007
'
' ADDITIONAL AUTHORS: Baz, Big_Berny, Peke, trixmoto
' UPDATE DATE: 28.02.2008
'
' COMMENT:
'- You need w3Sockets installed and registered from here:
'  http://www.dimac.net/default3.asp?M=FreeDownloads/'Menu.asp&P=FreeDownloads/FreeDownloadsstart.asp
'- You will also need SlimServer installed and running.'
'==========================================================================

Option Explicit
Public SqueezeBoxSocket
Public ManualTrackChange

Sub OnStartup
  Dim ind
  Call Script.RegisterEvent(SDB,"OnPlay","Event_OnPlay")
  Call Script.RegisterEvent(SDB,"OnPause","Event_OnPause")
  Call Script.RegisterEvent(SDB,"OnStop","Event_OnStop")
  Call Script.RegisterEvent(SDB,"OnSeek","Event_OnSeek")
  Call Script.RegisterEvent(SDB,"OnShutdown","Event_OnShutdown")
'  Call Script.RegisterEvent(SDB,"OnTrackEnd","Event_OnTrackEnd")
'  Call Script.RegisterEvent(SDB,"OnPlaybackEnd","Event_OnPlaybackEnd")
'  Call Script.RegisterEvent(SDB,"OnIdle","Event_OnIdle")
  ind = SDB.UI.AddOptionSheet("SqueezeBox Controller",Script.ScriptPath,"InitSheet","SaveSheet",-2)
  InitSqueezeBox
  ManualTrackChange = True
  Call SDB.Player.Play
End Sub

Sub InitSheet( Sheet)
  Dim UI : Set UI = SDB.UI
  Dim LabelAbout : Set LabelAbout = UI.NewLabel(Sheet)
  LabelAbout.Multiline = True
  LabelAbout.Common.SetRect 5,5,470,40
  LabelAbout.Common.Anchors = 4
  LabelAbout.Caption = "This small script will add ability to Control SqueezeBox using MediaMonkey Playback Controls"

  Dim Label1 : Set Label1 = UI.NewLabel(Sheet)
  Label1.Autosize = True
  Label1.Common.SetRect 10,31,65,20
  Label1.Common.Anchors = 4
  Label1.Caption = SDB.Localize("SlimServer IP:")
  Label1.Common.Hint = "Local IP address where SlimServer is Installed (127.0.0.1, 192.168.1.10, ...)"

  Dim Edit1 : Set Edit1 = UI.NewEdit(Sheet)
  Edit1.Common.ControlName = "SqueezeBoxIP"
  Edit1.Common.SetRect 85,27,121,20
  Edit1.Text = SDB.IniFile.StringValue("SqueezeBox","IP")
  If Edit1.Text = "" Then
    Edit1.Text = "127.0.0.1"
    SDB.IniFile.StringValue("SqueezeBox","IP") = "127.0.0.1"
  End If
  Edit1.Common.Anchors = 1
  Edit1.Common.Hint = "Enter Local IP address where SlimServer is Installed (127.0.0.1, 192.168.1.10, ...)"

End Sub

Sub SaveSheet(Sheet)
  SDB.IniFile.StringValue("SqueezeBox","IP") = Sheet.Common.ChildControl("SqueezeBoxIP").Text
End Sub

Sub InitSqueezeBox
  On Error Resume Next
  Set SqueezeBoxSocket = CreateObject("Socket.TCP")
  SqueezeBoxSocket.DoTelnetEmulation = True
  SqueezeBoxSocket.TelnetEmulation = "TTY"
  SqueezeBoxSocket.Host = SDB.IniFile.StringValue("SqueezeBox","IP") & ":9090"
  SqueezeBoxSocket.Open
End Sub

Sub CloseSqueezeBox
  On Error Resume Next
  SqueezeBoxSocket.Close
End Sub

Sub SendSqueezeBoxCmd(strPlayerCmd)
  On Error Resume Next
  SqueezeBoxSocket.SendLine( "XXXXXXXXXX " & strPlayerCmd )
  ' Call ReadSqueezeBoxLine
End Sub

Sub ReadSqueezeBoxLine
  On Error Resume Next
  Dim line
  line = SqueezeBoxSocket.GetLine
End Sub

Function SqueezeBoxMode
  On Error Resume Next
  SqueezeBoxMode = ""
'  SqueezeBoxSocket.SendLine "mode ?"
'  SqueezeBoxMode = SqueezeBoxSocket.GetLine
End Function

Function Max(a,b)
  If a > b Then
    Max = a
  Else
    Max = b
  End If
End Function

Sub Event_OnPlay
  Dim strRetVal, TrackPath
  TrackPath = Escape(CheckPath(SDB.Player.CurrentSong))
  TrackPath = Replace(TrackPath,"%5C","%2F")
  TrackPath = Replace(TrackPath,"#","%23")
  If ManualTrackChange = True Then
'    MsgBox("Manual")
    Call SendSqueezeBoxCmd("stop")
'    MsgBox( TrackPath )
    Call SendSqueezeBoxCmd("playlist play file%3A%2F%2F%2F" & TrackPath )
  Else
'    MsgBox("Auto")
    Call SendSqueezeBoxCmd("playlist add file%3A%2F%2F%2F" & TrackPath )
    ManualTrackChange = True
  End If
End Sub

Function CheckPath(SongValue)
If Left(SongValue.Path,1) = "?" Then
   If SongValue.Cached Then
     CheckPath = SongValue.CachedPath
   Else
     CheckPath = SongValue.Path
   End If
Else
   CheckPath = SongValue.Path
End If
End Function

Sub Event_OnStop
  Call SendSqueezeBoxCmd("stop")
End Sub

Sub Event_OnShutdown
  On Error Resume Next
  Call SendSqueezeBoxCmd("stop")
  CloseSqueezeBox
End Sub

Sub Event_OnPause
  If SDB.Player.IsPaused Then
	Call SendSqueezeBoxCmd("pause FromMediaMonkeyOn")
  Else
	Call SendSqueezeBoxCmd("pause FromMediaMonkeyOff")
  End If
End Sub

Sub Event_OnSeek
  Dim strRetVal, TrackPath
  strRetVal = SqueezeBoxMode
  TrackPath = Escape(CheckPath(SDB.Player.CurrentSong))
  TrackPath = Replace(TrackPath,"%5C","%2F")
  If InStr(1,strRetval,"mode stop") > 0 Then
    Call SendSqueezeBoxCmd("playlist play file%3A%2F%2F%2F" & TrackPath )
  End If
  Call SendSqueezeBoxCmd("time " & SDB.Player.PlaybackTime*0.001 )
End Sub

Sub Event_OnTrackEnd
  MsgBox("Track End")
  ManualTrackChange = False
End Sub

Sub Event_OnPlaybackEnd
  MsgBox("Playback End")
  ManualTrackChange = False
End Sub

Sub Event_OnIdle
  MsgBox("Idle End")
  ManualTrackChange = False
End Sub
Notes:
  • I've added some "On Error" stuff to prevent error messages if SqueezeCenter happens to not be running.
  • The "XXXX" bit is the MAC address of my "master" SoftSqueeze client (I describe my setup later). Basically, this client is always running, and MediaMonkey explicitly controls this client. If you don't specify a MAC address, SqueezeCenter will send the commands to some random connected client; this can cause headaches in some situations (for example, when connecting a streaming client to the stream.mp3).
  • I tried adding a line to replace '#' with '%23', because SqueezeCenter was hanging on filenames with a '#' in them. But this didn't work - by the time the SqueezeCenter 'playlist play' command gets the filename, it has already been unescaped. So my SqueezeCenter plugin (discussed later) re-escapes the string before passing it to the main 'playlist play' handler. This works!
  • I liked the 'playlist add' versus 'playlist play' idea, but I wanted it to immediately switch tracks when someone manually changes the track in MediaMonkey (as opposed to switching during automated playback). You'll see that I tried adding code to do this, but OnTrackEnd, OnPlaybackEnd, and OnIdle don't seem to be ever called! So I've disabled that for now, and always call 'playlist play'. Most tracks have a couple seconds of silence at the end, which is enough to prevent cutoffs in my setup.
  • Notice that I never call 'GetLine' anymore. SqueezeCenter is supposed to send a response for every single command, but sometimes this seems to be delayed for several seconds. So I don't call it. This means I can't really query the 'mode' of the SqueezeBox client anymore, so I just assume that it is in sync with what MediaMonkey's doing. This could only cause problems for the OnSeek handler, which means that automated playback will never be affected.
  • The "FromMediaMonkey" stuff is to prevent infinite loops with the SqueezeCenter plugin (code for that is given later).
  • I've added a command to start playback once the connection is set up. This is so my music server restarts itself on system reboots.
Here's how my main SqueezeCenter plugin code looks right now:

Code: Select all

package Plugins::MediaMonkey::Plugin;

use strict;
no strict "refs";

use Slim::Utils::Prefs;
use Plugins::MediaMonkey::Logging;
use lib qw(H:\Perl\lib);
use OLE;
use URI::Escape;

# create a logging object
my $log = Plugins::MediaMonkey::Logging::new('MediaMonkey');
$log->setTypes('all');
$log->setLevel(20);

# get the preferences
my $prefs = preferences('server');

# global variables
my $callbackset = 0;
my $mm_plyr = 0;
my $ignoreNextPowerOnCommand = 0;
my $playback = 0;
my %volumes = ();
my $originalJumpCommand;	# need to keep track of original
my $originalPauseCommand;	# need to keep track of original
my $originalPlayCommand;	# need to keep track of original
my $originalStopCommand;	# need to keep track of original
my $originalMuteCommand;	# need to keep track of original
my $originalVolumeCommand;	# need to keep track of original
my $originalSyncCommand;	# need to keep track of original
my $originalPowerCommand;	# need to keep track of original
my $originalPlaylistPlayCommand;

use vars qw($VERSION);
$VERSION = &vlVersion();

# whether we're enabled (the callback remains in the function 
# stack after "disabling" the plugin, so we need to keep track of this)
my $pluginEnabled = 0;

# setup routine
sub initPlugin
{
	# note that we should act
	if ( $callbackset == 0 ) {
		$log->msg("wrapping functions\n");

		# trap 'jump' so we can route it to MediaMonkey
		$originalJumpCommand		= Slim::Control::Request::addDispatch(['playlist',       'index',          '_index',     '_noplay',     '_seekdata'],        [1, 0, 0, \&MediaMonkey_jumpCommand]);
		my $originalJump2Command	= Slim::Control::Request::addDispatch(['playlist',       'jump',           '_index',     '_noplay',     '_seekdata'],        [1, 0, 0, \&MediaMonkey_jumpCommand]);
		if ( (!defined($originalJumpCommand)) || (ref($originalJumpCommand ) ne 'CODE') || ($originalJumpCommand ne $originalJump2Command) ) {
			$log->msg("problem wrapping 'jump' command!\n");
		}
		
		# trap 'pause' so we can route it to MediaMonkey
		$originalPauseCommand		= Slim::Control::Request::addDispatch(['pause',          '_newvalue'],                                                       [1, 0, 0, \&MediaMonkey_pauseCommand]);
		if ( (!defined($originalPauseCommand)) || (ref($originalPauseCommand ) ne 'CODE') ) {
			$log->msg("problem wrapping 'pause' command!\n");
		}
		
		# trap 'play' so we can route it to MediaMonkey
		$originalPlayCommand		= Slim::Control::Request::addDispatch(['play',          '_newvalue'],                                                       [1, 0, 0, \&MediaMonkey_playCommand]);
		if ( (!defined($originalPlayCommand)) || (ref($originalPlayCommand ) ne 'CODE') ) {
			$log->msg("problem wrapping 'play' command!\n");
		}

		# trap 'stop' so we can route it to MediaMonkey
		$originalStopCommand		= Slim::Control::Request::addDispatch(['stop'],                                                                              [1, 0, 0, \&MediaMonkey_stopCommand]);
		if ( (!defined($originalStopCommand)) || (ref($originalStopCommand ) ne 'CODE') ) {
			$log->msg("problem wrapping 'stop' command!\n");
		}

		# trap 'mute' so we can route it to MediaMonkey
		$originalMuteCommand		= Slim::Control::Request::addDispatch(['mixer',          'muting',         '_newvalue'],                                     [1, 0, 0, \&MediaMonkey_muteCommand]);
		if ( (!defined($originalMuteCommand)) || (ref($originalMuteCommand ) ne 'CODE') ) {
			$log->msg("problem wrapping 'mute' command!\n");
		}

		# trap 'volume' so we can route it to MediaMonkey
		$originalVolumeCommand		= Slim::Control::Request::addDispatch(['mixer',          'volume',         '_newvalue'],                                     [1, 0, 0, \&MediaMonkey_volumeCommand]);
		if ( (!defined($originalVolumeCommand)) || (ref($originalVolumeCommand ) ne 'CODE') ) {
			$log->msg("problem wrapping 'volume' command!\n");
		}

		# trap 'sync' for inspection
		$originalSyncCommand = Slim::Control::Request::addDispatch(['sync','_indexid-'],[1, 0, 0, \&MediaMonkey_syncCommand]);
		if ( (!defined($originalSyncCommand)) || (ref($originalSyncCommand ) ne 'CODE') ) {
			$log->msg("problem wrapping 'sync' command!\n");
		}

		# trap 'power' for inspection
		$originalPowerCommand = Slim::Control::Request::addDispatch(['power','_newvalue'],[1, 0, 0, \&MediaMonkey_powerCommand]);
		if ( (!defined($originalPowerCommand)) || (ref($originalPowerCommand ) ne 'CODE') ) {
			$log->msg("problem wrapping 'power' command!\n");
		}

		# trap 'playlist play' for inspection
		$originalPlaylistPlayCommand = Slim::Control::Request::addDispatch(['playlist',       'play',           '_item', '_title'],[1, 0, 0, \&MediaMonkey_playlistPlayCommand]);
		if ( (!defined($originalPlaylistPlayCommand)) || (ref($originalPlaylistPlayCommand ) ne 'CODE') ) {
			$log->msg("problem wrapping 'playlist play' command!\n");
		}

		$callbackset = 1;
	}
	$pluginEnabled = 1;
	$log->msg("MediaMonkey plugin enabled\n");
}

sub shutdownPlugin
{
	$log->msg("MediaMonkey plugin shutting down");
	# we should not act
	$pluginEnabled = 0;
	$log->msg("MediaMonkey plugin disabled\n");
}

sub enabled
{
	return 1;
}

sub vlVersion()
{
	my $rcsVersion = '$Revision: 1.0 $';
	$rcsVersion =~ s/.*:\s*([0-9\.]*).*$/$1/;
	return $rcsVersion;
}

sub getDisplayName()
{
	return 'PLUGIN_MEDIAMONKEY';
}

sub connectToMM()
{
	if( !$mm_plyr )
	{
		$log->msg("getting MediaMonkey object\n");
		my $mm_app = CreateObject OLE 'SongsDB.SDBApplication' || die $!;
		$mm_app->{'ShutdownAfterDisconnect'} = 0;
		$mm_plyr = CreateObject OLE 'SongsDB.SDBPlayer' || die $!;
	}
}

# our 'jump' wrapper function
sub MediaMonkey_jumpCommand
{
	$playback = 1;

	my @args = @_;

	$ignoreNextPowerOnCommand = 1;

	my $request = $args[0];
	my $client = $request->client();
	my $index = $request->getParam('_index');
	my $noplay = $request->getParam('_noplay');
	my $seekdata = $request->getParam('_seekdata');

	$log->msg("MediaMonkey_jumpCommand running:\n");
	$log->msg("  _index: " . $index . "\n");
	$log->msg("  _noplay: " . $noplay . "\n");
	$log->msg("  _seekdata: " . $seekdata . "\n");

	if( !$pluginEnabled || !defined( $index ) )
	{
		my $rc = &$originalJumpCommand(@args);
		return $rc;
	}

	$log->msg("MediaMonkey_jumpCommand taking over.\n");

	if( defined( $index ) )
	{
		if( $client->power() )
		{
			connectToMM();
			if( $index > 0 )
			{
				$mm_plyr->Next();
			}
			elsif( $index < 0 )
			{
				$mm_plyr->Previous();
			}
			else
			{
				$mm_plyr->Play();
			}
		}
	}
	else
	{
		$ignoreNextPowerOnCommand = 0;
	}

	$request->setStatusDone();
}

# our 'pause' wrapper function
sub MediaMonkey_pauseCommand
{
	my @args = @_;

	my $request = $args[0];
	my $newvalue = $request->getParam('_newvalue');
	my $fromMM = 0;

	$log->msg("MediaMonkey_pauseCommand running:\n");
	$log->msg("  _newvalue: " . $newvalue . "\n");

	if( !$pluginEnabled )
	{
		my $rc = &$originalPauseCommand(@args);
		return $rc;
	}

	if( $newvalue eq "FromMediaMonkeyOn" )
	{
		$request->deleteParam('_newvalue');
		$request->addParam('_newvalue', 1);
		my $rc = &$originalPauseCommand(@args);
		return $rc;
	}
	elsif( $newvalue eq "FromMediaMonkeyOff" )
	{
		$request->{'_request'}[0] = 'play';
		$request->deleteParam('_newvalue');
		my $rc = &$originalPlayCommand(@args);
		return $rc;
	}

	$log->msg("MediaMonkey_pauseCommand taking over.\n");

	connectToMM();
	$mm_plyr->Pause();

	$request->setStatusDone();
}

# our 'play' wrapper function
sub MediaMonkey_playCommand
{
	$playback = 1;

	my @args = @_;

	$log->msg("MediaMonkey_playCommand running.\n");

	my $rc = &$originalPlayCommand(@args);
	return $rc;
}

# our 'stop' wrapper function
sub MediaMonkey_stopCommand
{
	my @args = @_;

	$log->msg("MediaMonkey_stopCommand running.\n");

	my $rc = &$originalStopCommand(@args);
	return $rc;
}

# our 'mute' wrapper function
sub MediaMonkey_muteCommand
{
	my @args = @_;

	my $request = $args[0];
	$log->msg("MediaMonkey_muteCommand running.\n");

	if( $pluginEnabled )
	{
		my $client = $request->client();

		if( $client->volume() == 0 )
		{
			$request->{'_request'}[1] = 'volume';
			$request->deleteParam('_newvalue');
			$request->addParam('_newvalue', $volumes{ $client } );

			my $rc = MediaMonkey_volumeCommand(@args);
			return $rc;
		}
		else
		{
			$volumes{ $client } = $client->volume();
		}
	}

	my $rc = &$originalMuteCommand(@args);
	return $rc;
}

# our 'volume' wrapper function
sub MediaMonkey_volumeCommand
{
	my @args = @_;

	my $request = $args[0];
	my $client = $request->client();
	$log->msg("MediaMonkey_volumeCommand running.\n");

	my $rc = &$originalVolumeCommand(@args);
	$volumes{ $client } = $client->volume();
	$client->mixerDisplay('volume');
	return $rc;
}

# our 'sync' wrapper function
sub MediaMonkey_syncCommand
{
	my @args = @_;

	my $request = $args[0];
	my $indexid = $request->getParam('_indexid-');

	$log->msg("MediaMonkey_syncCommand running:\n");
	$log->msg("  _indexid: " . $indexid . "\n");

	my $rc = &$originalSyncCommand(@args);
	return $rc;
}

# our 'power' wrapper function
sub MediaMonkey_powerCommand
{
	my @args = @_;

	my $request = $args[0];
	my $newvalue = $request->getParam('_newvalue');

	$log->msg("MediaMonkey_powerCommand running:\n");
	$log->msg("  _newvalue: " . $newvalue . "\n");

	if( $pluginEnabled )
	{
		if( $newvalue == 1 )
		{
			if( 0 && $ignoreNextPowerOnCommand )
			{
				$ignoreNextPowerOnCommand = 0;
				return;
			}
		}
		else
		{
			my $client = $request->client();

			if( $client->volume() == 0 && exists( $volumes{ $client } ) )
			{
				$client->volume( $volumes{ $client } );
			}
		}
	}

	$ignoreNextPowerOnCommand = 0;

	my $rc = &$originalPowerCommand(@args);

	if( $pluginEnabled && $newvalue == 1 && $playback )
	{
		connectToMM();
		if( $mm_plyr->{'isPaused'} == 1 )
		{
			$mm_plyr->Pause();
		}
	}

	return $rc;
}

# our 'playlistPlay' wrapper function
sub MediaMonkey_playlistPlayCommand
{
	my @args = @_;

	my $request = $args[0];
	my $item = $request->getParam('_item');
	my $escape = uri_escape(uri_unescape($item));
	$escape =~ s/%3A/:/g;
	$escape =~ s/%2F/\//g;
	my $title = $request->getParam('_title');

	$log->msg("MediaMonkey_playlistPlayCommand running.\n");
	$log->msg("  item: " . $item . "\n");
	$log->msg("  escape: " . $escape . "\n");
	$log->msg("  title: " . $title . "\n");

	$request->deleteParam('_item');
	$request->addParam('_item', $escape );

	my $rc = &$originalPlaylistPlayCommand(@args);
	return $rc;
}

1;
Notes:
  • A lot of trial and error went into tweaking this. I tried other, completely different approaches. In the end, this is what I came up with.
  • You can look up other example plugins online to see what other files you need to make a functional plugin, where to put the files, etc. If people are interested, I can post a .zip file or something.
  • This doesn't connect to MediaMonkey until it needs to, so you can start up SqueezeCenter and then launch MediaMonkey (in that order), and the applications will talk to each other.
  • Notice that the 'playlist play' handler re-escapes the filename to handle the '#' problem. It first runs an unescape, in case the filename came from SqueezeCenter itself (in which case it is already escaped). It also puts back ':' colons and '/' slashes - I don't think the main 'playlist play' handler likes those to be escaped.
My Setup:
  • I have a "server" box (old headless PC) running in a corner of my living room. It runs MediaMonkey, SqueezeCenter, and the "master" SqueezeBox client. It is connected via cable to my stereo receiver nearby.
  • When the server machine starts up, it starts SqueezeCenter, gives it time to get started, then starts the "master" client, waits a little more time, then starts up MediaMonkey. I'm tweaking this to try and make it work 100% of the time without taking too long to get going.
  • Other PCs in the house can run SqueezeBox clients, and they are set to synchronize with the "master" client. Since the master is always running, you instantly hook into the stream when you connect a client.
  • MediaMonkey volume is set to 0. I use the output from the "master" client for my stereo, that way it is totally in sync with the other clients in the house, in case you can hear two at once.

Re: MM and SqueezeBox Script

by debacle » Sun Mar 01, 2009 3:50 pm

Oyvindo, the point of the script is that whenever MediaMonkey plays a song, it will tell SqueezeCenter to play that same song (by giving it the file path).

Also, when you press Pause or Stop in MediaMonkey, it will tell SqueezeCenter to Pause or Stop.

I've added an OnSeek handler to my script:

Code: Select all

Sub Event_OnSeek
  Dim strRetVal, TrackPath
  strRetVal = SqueezeBoxMode
  TrackPath = Escape(CheckPath(SDB.Player.CurrentSong))
  TrackPath = Replace(TrackPath,"%5C","%2F")
  If InStr(1,strRetval,"mode stop") > 0 Then
    Call SendSqueezeBoxCmd("playlist play file%3A%2F%2F%2F" & TrackPath )
  End If
  Call SendSqueezeBoxCmd("time " & SDB.Player.PlaybackTime*0.001 )
End Sub

Top