Huffduffer Radiodan

Update: a step by step how-to is now available.

I’ve been wanting a physical radio that plays podcasts for a long time, and it’s something we’ve discussed quite a lot in the Radiodan team. There’s no real reason why not – Radiodan plays MP3s because it uses MPD. and I occasionally talk about a ‘Cambrian explosion’ of radios – we think that Radiodan will be able to let us quickly try out new ideas like this one.

So I want to do something very quickly – 1 day out of my 10% time, and see how far I get.

I also want to use Richard Pope’s checklist for new projects – so these are my notes (Richard’s point 6). This post will therefore change and be added to as I go along.

Background

Radiodan is a radio experiences prototyping platform that we are using at work to show what radio could be like. It’s a Raspberry Pi in a nice box with custom software written in node.js to play audio internet streams and run a webserver to help you control it. There are also physical buttons and dials and some work around easily(ish) getting it on the wifi. The idea is to show what’s possible and test what’s sensible. It uses internet streams – not DAB or FM – because we can quickly show interesting things using streams only. We can make something that acts like a radio without building all the pieces.

Browsing around yesterday I re-found Huffduffer, a really nice service and site by @adactio that allows you to find audio files on the web and add them to a collection – and RSS feed – and also to follow other people, subscribe to RSS feeds from specific events. That seems like a perfect fit for a podcast Radiodan.

Checklist

Here are Richard Pope’s checklist items, which you should read in full:

1) Know your history.
2) Read the legislation.
3) Draw the thing
4) Understand the state of technology
5) Seek out metaphors.
6) Keep notes, share notes.
7) Keep a list of user needs.
8) Sketch in code.
9) Get a prototype in front of real users.
10) Throw your prototype away.

To add to that, my colleague Tristan’s written about types of prototyping – I need to work out what fidelity I need to make the prototype. Obviously I’d like something that actually works, but probably don’t have time for that.

Initial idea

  • A physical radio that plays podcasts like a radio station
  • maybe with some sort of RFID(?) interface that allows you to flip between different collections

Todo list

00. Start a product checklist
0. start with a standard radiodan, set it up and get it working
1. Fork the simple version of the radiodan client (there are two types of radio currently)
2. See if it’ll play an mp3 as a stream
3. Hardcode an RSS feed and display the result in the controller webpage
4. Try RFID to flip between different RSS feeds?
5. Invent a nice case
6. Document everything
7. Fin

Know your history

I’m doing a quick search for:

  • projects that are very similar (e.g. raspberry pi podcast players)
    • Podcast downloader/player – can I use Podget? nice list of features needed at a minimum, and interesting “WiFi dongle with an antenna to keep one device in my car”
  • podcast players in general (for interface issues)
  • List of Radiodan postcards for similar things
    • I think the closest is ChrisG’s radio, though there are several where podcasts are one element of a more complex radio.

For podcast players in general, I think it actually makes more sense to try some out, but not sure I have enough time, so going with my current experience:

I do use the one on my iphone, and it’s very annoying

  • it seems not to delete things and so the disk fills up
  • it constantly nags to be online
  • its sleep timer doesn’t work properly so sometimes I end up listening to in our time all night while asleep, which is weird

however:

  • it does mark new things as new, and listened to as listened to
  • it remembers where I am in the podcast (that seems pretty important)

2) Read the legislation

I hope / think I can skip this one. Vaguely related, here’s a note on Huffduffer’s terms of use.

3) Draw the thing

We have a Radiodan ‘process’ for some of this. Here’s my postcard:

huffduffer_radiodan

I think the checklist item is more general than that though:

“Aim for something that represents the totality of the service – a mental model for yourself, and something to help you explain it to others.”

huffduffer_radiodan_story

A few things came out of this

  • I don’t know whether I can stream the mp3s or need to schedule their downloads
  • I don’t know if I need a Radiodan web interface or not. That’s sort of interesting.
  • Forgot to draw the RFID bit

4) Understand the state of technology

“Spend time understanding the state of technology and design right now. Assume it has changed since you started your last project and that your knowledge is out of date.”
“Actively seek out ideas that you can steal to solve the problem at hand.”

The research part missing here was to do with how radios handle these kinds of problems. Here’s a quick bit of research:

5) Seek out metaphors.

Something like “your home-made radio station”.

6) Keep notes, share notes.

These are them. Though maybe I should have used github so I got version control.

7) Keep a list of user needs.

A few are emerging, I’m sure there are more:

  • Remembers where you are in a podcast
  • Some way of managing of podcasts (maybe just the Huffduffer site? does that make any sense?
  • Somehow you need to decide what goes on the radio, so assuming Huffduffer, that means either pairing to an account or some other way of telling it the RSS feed you’re interested in
  • Maybe: new podcast available?
  • Mark new items as new (how?)
  • Volume, on / off

8) Sketch in code.

I’ve been working for about two and a half hours, so on my self-imposed timetable I need to get moving to make something. I’m going to try and adapt one piece of the current Radiodan codebase – a very simple interface – to try and use it for podcasts. Radiodan can have different brains swapped in – a more complex one is the magic button radio – which is a more fully-featured radio experience, but also more complicated to hack on.

Maybe I need lunch first actually.

0. start with a standard radiodan, set it up and get it working

I’m cheating a bit here. I already have one I prepared earlier. The basic steps are outlined here:

  • download a card image (we need to make a new one)
  • put it on a pi
  • assemble the bits
  • turn it on
  • do the wifi dance to get it online
  • turn it on using the buttons or the web interface

Here’s mine with the back off so I can ssh to it over ethernet shared from my mac – typically wifi is slower for that kind of operation.

radiodan

Intermission – Catwigs

Catwigs are a project I’ve been working on with Richard Sewell. They’re a way of talking and thinking about your project to make sure you haven’t missed anything important. I forgot to do them for this project. One moment please….

