Skip to content

Instantly share code, notes, and snippets.

@southrop
Forked from ybenjo/README.md
Last active November 6, 2017 06:21
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save southrop/745d7d383602fce791fd6843f0741e7b to your computer and use it in GitHub Desktop.
Save southrop/745d7d383602fce791fd6843f0741e7b to your computer and use it in GitHub Desktop.
save AGQR radio programs.

agqr.rb

What is this?

A script used to save radios broadcasted on AGQR.

Differences in this fork

Compared to ybenjo/agqr.rb:

  • Fixed the script to work if run on machines that operate on non-JST timezones
  • Fixed a bug in the folder creation part of the script which would cause the script to fail and not run
  • Changed the folder paths to be within the same directory as the script
  • Updated the dependencies to say Ruby 2.x or above, because __dir__ was only introduced in Ruby 2.0.0.

Usage

Put agqr.rb in a folder of your choice, then install a Cron job like this: 29,59 * * * * sleep 55; ruby agqr.rb

This causes Cron to execute this command at 29th and 59th minute of every hour, sleep for 55 seconds, then run agqr.rb. If there is something to record, then it should automatically start recording.

A note on cronjobs:

You may need to use absolute paths when specifying your ruby binary and the location of agqr.rb due to the fact that Cron executes with a different PATH compared to your normal shell. Alternatively, you can specify a custom PATH in your personal file.

See this AskUbuntu answer for more details).

The script automatically creates a structure like this upon first run:

├ rec
  ├ flv
  └ mp3

Downloaded .flv files are placed in rec/flv and the converted .mp3 files are in rec/mp3.

The default paths for rtmpdump and ffmpeg are based on what I have on my Ubuntu server, so feel free to overwrite those with your correct paths.

Dependencies

  • Ruby 2.x
  • rtmpdump
  • ffmpeg
  • cron

schedule.yaml

This is where you specify the shows you want to record.

To add a show, simply add a new entry to the file like this:

- title: title
  wday: 月
  time: '10:30'
  length: 30

The script supports time expressions like 26:00 (02:00 next day).

Weekday is specified via kanji for readability.

NOTE: Using spaces, ampersands, quotation marks, braces/brackets in the title may break the script.

# -*- coding: utf-8 -*-
# record AGQR
# usage: use with crontab
# 29,59 * * * sleep 55; ruby agqr.rb
# requirements
# crontab, ruby >~ 1.9, ffmpeg, rtmpdump
require 'yaml'
rtmpdump = '/usr/bin/rtmpdump'
ffmpeg = '/usr/bin/ffmpeg'
# If this ever stops working, check http://www.uniqueradio.jp/agplayerf/getfmsListHD.php for a new one
agqr_stream_url = 'rtmp://fms-base1.mitene.ad.jp/agqr/aandg22'
current = __dir__
save_dir = "#{current}/rec"
Dir.mkdir(save_dir) if !File.exist?(save_dir)
%w(mp3 flv).each do |dir|
path = save_dir + '/' + dir
Dir.mkdir(path) if !File.exist?(path)
end
schedule_yaml = "#{current}/schedule.yaml"
if !File.exist?(schedule_yaml)
puts "Config file (#{schedule_yaml}) is not found!"
puts "Please make #{schedule_yaml}."
exit 1
end
today = Time.now.getlocal("+09:00")
# ruby 1.9.x でも動くために汚いけど書き換える
# WDAY = %w(日 月 火 水 木 金 土).zip((0..6).to_a).to_h
tmp = { }
%w(日 月 火 水 木 金 土).each_with_index do |v, i|
tmp[v] = i
end
WDAY = tmp
schedule = YAML.load_file(schedule_yaml)
schedule.each do |program|
program_wday = WDAY[program['wday']]
is_next_day_program = false
# appropriate wday
h, m = program['time'].split(':').map(&:to_i)
if h.zero? && m.zero?
# check next day's wday
# if today.wday is 6 (Sat), next_wday is 0 (Sun)
next_wday = (today.wday + 1).modulo(7)
is_appropriate_wday = program_wday == next_wday
is_next_day_program = true
else
# check today's wday
is_appropriate_wday = program_wday == today.wday
end
# appropriate time
if is_next_day_program
# 日付を跨ぐので録音開始の日付が1日ずれる
next_day = today + 60 * 60 * 24
# today.day + 1 してたら 31 を超えるとTimeがエラー吐く
program_start = Time.new(next_day.year, next_day.month, next_day.day, h, m, 0, "+09:00")
else
program_start = Time.new(today.year, today.month, today.day, h, m, 0, "+09:00")
end
is_appropriate_time = (program_start - today).abs < 120
length = program['length'] * 60 + 10
if is_appropriate_wday && is_appropriate_time
title = (program['title'].to_s + '_' + today.strftime('%Y%m%d')).gsub(' ','')
flv_path = "#{save_dir}/flv/#{title}.flv"
# record stream
rec_command = "#{rtmpdump} -r #{agqr_stream_url} --live -B #{length} -o #{flv_path} >/dev/null 2>&1"
system rec_command
# encode flv -> m4a
m4a_path = "#{save_dir}/mp3/#{title}.m4a"
m4a_encode_command = "#{ffmpeg} -y -i #{flv_path} -vn -acodec copy #{m4a_path} >/dev/null 2>&1"
system m4a_encode_command
# encode m4a -> mp3
mp3_path = "#{save_dir}/mp3/#{title}.mp3"
mp3_encode_command = "#{ffmpeg} -i #{m4a_path} #{mp3_path} >/dev/null 2>&1"
system mp3_encode_command
# delete m4a
system "rm -rf #{m4a_path}"
end
end
- title: moeshi
wday: 月
time: '17:30'
length: 30
- title: torima
wday: 月
time: '19:30'
length: 30
- title: fivestars_mon
wday: 月
time: '20:00'
length: 60
- title: dream_theater
wday: 月
time: '21:30'
length: 30
- title: muuun
wday: 月
time: '22:00'
length: 60
- title: yonayona_mon
wday: 火
time: '00:00'
length: 60
- title: tryangle
wday: 火
time: '19:30'
length: 30
- title: fivestars_tue
wday: 火
time: '20:00'
length: 60
- title: toshitai
wday: 火
time: '23:30'
length: 30
- title: yonayona_tue
wday: 水
time: '00:00'
length: 60
- title: anime_scramble
wday: 水
time: '17:30'
length: 30
- title: catch_shiena
wday: 水
time: '18:00'
length: 60
- title: fivestars_wed
wday: 水
time: '20:00'
length: 60
- title: yonayona_wed
wday: 木
time: '00:00'
length: 60
- title: maru
wday: 木
time: '1:30'
length: 30
- title: pyxis
wday: 木
time: '19:00'
length: 30
- title: anigera
wday: 木
time: '21:00'
length: 30
- title: yonayona_thu
wday: 金
time: '00:00'
length: 60
- title: mikku
wday: 金
time: '1:00'
length: 30
- title: sachika
wday: 金
time: '2:00'
length: 30
- title: ohanac
wday: 土
time: '20:30'
length: 30
- title: agson
wday: 土
time: '21:00'
length: 120
- title: comcha
wday: 土
time: '23:00'
length: 60
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment