How to display 'song title, artist' in another web page?


#1

I have mopidy 2.0 running on Rpi 3. I also have a MagicMirror running on Apache2 on the same Rpi 3 concurrently. Both work well together.

I need help in getting the ‘song title and artist’ pulled from mopidy and displayed on the MagicMirror web page. And Yes, I have read the Docs. But I’m not a programmer.

  1. How would I access mopidy.js?
  2. What files would I need to include on the MagicMirror html page?
  3. I have api_explorer loaded. Were/how to use :slight_smile:JavaScript

mopidy.tracklist.slice({“start”:null,“end”:null}).then(function(data){
console.log(data);
});

to display:
Events
Here you can see events arriving from Mopidy in real time:

10:14:29 PM: {“event”: “stream_title_changed”, “title”: “Beatles - Come Together”}

I have looked at many HTTP frontend extension and websockets. But I’m not a coder.
A friend gave me this outline as to how to code, but I am lost.

(function updateMusic()
{
// Get info from Mopidy here

  var muscInfoString;
  // Populate musicInfoString with HTML here
  // Update the div
  $('.music').updateWithText( musicInfoString );
  // Call this function again in 5 seconds
  setTimeout( updateMusic, 5000 );

} ();

You can do some optimizations, like detecting if musicInfoString has changed or not and only updating the div when it has, so that the UI doesn’t update unnecessarily.

Instead of polling, you could also use the events mechanism in that Mopidy Javascript you found so that you can be told when to update. That’s much more efficient, but a slightly different approach. You’d set up a function that is called once on startup (meaning, you skip the setTimeout() bit) to register the event handlers. When one of them is called, it updates the div.

Sorry for the long post.
Thanks in advance for reading.

Old retired guy.
Joe


Web ui to display current playing track
#2

I made a little working example so you can use it to get started.

<!DOCTYPE html>
<html>

<head>

<!-- Load mopidy.js (Related to your first question) -->
<script type="text/javascript" src="http://localhost:6680/mopidy/mopidy.js"></script>

<script type="text/javascript">

	// This function will be called when a track playback is started
	function updateText(data){

		// Show what contains the data on the console
		console.log(data)

		// Get the track from the data
		var track = data.tl_track.track;
	
		// Get the track name and album name
		var trackName = track.name;
		var albumName = track.album.name;

		// A song can have more than one artist so we will iterate all the artists
		var artists = "";
		for (var i=0; i<track.artists.length; i++){
			// Add the current artist name to artists
			artists += track.artists[i].name;
		}
		
		// Get the HTML elements and update their content
		document.getElementById("track_name").innerHTML = trackName;
		document.getElementById("album_name").innerHTML = albumName;
		document.getElementById("artist_name").innerHTML = artists;
	}

	// Init the object
	var mopidy = new Mopidy();

	// We set that when the event:trackPlaybackStarted is fired updateText mehtod will be executed
	mopidy.on("event:trackPlaybackStarted", updateText);
	
</script>
</head>
<body>

<!-- Containers to show the data -->
<span id="track_name"></span><br>
<span id="album_name"></span><br>
<span id="artist_name"></span>

</body>
</html>

I have never used MagicMirror but You should probably edit index.php.


#3

Thanks for taking the time to help! Much Appreciated!

I copy and pasted the ‘working example’ into the dir MagicMirror and gave it the title ‘song.html’. When I pointed the browser to 192.168.1.94/MagicMirror/song.html all I got was a blank page. I must be missing something simple.
I did change ‘localhost’ to the IP: 192.168.1.94 same results - no data. I must have made a simple error, but how do I fix it?

Joe


#4

Note that the script is very simple. When you enter the page you will see a blank page and nothing will be displayed. You have to change the song (this way mopidy will send the ‘event:trackPlaybackStarted’ with the new song info) while the page is open to get the song shown on the page.

You mentioned that you changed the ip. If the browser you are accessing the page is on the same raspberry pi as mopidy localhost should work fine but if you are browsing to the page from another device you will have to change the ip.
To change it apart from changing the localhost on the script (as you already did) you must also make the following change:

replace

var mopidy = new Mopidy();

to

var mopidy = new Mopidy({webSocketUrl: "ws://192.168.1.94:6680/mopidy/ws/"});

You should also check if mopidy allows the connection from that ip (mopidy only allows localhost by default).

As a suggestion use your browser console to check what errors are happening. In chrome you can open it pressing ctrl+shift+j


#5

Thanks for the updates. Still no data shows. Yes, the songs have been playing all afternoon. ( my wife wonders when I am going to get things done around the house, too :wink: )

I opened the Chrome console = no errors.

Not sure if I did this correctly, but tried to add Watch:
updateText: updateText(data)
console.log: log()
track_name: span#track_name

Changed songs: no data
Refreshed the Watch: no data

song.remote.html





++++++++++++++++++++++++++++++++++

Mopidy.conf ( I used 0.0.0.0 instead of 127.0.0.1 as I could not get mopidy to start with 127.0.0.1)

[http]
enabled = true
hostname = 0.0.0.0
port = 6680
static_dir =
zeroconf = Mopidy HTTP server on $hostname

Thanks -
Joe


#6

The two lines that instantiate the Mopidy object and then register your function to be called on the Mopidy event should not be part of your function. Those two lines should be outside of your function so that they actually execute.

In future please paste the code rather than images of it as then people can reference line numbers and even copy and paste you a complete solution.


#7

Thank you! That fixed the display problem! The page only refreshes if I manually change the song via my phone app.

What code would I need to update the streaming info? or to display changes as this code does:

mopidy.tracklist.slice({“start”:null,“end”:null}).then(function(data){
console.log(data);
});

As in the Mopidy HTTP API frontend Event:

11:15:32 AM: {“event”: “stream_title_changed”, “title”: “Petula Clark - This Is My Song”}
11:14:12 AM: {“event”: “stream_title_changed”, “title”: “Leslie Gore - Judy’s Turn to Cry”}
11:13:38 AM: {“tl_track”: {“track”: {“album”: {“images”: [“http://cdn-radiotime-logos.tunein.com/s234015q.png”], “model”: “Album”, “name”: “60’s Pop (US)”, “uri”: “tunein:station:s234017”}, “model”: “Track”, “artists”: [{“model”: “Artist”, “name”: “60’s Pop (US)”, “uri”: “tunein:station:s234017”}], “name”: “Lesley Gore - Judy’s Turn to Cry”, “uri”: “tunein:station:s234017”}, “model”: “TlTrack”, “tlid”: 25}, “event”: “track_playback_started”}
11:13:37 AM: {“old_state”: “playing”, “new_state”: “playing”, “event”: “playback_state_changed”}
11:13:37 AM: {“time_position”: 0, “tl_track”: {“track”: {“album”: {“images”: [“http://cdn-radiotime-logos.tunein.com/s48937q.png”], “model”: “Album”, “name”: “.977 50s, 60s Hits (US)”, “uri”: “tunein:station:s89816”}, “model”: “Track”, “artists”: [{“model”: “Artist”, “name”: “.977 50s, 60s Hits (US)”, “uri”: “tunein:station:s89816”}], “name”: “Peter & Gordon - I Dont Want To See You Again”, “uri”: “tunein:station:s89816”}, “model”: “TlTrack”, “tlid”: 24}, “event”: “track_playback_ended”}
11:13:37 AM: {“volume”: 46, “event”: “volume_changed”}
11:13:35 AM: {“event”: “tracklist_changed”}
11:12:04 AM: {“event”: “stream_title_changed”, “title”: “Lou Christie - Two Faces Have I”}

Yes, I just signed up for Pastebin.


#8

One more question. Is there a way to have the Song Title, Artists update on
change? I tried mopidy.on(“event:trackPlaybackChanged”, updateText);

But that didn’t work. Is there more code to add?

Thanks,
Joe


#9

Thanks 9and3r and kingosticks,

Your example works. My question is:

  1. is it suppose to update the song album, title, and artists every time the song changes?
    2 it only updates when I change the song on my phone app.
  2. updates are from TuneIn radio stations.

I’m not sure how to use Pastebin

I have mangled your code to work with my MagicMirror code (Index.php) by adding this file mm-music.js

I just need the song information to update when a song changes. (station plays the next song, no user intervention. )

I can see the song information update in the browser console window, but don’t know how to update the information in Index.php Just the first song displays.
Thanks.

ScreenShot:


#10

Yes except in the case of radio stations. The trackPlaybackStarted event will be executed anytime a new track starts playing. Probably your problem is related that you are using radio stations. In Mopidy each radio station seems to be a track so when the station changes the song, there is no trackPlaybackStarted event, instead of this the streamTitleChanged event is executed as you can see in the HTTP API frontend:

To fix this you have to listen also to this event and update the title. This is the updated code:

<!DOCTYPE html>
<html>

<head>
<script type="text/javascript" src="http://localhost:6680/mopidy/mopidy.js"></script>
<script type="text/javascript">

	// This function will be called when a track playback is started
	function updateText(data){

		// Show what contains the data on the console
		console.log(data)

		// Get the track from the data
		var track = data.tl_track.track;
	
		// Get the track name and album name
		var trackName = track.name;
		var albumName = track.album.name;

		// A song can have more than one artist so we will iterate all the artists
		var artists = "";
		for (var i=0; i<track.artists.length; i++){
			// Add the current artist name to artists
			artists += track.artists[i].name;
		}
		
		// Get the HTML elements and update their content
		document.getElementById("track_name").innerHTML = trackName;
		document.getElementById("album_name").innerHTML = albumName;
		document.getElementById("artist_name").innerHTML = artists;
	}

	function updateTitle(data){
		document.getElementById("track_name").innerHTML = data.title;
	}

	// Init the object
	var mopidy = new Mopidy({webSocketUrl: "ws://localhost:6680/mopidy/ws/"});

	// We set that when the event:trackPlaybackStarted is fired updateText mehtod will be executed
	mopidy.on("event:trackPlaybackStarted", updateText);
	mopidy.on("event:streamTitleChanged", updateTitle);
	
</script>
</head>
<body>

<!-- Containers to show the data -->
<span id="track_name"></span><br>
<span id="album_name"></span><br>
<span id="artist_name"></span>

</body>
</html>

#11

All is working now thanks to @9and3r!

This year’s question: Is it possible to use a variable instead of the actual ip address? I can use this code in my index.php to obtain the ip address. ( lines 1-3) and use the variable $localIP to replace the ip address in line #19.
see this ip_code_test.php

But I don’t understand how/if I can pass the variable $localIP to the javascript program - mm-music.js
Lines 1-3 are illegal in JS. But is there a method to pass $localIP to line # 10?

Thanks in advance.

Joe