catwigs_huffduffer_radiodan

Basically you shuffle the 22 cards, pick 7 and then decide their orientation based on your project, and then talk about how to improve the ones facing downwards.

For this project, I think it’s reasonably clear what it is, I hope to make it usable, though probably only averagely so, given my limited UX skills; it solves a problem for me (but not a terribly important problem, and it might be quite niche); I think it will generate ideas because physical prototypes often do; it should benefit people (it certainly won’t take anything away and might even increase the amount of knowledge in the world), and it’s in our best interests in order to test Radiodan. It won’t make us any money, but that’s ok.

Sketch in code (cont)

TODO: 1. Fork the simple version of the radiodan client (there are two types of radio currently)


# check the example type radiodan works
sudo radiodan-device-type radiodan-type-example
sudo reboot
# go to http://radiodan-libby.local
# play a stream (works)

# make a new device type
# clone my fork
cd /opt/radiodan/apps
sudo git clone https://github.com/libbymiller/client-web-example.git
sudo mv client-web-example client-huffduffer
cd client-huffduffer
sudo chown -R pi:pi .
# change repo name in the web interface (https://help.github.com/articles/renaming-a-repository/) and in the client:
sudo git remote set-url origin https://github.com/libbymiller/client-huffduffer
# make a little edit so that we know the right one is running
# e.g. in /opt/radiodan/apps/client-huffduffer/static/index.html
git add .
git commit -m "Small edits"
git push
npm install # this takes a few minutes. I had to remove references to avahi and mdns to make it work, but we don't need that for now.

# add to init.d
cd /etc/init.d/
sudo cp radiodan-example radiodan-huffduffer
# make appropriate edits, including this:
# DAEMON_OPTS="/opt/radiodan/apps/client-huffduffer/main.js"
# then
sudo pico radiodan-huffduffer
sudo chmod 755 /etc/init.d/radiodan-huffduffer
sudo update-rc.d radiodan-huffduffer defaults
sudo update-rc.d radiodan-huffduffer enable

# add to monit so we can switch between them
cd /etc/monit/monitrc.d/
sudo cp radiodan-type-example radiodan-type-huffduffer
# make edits to replace radiodan-example in that file

# now:
sudo radiodan-device-type
Current device type: radiodan-type-example
Device type required. Valid types radiodan-type-example, radiodan-type-huffduffer, radiodan-type-magic
sudo radiodan-device-type radiodan-type-huffduffer
sudo reboot

After a bit of fiddling that worked, so I now have a basic radiodan instance with an interface I can change, and it’s all in github.

Todo: 2. See if it’ll play an mp3 as a stream

If it does, that’s great, because I won’t have to download them, manage files etc, but just the metadata about them.

I can test that within the web interface (for me, http://radiodan-libby.local), and yes they do seem to play fine.

Next I want to see if I can play them programmatically.

The main guts of the functionality are in ./node_modules/radiodan-client/, the Radiodan client library installed as module. This converts commands to events in rabbitmq. The commands available are in ./static/js/playback-controls.js.

This makes things very straightforward indeed I think for a hardcoded RSS file:

a. when the app is started, get the hardcoded RSS file
b. add all the media files to the playlist
c. start playing the first one
d. is that it?

Obviously that won’t provide a away to remember where you were on restart, which will be very irritating, and nor will the buttons work (e.g. for next, previous), but it’s a start.

TODO: 3. Hardcode an RSS feed and display the result in the controller webpage


# First, stop monit monitoring radiodan-huffduffer:
sudo monit unmonitor radiodan-huffduffer

# then make some edits and test
/usr/local/bin/node /opt/radiodan/apps/client-huffduffer/main.js

The slightly confusing thing here is that node is really just running a tiny website – everything’s happening in client-side javascript, but we want to do this server-side, because chances are Huffduffer doesn’t do CORS for RSS and indeed I think it doesn’t):


curl -k -H "Origin: http://example.com" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: X-Requested-With" -X OPTIONS --head https://huffduffer.com/libbymiller/rss

Copying the similar file in the original code, I think the best thing is to create a little file that adds the rss feed data to the playlist like that.

….time passes…

I wasn’t able to make the player play from node.js – I couldn’t find an example that helped. I’ll try again at some point. You can see my attempts in git.

My second attempt used javascript, with a very simple proxy for my url, like this:


// proxy our one url
var request = require('request');
app.get('/rss', function(req,res) {
//modify the url in any way you want
var newurl = 'https://huffduffer.com/libbymiller/rss';
request(newurl).pipe(res);
});

Then it was just a matter of a small change to xjr.js:

function getRSS(url, success) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
var rss = xhr.responseText;
//console.log(rss);
var arr = rss.split("\n");
var urls = [];
for(var i =0; i< arr.length; i++){
var text = arr[i];
var m = text.match(/<enclosure url=\"(.*?)\"/);
if(m){
urls.push(m[1]);
}
}
console.log(urls);
success(urls);
};
xhr.send();
}

and then a call in app.js:


getRSS("/rss",function(urls){
console.log("ok");
console.log(urls);
if(urls && urls.length>0){
for (var i=0; i< urls.length; i++){
addToPlaylist(urls[i]);
}
play();
}else{
console.log("nothing to add to playlist");
}
});

and bingo.

It currently only works when the html page on the device is loaded. Not sure how to manage it with a button. There’s also no title or length, but maybe those can be passed somehow to it. But it plays!

I didn’t get to try the RFID reader, but you could also set the URL in the page for example.

That’s enough for today though – about 7 hours from start to finish – not bad.

One thought on “Huffduffer Radiodan

  1. Pingback: Huffduffer Radiodan part 2 – a switch | PlanB

Comments are closed.