commit b7aa7e0ca27c5a7adbb72edb761880fa2afa61db
Author: Alex Balgavy <a.balgavy@gmail.com>
Date: Tue, 6 Oct 2020 11:01:28 +0200
Initial commit
Diffstat:
A | README.md | | | 5 | +++++ |
A | radio | | | 116 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | urls | | | 19 | +++++++++++++++++++ |
3 files changed, 140 insertions(+), 0 deletions(-)
diff --git a/README.md b/README.md
@@ -0,0 +1,5 @@
+# radio: a command line radio player
+
+Requires Ruby, and uses [mpv](https://mpv.io) as a backend.
+Radio channels are defined in \$HOME/.config/urls, see [urls](./urls) for an example.
+The file uses the standard conf syntax.
diff --git a/radio b/radio
@@ -0,0 +1,116 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+class Subreddit
+ require 'json'
+ require 'open-uri'
+
+ def initialize(name)
+ @url = "https://www.reddit.com/r/#{name}/top.json?t=week&limit=100&show=all"
+ begin
+ URI.open(@url, 'User-Agent' => 'ruby/2.7', 'Accept' => 'application/json') do |response|
+ data = JSON.parse(response.read)['data']
+ @posts = data['children']
+ end
+ rescue OpenURI::HTTPError
+ @posts = []
+ end
+ end
+
+ def posts?
+ !@posts.empty?
+ end
+
+ def play
+ mpv_options = '--no-video --volume=50'
+ links = []
+ @posts.each do |post|
+ p = post['data']
+ if !p['is_self'] && p['post_hint'] != 'image'
+ links.append(title: p['title'], url: p['url'], reddit: "https://reddit.com#{p['permalink']}")
+ end
+ end
+
+ begin
+ puts "Number of tracks: #{links.length}"
+ links.each do |link|
+ puts "\n-----\n"
+ puts "# #{link[:title]}"
+ puts "Reddit: #{link[:reddit]}"
+ puts '(press q to skip, ^C to stop)'
+ puts "Cannot play #{link[:url]}" unless system("mpv #{mpv_options} '#{link[:url]}'")
+ end
+ rescue Interrupt
+ true
+ end
+ end
+end
+
+class Radio
+ CONFIG_FILE = "#{ENV['HOME']}/.config/radio/urls"
+ SUBREDDIT_CHANNEL = 'Play from music subreddit'
+ def initialize
+ unless system('command -v mpv 1>/dev/null 2>&1')
+ warn 'mpv not installed.'
+ exit 1
+ end
+ unless File.exist? "#{ENV['HOME']}/.config/radio/urls"
+ warn "Please set URLs in #{ENV['HOME']}/.config/radio/urls."
+ exit 1
+ end
+ @channels = {}
+ File.open(CONFIG_FILE, 'r').each do |line|
+ unless line.match?(/^\s*\#/)
+ parts = line.chomp.split(/(?<=")\s+(?=http)/)
+ @channels[parts.first.gsub('"', '')] = parts.last
+ end
+ end
+ @channels[SUBREDDIT_CHANNEL] = SUBREDDIT_CHANNEL
+ end
+
+ def select
+ puts "\e[H\e[2J"
+ channel_names = @channels.keys
+ user_selection = false
+ begin
+ until user_selection
+ channel_names.each_with_index do |name, i|
+ puts "#{i + 1}: #{name}"
+ end
+ print 'Enter number or press ^C to exit> '
+ user_selection = (Integer(gets) - 1) rescue false
+ if user_selection && !@channels[channel_names[user_selection]]
+ puts 'Invalid selection, please try again.'
+ user_selection = false
+ end
+ end
+ @channels[channel_names[user_selection]]
+ rescue Interrupt
+ nil
+ end
+ end
+
+ def play(selection)
+ if selection == SUBREDDIT_CHANNEL
+ print 'Enter subreddit name: '
+ sub = Subreddit.new(gets.chomp)
+ until sub.posts?
+ puts 'Subreddit has no music posts or does not exist.'
+ print 'Enter subreddit name: '
+ sub = Subreddit.new(gets.chomp)
+ end
+ sub.play
+ else
+ puts "\e[H\e[2J"
+ puts "Loading #{selection}..."
+ system 'mpv', selection, '--volume=50'
+ # visualiser: system 'mpv', selection, '--volume=50 --script="$HOME/.config/mpv/visualizer.lua" --really-quiet -vo caca'
+ end
+ end
+end
+
+radio = Radio.new
+while (selection = radio.select)
+ result = radio.play selection
+ puts "Error playing #{selection}" unless result
+end
diff --git a/urls b/urls
@@ -0,0 +1,19 @@
+"Nightride FM" https://nightride.fm/stream/nightride.m4a
+"Nightwave Plaza" https://plaza.one/mp3
+"6forty" http://54.173.171.80:8000/6forty
+"Fnoob Techno" http://play.fnoobtechno.com:2199/tunein/fnoobtechno320.pls
+
+# Psystation
+"Psystation: Classic Goa" http://hestia2.cdnstream.com/1458_128
+"Psystation: Prog Psytrance" http://hestia2.cdnstream.com/1453_128
+
+# Soma FM
+"SOMA - Groove Salad (ambient/downtempo)" https://somafm.com/groovesalad256.pls
+"SOMA - Mission Control (ambient, space)" https://somafm.com/missioncontrol.pls
+"SOMA - The Trip (prog house/trance)" https://somafm.com/thetrip.pls
+"SOMA - Beat Blender (deep house, downtempo)" https://somafm.com/beatblender.pls
+"SOMA - Dub Step" https://somafm.com/dubstep256.pls
+"SOMA - Defcon" https://somafm.com/defcon256.pls
+"SOMA - Deep Space (deep ambient electro/experimental)" https://somafm.com/deepspaceone.pls
+"SOMA - Thistle Radio (Celtic)" https://somafm.com/thistle.pls
+"SOMA - Fluid (instr. hip hop, liquid trap" https://somafm.com/fluid.pls