Foobar über IPS steuern

Und weist Du wie der Folder jeweils heißt? Dann könntest Du ja eventuell das Cover direkt aus dem Folder auslesen.

Nicht ganz:


<? 
$startnext = startnext(); 
 var_dump($startnext); 
  
 function startnext() 
 { 
     $command = "StartNext"; 
    $payload = "http://192.168.178.20:8888/ajquery/?cmd=".$command; // Command ergänzen 
    $startnext = file_get_contents ($payload); 
    return $startnext; 
 } 
?>

Finde den Fehler im Vergleich zu dem was Du hast :wink:

Ja ist klar, man…:banghead:

$startnext = file_get_contents ($payload); 

Bin ein schwieriger Fall :rolleyes:

Die Cover habe ich direkt in den jeweiligen Ordner der verschiedenen Alben z.B.

Foobar Ordnerstruktur.JPG

Bekomme jetzt noch eine Fehlermeldung, die aber mit Foobar zu tun hat, da er die Datei „foo_httpcontrol_controls_tpl.html“ nicht findet, die aber auch in diesem Template nicht zu finden ist.

string(371) „Invalid requestError reading foo_httpcontrol_data\ajquery\foo_httpcontrol_controls_tpl.htmlCheck foobar2000 console (View/Console) for error details.Open ajquery template“

…wie muss ich das mit den Zusatz Parameter machen die manche Befehle haben?

z.B.

Volume

Set volume level, in percent.

param1=volume level, 0…100

EDIT: Ich habe jetzt mal ein anderes Template ausgewählt und jetzt habe ich folgende Scriptausgabe z.B. bei Play

string(14569) "

foo_httpcontrol-->
Foo_control

<!--
var mouseX = 0;
var p_key = 0;
var act = 0;

function KeyPress(e) { 
	p_key = e; 
	if (p_key == 16) // shift -- focus
		act = 3;
	else if (p_key == 17) // ctrl -- remove
		act = 4;
	else if (p_key == 81) // q -- enqueue
		act = 1;
	else if (p_key == 87) // w -- dequeue
		act = 2;
	else
		act = 0;
	document.getElementById('Actions').selectedIndex = act;
}

function pad(str, char, count) {
	var str_out = str.toString();
	while (str_out.length < count)
		str_out = char + str_out;
	return str_out;
}

function pc(c, p) {
	var com = c || ''; var par = p || '';
	with (document.cmd_form)
	{
		cmd.value = com;
		param1.value = par;
		submit();
	}
}

function format_time(time) {
	mins = Math.floor(time / 60);
	secs = pad(time % 60, '0', 2);
	return mins+":"+secs;
}

function set_t_pos(time) { 
	var str = format_time(time) + " / ";
	document.getElementById("t_time").innerHTML = str + ( 0 > 0 ? format_time(0) : '?' );
}

function set_np_width(t_sec, t_length) {
	var np_width = document.getElementById("npd").offsetWidth;
	np_width = np_width < 100 ? 100: np_width;
	document.getElementById('np').style.width=Math.floor(np_width * t_sec / t_length) + "px";
}

function t_playback_timer(t_sec, t_length) {
	if (t_sec <= t_length && t_length != 0)
	{
		set_t_pos(t_sec);
		if (t_length != 0)
			set_np_width(t_sec, t_length);
		setTimeout('t_playback_timer('+(t_sec+1)+','+t_length+')',1000);
	}
}

function a(track) { // do a(ction) on clicked entry
	if (act == 0)		pc('Start', track);
	else if (act == 1)	pc('EnqueueTrack', track);
	else if (act == 2)	pc('DequeueTrack', track);
	else if (act == 3)	pc('MoveCursor', track);
	else if (act == 4)	pc('Del', track);
}

function np_onclick() {
	with (document)
		pc('Seek', Math.round((mouseX-getElementById("np").offsetLeft)*100 / (getElementById("npd").offsetWidth)) );
}

function mouse_capture_init() {
	if (document.layers? true : false)
		captureEvents(Event.MOUSEMOVE)
	document.onmousemove = handleMouseMove;
}

