~akstuhl/tuner

878febcc22d727bd90dbaa89c37af0cfc0f3a100 — Andy Stuhl 2 years ago 00b57e4
rename script file and add readme
2 files changed, 49 insertions(+), 1 deletions(-)

A README.md
R main.py => tuner.py
A README.md => README.md +48 -0
@@ 0,0 1,48 @@
## A tuner script

#### Installation

Requires [pipenv](https://pipenv.pypa.io/en/latest/#install-pipenv-today) and [mpv](https://mpv.io/installation/)

```
git clone https://git.sr.ht/~akstuhl/tuner
cd tuner
pipenv install
```

#### Usage

```
pipenv run python tuner.py [--fallback http://example.com/audiostream.mp3] http://example.com/radio.ics
```

### How to use

1. Find a radio show (or bandcamp album, mp3 file, etc. -- see listening queue section below) you'd like to tune in to when it's on.
2. Make an event for the show in a web calendar (e.g. Google calendar). Find a streaming audio URL where you can listen to the show and paste that URL into the event's `location` field.
3. Copy your calendar's .ics URL (for a Google calendar, go to the calendar's settings and look under "Integrate calendar" for an "address in iCal format" field).
4. To start playing audio, paste your .ics URL as an argument to the script in your terminal: `pipenv python tuner.py <your-URL-here>`

### What it does

This is a listening helper that prioritizes tuning in to weekly radio shows via internet radio streams. If you add these shows as repeating events to a web calendar that publishes an iCalendar (.ics) endpoint, for instance a Google calendar, then this script can retrieve them and switch between the streams according to schedule. [Here's mine](https://calendar.google.com/calendar/u/0?cid=YWJkOTY0YThiOTQ1MDBkZjNjNWI1ZTIwYzdjNjRlNmU3YTM4NTY1ODZlNWNjNDFkODZmOTYzNWVhZmM0MTgyNUBncm91cC5jYWxlbmRhci5nb29nbGUuY29t), for example.

#### Listening queue

When nothing is found on the schedule at the current time, the script will rotate through a set of calendar entries it identifies as listening queue items rather than scheduled shows. For now, the way I designate queue items is very inelegant: in Google calendar, create an all-day event and set it to repeat daily, putting the URL in its `location` field as usual (if your mpv installation supports youtube-dl, a surprising number of URL sources including Bandcamp and Mixcloud pages should work) -- in the iCalendar format, Google will mark an all-day event as "transparent," and the script interprets that to mean queue item. Simply delete the recurring event to remove its queue item. 

#### Alternate uses

This script tries to do as little as possible in passing URLs from the iCalendar file through to the mpv player. While I wrote it with just audio in mind, there are no guard rails against queuing video sources; or, for that matter, experimenting with calendar event settings in between or outside the envisioned "weekly show / listening queue" dichotomy. Just keep in mind it's untested for any of that.

### Why

This is a little tool I wrote for myself with the primary goal of catching weekly radio shows that friends produce or that I'm otherwise interested in. The secondary goal was to have a one-click way to start playing interesting audio when I have a moment to listen and don't want to spend time thinking about what to put on. Now I add things to my radio calendar when I hear about them and, when the timing works out, catch them by listening through the tuner script.

### What else

Additions might include:

- Support iCalendar's `VTODO` record type for listening queue entries (Google and other web calendar services don't support this, but it would be internally much more elegant)
- Set up or find a directory of station stream URLs so the full URL doesn't need to be entered into each event's `location` every time
- A helper, probably as a separate tool, for adding shows and queue items via CalDAV or (more likely) via an .ics file that gets published within a static (Jekyll) site

R main.py => tuner.py +1 -1
@@ 13,7 13,7 @@ parser.add_argument('--fallback', dest='fallback_url', action='store', help='A f

args = parser.parse_args()
fallback_url = args.fallback_url
ical_url = args.ical_url
ical_url = args.ical_url # TODO store last used ical url in a local file for convenience?

# convenience function for working with icalendar library's vText format
def get_text(e, k):