function handleMouseMove(evt) {
	if (evt)
		mouseX=evt.clientX;
	else
	if (event)
	    mouseX=event.x;	
	return false;
}

function fit() {
	with (document.getElementById('playlist'))
	{
		style.position = 'static'; // important for the onresize event
		style.overflowY = 'auto';
		style.top = offsetTop + 'px';
		style.left = offsetLeft + 'px';
		style.right = offsetLeft + 'px';
		style.bottom = '2px'; // fit this to your taste
		style.position = 'absolute';

		var npelem = document.getElementById("nowplaying");
		if (npelem)
		{
			scrolltop = npelem.offsetTop - offsetHeight/2;

			if (scrolltop > 0)
				scrollTop = scrolltop;
		}
	}
}

document.onkeydown = function(evt) { KeyPress(evt?evt.keyCode:event.keyCode); }
//-->

/*BODY {background: black; color: silver;} /* colors for safety's sake */
DIV#header {position: fixed; top: 0; height: 50px; left: 0; right: 0;
background: black; margin-bottom: 2px; color: white;padding : 0,0,0,0;}
DIV#sidebar {position: fixed; width : 320px; top: 50px; bottom: 0; left: 0; 
background: black; margin-right: 2px; color: white;text-align: center;}
DIV#main {position: absolute; top: 50px; bottom: 0; left: 320px; right: 0;
 background: black; color: white;padding-left : 10px;}
body {background: #000; color: #fff; font: menu; margin: 0; padding: 0,0,0,0;}
form {margin-top: 10px; padding: 1px;}
div.nob {border-bottom: none;}
/*div, p {padding: 5px 0; margin: 0; line-height: 1.3;}*/

/* form elements */
#controls {margin-top: 5px; margin-bottom: 10px;}
input[type=button] {font: 12px sans-serif; box-sizing: border-box; margin: 3px 0; height: 1.6em; cursor: pointer;}
input[type=checkbox] {font: 12px sans-serif; box-sizing: border-box; margin: 3px 0; height: 1.6em;}
div#controls input[type=image] { vertical-align : middle; padding : 0,0,0,0;margin-right: -5px;}
select {box-sizing: border-box; margin: 3px 0; height: 1.6em; font: 12px sans-serif;}
select[title="Playlists"] {width: 56%; max-width: 400px; min-width: 95px;}
select[title="Playback order"] {width: 36%; max-width: 215px; min-width: 55px;}

/* now playing line */
#npd {border: solid gray 1px; position: relative; padding-right: 6em; white-space: pre-wrap; cursor: move;}
#np {position: absolute; left: 0; top: 0; bottom: 0; width: 0px; opacity: .50; background-color: #aaa;}
#track_title {font: bold 16px sans-serif; font-variant: small-caps; text-shadow: 0px 0px 10px #aaa; padding: 2px;}
#t_time {position: absolute; right: 2px; top: 2px; width: 6em; text-align: right;}

fieldset {margin-top : 10px; padding-top: 10px;}
a, a.current, a.current:hover { color: #555;}
a:hover {text-decoration: none;}

/* cover art */
img {width: 300px; height : 300px; magin-left: 150 px; border: solid #eaeaea 1px;}

/* playlist_pages */
#playlistpage { margin-top : 50px; font-size:12pt;}

/* playlist table */
table {border-collapse: collapse; margin-top: 0px;}
table td {padding: 2px 1px; }
tr.npr td {background: #ccc; color: black ;font-weight: bold;}
.playlist_time {border-top: 1px ; text-align: right;}
/* playlist entries highlight */
tr.o td {background: #000000;}     /* o(dd) */
tr.e td {background: #222222;}     /* e(ven) */
tr.prev td {border: 1px ;}  /* prev(iously played) */
tr.focus td {border: 1px ;} /* focus(ed) */
tr.queue td {background: #red;} /* queue(d) #ecebff */ 
td.t {text-align: right;}                /* t(otal time) */
td.q {text-align: right;}                /* q(ueue order) */



  
















Volume Level 10095908580757065605550454035302520151050 %

-->
StartEnqueueDequeueFocusDelete on click

SAC -->







First Previous 1 2 3 Next Last



<!--
with (document)
{
	act = 0;
	getElementById('Actions').selectedIndex = act;
if (1) { // start progressbar if playing
	t_playback_timer(0,0);
	if ((0>0))
		setTimeout('pc()',(0-0)*1000 + 500);
	getElementById('status').innerHTML = '[ Playing ? / 85 ]';
}
else if (0) { // adjust progressbar width if paused
	set_np_width(0, 0);
	set_t_pos(0);
	getElementById('status').innerHTML = '[ Paused ? / 85 ]';
} else { // hide unnecessary track info if stopped
	counter = getElementById("counter");
	if (counter)
		counter.innerHTML = "";
	getElementById("status").innerHTML = "[ Stopped ]";
	getElementById("npd").style.visibility = "hidden";
}

if (0 ) {
	getElementById('status').innerHTML = '[ Enqueuement in progress ] ' + getElementById('status').innerHTML;
	setTimeout('pc()',5000);
}

track = getElementById("track_title");

if (track && track.innerHTML == '' && (1 || 0)) // if playing but track info is not loaded yet, reload page
	setTimeout('pc()',500);

npp = getElementById("np");	// adjust progressbar width and height, and opacity hack for IE6
if (npp)
with (npp.style) {
//	if (getElementById("np").offsetHeight >= 2 )
//		height=getElementById("np").offsetHeight*2-2+"px";
//	left=getElementById("npd").offsetLeft+"px";
	filter = "alpha(opacity=50)";
}
}
//-->


Pink Floyd [Wish You Were Here] 02-Welcome To The Machine7:27Pink Floyd [Wish You Were Here] 03-Have A Cigar5:08Pink Floyd [Wish You Were Here] 04-Wish You Were Here5:40Pink Floyd [Wish You Were Here] 05-Shine On You Crazy Diamond [Part Two]12:23Led Zeppelin [Led Zeppelin CD01] 01-Good Times Bad Times2:47Led Zeppelin [Led Zeppelin CD01] 02-Babe I'm Gonna Leave You6:43Led Zeppelin [Led Zeppelin CD01] 03-You Shook Me6:28Led Zeppelin [Led Zeppelin CD01] 04-Dazed And Confused6:29Led Zeppelin [Led Zeppelin CD01] 05-Your Time Is Gonna Come4:35Led Zeppelin [Led Zeppelin CD01] 06-Black Mountain Side2:13Led Zeppelin [Led Zeppelin CD01] 07-Communication Breakdown2:30Led Zeppelin [Led Zeppelin CD01] 08-I Can't Quit You Baby4:43Led Zeppelin [Led Zeppelin CD01] 09-How Many More Times8:30Martin Dupont [Lost And Late...] 01-Just Because 1985 Remix4:41Martin Dupont [Lost And Late...] 02-No Hands1:43Martin Dupont [Lost And Late...] 03-Wagui3:03Martin Dupont [Lost And Late...] 04-I Love The Lovers3:19Martin Dupont [Lost And Late...] 05-Other Souvenir3:06Martin Dupont [Lost And Late...] 06-Your Passion3:44Martin Dupont [Lost And Late...] 07-Shake Your Flowers2:47Martin Dupont [Lost And Late...] 08-Without Face5:42Martin Dupont [Lost And Late...] 09-Its No Use3:49Martin Dupont [Lost And Late...] 10-Lost And Late3:02Martin Dupont [Lost And Late...] 11-Just Because4:59A Flock Of Seagulls [A Flock Of Seagulls] 01-Modern Love Is Automatic3:49A Flock Of Seagulls [A Flock Of Seagulls] 02-Messages2:52A Flock Of Seagulls [A Flock Of Seagulls] 03-I Ran5:06A Flock Of Seagulls [A Flock Of Seagulls] 04-Space Age Love Song3:47A Flock Of Seagulls [A Flock Of Seagulls] 05-You Can Run4:26A Flock Of Seagulls [A Flock Of Seagulls] 06-Telecommunication2:32
 6:30:27








"

Werden die Cover nicht auch angezeigt? Zumindest bei
https://bitbucket.org/oblikoamorale/foo_httpcontrol/wiki/Home
ist doch ein Cover abgebildet und das Theme sieht doch so aus wie das
Foobar über IPS steuern - Seite 2
was ich hier gepostet hatte oder?

Und das passende Template in der die Datei enthalten ist besitzt Du nicht?

:rolleyes: So wie es in der Anleitung steht

Also


<?  
// param1=volume level, 0...100
$volume = volume(50);  
 var_dump($volume);  
   
 function volume($vol)  
 {  
     $command = "Volume";  
    $payload = "http://192.168.178.20:8888/ajquery/?cmd=".$command."&param1=".$vol; // Command ergänzen  
    $volume = file_get_contents ($payload);  
    return $volume;  
 }  
?>

denk ich mal, probier es aus.

Und das passende Template in der die Datei enthalten ist besitzt Du nicht?

In dem Template „ajquery“ ist die Datei nicht dabei, im Gegensatz zu anderen Templates.

Werden die Cover nicht auch angezeigt?

Wenn ich in NEO das ganze als Webseitenelement darstelle, ist auch das Cover dabei. Ich dachte wenn ich in NEO einzelne Button etc. anlege, könnte ich auch eventuell das Cover anzeigen lassen. Im Prinzip dachte ich wie das anzeigen des Picons von Enigma2. Ist ja im Prinzip das gleiche, nur das die Cover in den einzelnen Ordner liegen.

Also in IP-Symcon legst Du einfach ein Dummy Modul an und darunter eine String Variable mit dem Profil ~HTMLBox.


Dann beschreibst Du die Variable mit dem Inhalt mit einem Skript.


<?

 $varidremote = 51931 /*[Geräte\Heimkino\Audio\Foobar\Foobar\Remote]*/; //Remote Var (String),Profile ~HTMLBox
 $content = '<iframe src="http://192.168.178.20:8888/ajquery/index.html" border="0" frameborder="0" style="top:0pt; bottom:0pt; left:0pt; right:0pt; width:100%; height:600px "/></iframe>';
 SetValue($varidremote, $content);

?>

Sieht dann im Webfront bzw. NEO oder IPS View so aus


Jetzt musst Du Dir halt nur noch ein Template auswählen was Dir gefällt. Die Befehle kannst Du ja anscheinend auch von IP-Symcon absetzten. An das Cover kommt man bestimmt auch wenn das das Javascript auslesen kann dann geht das auch mit PHP dazu müsstest Du Dir dann die Mühe machen und die den Javascript Code näher anschauen wie das Cover genau geladen wird.

Jetzt musst Du Dir halt nur noch ein Template auswählen was Dir gefällt. Die Befehle kannst Du ja anscheinend auch von IP-Symcon absetzten.

Das ist das Problem, es gefällt mir wirklich keins bzw. es werden nicht die Zusatz Tags übermittelt die ich benötige um z.B. die Alben auseinander zu halten.:smiley:

An das Cover kommt man bestimmt auch wenn das das Javascript auslesen kann dann geht das auch mit PHP dazu müsstest Du Dir dann die Mühe machen und die den Javascript Code näher anschauen wie das Cover genau geladen wird.

…machst du Witze mit mir?:D:confused::smiley:

Sieht dann im Webfront bzw. NEO oder IPS View so aus

Ich denke mal das ich das Webfront nicht benutzen werde und alles über NEO machen möchte.

Edit:

ajquery template configuration file
; 
; check readme.txt for usage details
;
[foo_httpcontrol]
url=/index.html
; defines formatting of a playlist row using foobar2000 titleformatting.
playlist_row={"a":"$fix_eol($replace(%artist%,\,\\,",\"))","b":"$fix_eol($replace(%album%,\,\\,",\"))","n":"$if(%queue_indexes%,'('%queue_indexes%') ',)$ifgreater(%totaldiscs%,1,D%discnumber%.,)%tracknumber%","t":"$fix_eol($replace(%title%,\,\\,",\"))","l":"%length%","ls":"%length_seconds%","d":"%date%"}
; defines formatting of a helper macros using foobar2000 titleformatting.
helper1=[%title% - ]
helper2=[%artist% - %title%]
helper3=[%codec% | %bitrate%kbps | %samplerate%Hz | %channels%]
; specifies wildcards where we should look for albumart files, separated by |. foobar2000 titleformatting is available there as well.
albumart=$directory_path(%path%)\folder.jpg|$directory_path(%path%)\*.jpg
; specifies path of a picture to show when albumart is not found.
albumart_not_found=ajquery/img/icon1rx.png
; specifies path of a picture to show when albumart is requested but not currently available (no playing track).
albumart_not_available=ajquery/img/icon1rx.png
; limits maximum albumart size to download, in bytes.
albumart_limit_size=0
; setting to 1 prefers embedded albumart over external.
albumart_prefer_embedded=0
; controls size of a playlist 'page'. setting to 0 completely disables playlist generation.
playlist_items_per_page=30

Nein kein Witz, ist nur so das Du eben entweder auf ein fertiges Template zurückgreifen musst oder aber Dir tatsächlich die Mühe machen musst Dir selber etwas zu basteln was Dir dann auch genügt. Ich persönlich würde mir die Arbeit nicht machen wollen.
Wenn die Sachen die Du benötigst sowieso nicht angezeigt werden sind wir wieder beim Thema warum nimmst Du nicht einfach Kodi oder Plex.

Das Cover liegt im Übrigen auch im Ordner die Frage wäre nur wie bekommt man den Namen raus dann kannst Du das auch in IP-Symcon laden

http://192.168.55.10:8888/ajquery/albumart_21054.jpg

Wenn die Sachen die Du benötigst sowieso nicht angezeigt werden sind wir wieder beim Thema warum nimmst Du nicht einfach Kodi oder Plex.

Das kann man einstellen welche Tags man gerne hätte, ist aber wiederum Template abhängig. Ich kann im ajquery Template in der config die Anzeige die unten steht „Playing 5 of 10…“ kann ich erweitern, was ich probiert habe. In meinem Fall habe ich den Tag %composer% hinzugefügt. Problem steht darin der Platz ist begrenzt.

Irgendwo hab ich hier noch ein Fehler drin. Es gibt ja 7 verschiedene Funktionen und er schaltet nach dem ausführen immer auf Default, also 0

<?   
// param1=param1=order number, from 0 to 7 
$playbackorder = playbackorder(3);   
 var_dump($playbackorder);   
    
 function playbackorder()   
 {   
     $command = "PlaybackOrder";   
    $payload = "http://192.168.178.20:8888/vairulez/?cmd=".$command."&param1="; // Command ergänzen   
    $playbackorder = file_get_contents ($payload);   
    return $playbackorder;   
 }   
?>

Das ist nicht weiter verwunderlich denn Du übergibst gar keinen Wert an die Funktion und hast auch auch keine Variable mit dem Wert in die Übergabe eingebaut.

Lies Dir mal den Grundsatz zu Funktionen durch
Eigene Funktionen in PHP
dann wirst Du auch den Fehler finden.

So sollte es wohl richtig aussehen

<?   
// Default (0), Repeat (Playlist), Repeat (Track), Random, Shuffle (tracks), Shuffle (Albums), Shuffle (Folders) (7). 
$playbackorder = playbackorder(3);   
 var_dump($playbackorder);   
    
 function playbackorder($order)   
 {   
     $command = "PlaybackOrder";   
    $payload = "http://192.168.178.20:8888/vairulez/?cmd=".$command."&param1=".$order; // Command ergänzen   
    $playbackorder = file_get_contents ($payload);   
    return $playbackorder;   
 }   
?>

ob das funktioniert kannst nur Du testen.

Hat funktioniert. Habe mir mal deinen Link zu Funktionen angeschaut und schaue mir gerade ein Lernvideo von V2B an.

Das ist jetzt schon mal ein Problem das ich habe. Ich kann das nicht „heraus“ lesen z.B. woher weiß ich das ich „order“ nehmen muss? Besagt das diese Zeile?

param1=order number, from 0 to 7

Dann wäre es bei dieser Zeile folgender Code?

param1=item indexes separated by any delitemeter

<?    
// Put active playlist items to playback queue.  
$queueitems = queueitems(1);    
 var_dump($queueitems);    
     
 function queueitems($item)    
 {    
     $command = "QueueItems";    
    $payload = "http://192.168.178.20:8888/vairulez/?cmd=".$command."&param1=".$item; // Command ergänzen    
    $queueitems = file_get_contents ($payload);    
    return $queueitems;    
 }    
?> 

Wie Du eine Variable benennst ist Dir überlassen Du musst nur darauf achten das dies dann konsistent ist ob Du die Variable also $item, $Item, $ITEM oder $Schurtzelpups nennst ist egal Du musst dann nur immer wieder die gleiche Bezeichnung für die Variable wählen, also Groß und Kleinschreibung beachten.
Keine Ahnung was ein „delitemeter“ sein soll wahrscheinlich ist delimiter gemeint das wäre ein Trennzeichen. Dann wäre das ganze aber ein Array
PHP Array
Array Manual
was ja auch Sinn macht da es ja eine Queue ist.
Also dann wäre


$item = array(1,2,3,4,7); // Titel 1,2,3,4,7

Da es sich ja um eine http URL handelt ist mir aber unklar wie jetzt dieser Array übergeben werden soll weil in der Doku steht ja nur separated by any delimiter. Das ist wie Rätselraten. Den Array kannst Du so zumindest nicht in der URL übergeben. Also kannst Du da wohl nur probieren was funktioniert z.B.


$item = "1.2.3.4.5";

so lange die Dokumentation da nicht eindeutig ist ist das heiteres Raten.

Da in der Doku ja nun gar nichst steht kannst Du das ausprobieren oder versuchen den Array als JSON zu übergeben oder aber urlencoded

$item = array(1,2,3,4,7);
 var_dump($item);
 $itemjson = json_encode($item);
 var_dump($itemjson);
 $itemurlencoded = urlencode($itemjson);
var_dump($itemurlencoded);

@Fonzo
gibt es mittlerweile eine andere Möglichkeit aus NEO/IPS eine externe App zu starten? Leider unterstützt die App nicht URL Schemes.

Mit Apps kenne ich mich nicht so gut aus und wenn dann nur mit IOS. Auf Android geht das vielleicht mit Tasker. Frage doch mal im Unterforum Mobile IOS Android ob da jemand weis wie man fremde Apps starten kann. Wie heisst die App denn die Du starten willst?

Danke, werde mal da nachfragen. Die App wäre FoobarCon Pro.

https://play.google.com/store/apps/details?id=com.wan.foobarconpro&hl=de

Die App
Monkeymote
lässt sich über ein URL Scheme starten eventuell ist da ja noch eine Alternative.

Danke für den Tipp. Hatte ich mir schon mal vor ein paar Jahren angeschaut.

Wie wird das den gehandhabt wenn ich von der App wieder in meine NEO Oberfläche zurück möchte?

Edit: Habe gerade gelesen das man speziell Android Apps mit dem Paketnamen aufrufen könnte, das wäre in meinem Fall bei der FoobarCon App: com.wan.foobarconpro&hl=de
Aber damit kann NEO bestimmt auch nichts anfangen. Werde mal im Mobile Forum schreiben.

Was hast Du denn Android oder iOS? Monkeymote würde z.B. mit mmotefoo:// gestartet werden. Zu NEO oder jeder anderen App kommt man bei iOS zurück wenn man oben in der durch das URL Scheme aufgerufene App zurück drückt.

Ich hätte beides IOS oder Android. Bei der FoobarCon App geht leider nur Android. Aber ich schau mir das mal an.

Habe mir mal MonkeyMote installiert, bekomme die App aber aus NEO nicht geöffnet.

HTTP Request senden -> mmotefoo://

Passiert denn was wenn Du in Safari mmotefoo:// eingibst? Ansonsten ist eventuell das URL Schema geändert worden.