Asterisk で音声返答付きモーニングコール機能を実装する

2025/11/23 19:35 PerlLinuxAsterisk
Asterisk で運用している内線電話システムに、モーニングコール機能を実装しました。受付・キャンセル時に自動音声で応答します。

前提条件

  • Ubuntu 24.04.3 LTS
  • FFmpeg インストール済み (version 6.1.1-3ubuntu5)
  • Asterisk で通話可能になっている
  • 文字コードは UTF-8 で統一

準備1 音声を生成するためのもの (OpenJTalk + MMDAgent)

インストール

$ sudo apt install open-jtalk open-jtalk-mecab-naist-jdic hts-voice-nitech-jp-atr503-m001
$ : MMDAgent から音声モデルをいただきます
$ wget https://sourceforge.net/projects/mmdagent/files/MMDAgent_Example/MMDAgent_Example-1.8/MMDAgent_Example-1.8.zip
$ unzip MMDAgent_Example-1.8.zip
$ sudo mv MMDAgent_Example-1.8/Voice/mei /usr/share/hts-voice/
$ : 発声が出来るか確認
$ echo "10分" | open_jtalk -m /usr/share/hts-voice/mei/mei_normal.htsvoice -x /var/lib/mecab/dic/open-jtalk/naist-jdic -ow /tmp/voice.wav -g 15 && aplay /tmp/voice.wav

文字列を Asterisk 用音声に変換するスクリプトを用意

パスを /usr/local/bin/asterisk-utils/jtalk2wav.pl とします。実行権限を付加します。
標準状態の Asterisk で .wav ファイルを再生するには モノラル / サンプリング周波数8000Hz である必要があるようです。
#!/usr/bin/perl

use strict;
use warnings;

my $VOICE     = '/usr/share/hts-voice/mei/mei_normal.htsvoice';
my $DICT      = '/var/lib/mecab/dic/open-jtalk/naist-jdic';
my $OTHER_OPT = '';

my($text, $output_wav) = @ARGV;

my $TEMP_WAV  = "/var/tmp/$$.wav";

open(my $pipe, '|-', "/usr/bin/open_jtalk -m $VOICE -x $DICT -ow $TEMP_WAV $OTHER_OPT") or die;
print $pipe $text;
close $pipe;

system("ffmpeg -i $TEMP_WAV -af 'aformat=sample_rates=8000' -loglevel quiet -y $output_wav");
unlink($TEMP_WAV);

exit;

準備2 受付・キャンセル用スクリプトの用意

パスを /usr/local/bin/asterisk-utils/morning-call.pl とします。実行権限を付加します。
#!/usr/bin/perl -w

use v5.12;

use FindBin;
chdir $FindBin::Bin or die;

use Getopt::Long qw(:config posix_default no_ignore_case gnu_compat);


my $OUT_SPOOL = '/var/spool/asterisk/outgoing';
my $TEMP_DIR  = '/var/tmp';
my $SOUND_EXT = '279';  #モーニングコール音源につながる内線番号

my($action, $time, $caller, $answer_wav);
GetOptions('answer-wav=s' => \$answer_wav,
           'action=s'     => \$action,
           'time=s'       => \$time,
           'caller=s'     => \$caller,
                                        ) or die 'Invalid options';

my $answer_text = '';

if( $action =~ /REGISTER/i && $time =~ /^(\d{2})(\d{2})$/ && $1 <= 23 && $2 <= 59){
    my($h, $m) = ($1, $2);

    cancel($caller);

    my ($date, $today_or_tomorrow) = get_date_at_the_time($time);
    register($date, $time, $caller);

    $h =~ s/^0//;
    $m =  $m==0 ? 'ちょうど'
         :$m==30? '半'
         :( int($m). "分" );

    $answer_text = "モーニングコールを $today_or_tomorrowの $h時$mにセットしました";

}elsif( $action =~ /CANCEL/i ) {
    cancel($caller);
    $answer_text = "モーニングコールをキャンセルしました";

}else{
    $answer_text = "無効な指定です";
}

system("./jtalk2wav.pl '$answer_text' $answer_wav") if $answer_wav;
say $answer_text;

exit;



#コールをセット.
sub register {
    my($date, $time, $caller_ext) = @_;

    my $file = "$TEMP_DIR/morning-call-$caller_ext-$date-$time.txt";
    open(my $fh, '>', $file) or die("Cannot create $file");

    my $body = << "    EOM";
        Channel: PJSIP/$caller_ext
        CallerID: Good_Morning!!
        MaxRetries: 0
        RetryTime: 300
        WaitTime: 30
        Context: ipdenwa
        Extension: $SOUND_EXT
        Archive: yes
    EOM

    $body =~ s/^\s+//gm;
    print $fh $body;

    system("touch --date='$date $time' $file");
    system("mv $file $OUT_SPOOL");
}



#指定内線番号の登録をすべて解除.
sub cancel {
    my($caller_ext) = @_;

    unlink glob("$OUT_SPOOL/morning-call-$caller_ext-*.txt");
}



#指定された時刻に応じて ( 今日or明日の日付(ISO8601),  文字列「今日」or「明日」 ) をリストで返す.
sub get_date_at_the_time {
    #時刻は3~4桁の数値で指定
    my($time) = @_;

    my $date;
    my $today_or_tomorrow;

    my $now_time = int(`date +%H%M`);

    #現在時刻が 指定時刻を過ぎていたら
    if( $time <= $now_time ){
        $today_or_tomorrow = '明日';
        $date = `date --iso-8601 --date 1day`;
    }else{
        $today_or_tomorrow = '今日';
        $date = `date --iso-8601`;
    }

    chomp $date;
    return ($date, $today_or_tomorrow);
}

準備3 モーニングコール音源の用意

モーニングコールを受けた際に再生する音楽や音声などを、モノラル / サンプリング周波数8000Hz の .wav ファイルで用意します。
お好みで CD から音楽をリッピングしたり、前述の OpenJTalk で音声を合成したりしてください。
そのファイルを私は /var/lib/asterisk/sounds/asadayo.wav に置きました。

準備4 extensions.conf への追記

/etc/asterisk/extensions.conf にモーニングコールに関する動作を追記します。
私の環境では内線番号には200番台を振っています。それにならって、モーニングコールのセットには「277 + 時刻4桁」を、キャンセルには「278」を、またモーニングコール音源を再生する番号には「279」を割り当てました。
[house] は私の環境における内線のためのコンテキストです。適宜読み替えてください。
[house]

(...中略...)

; 277xxxx モーニングコール 登録
exten => _277XXXX,1,NoOp(REGISTER-MORNINGCALL)
same  => n,Answer
same  => n,Playback(beep)
same  => n,Set(ANSWER_WAV_BASENAME=/var/tmp/morning-call-answer-$CALLERID(num))
same  => n,System(/usr/bin/rm $ANSWER_WAV_BASENAME.wav)
same  => n,System(/usr/local/bin/asterisk-utils/morning-call.pl --action register --time '$EXTEN:3' --caller '$CALLERID(num)' --answer-wav $ANSWER_WAV_BASENAME.wav)
same  => n,Playback($ANSWER_WAV_BASENAME)
same  => n,System(/usr/bin/rm $ANSWER_WAV_BASENAME.wav)
same  => n,Wait(1)
same  => n,Playback(beep)
same  => n,Hangup

; 278 モーニングコール 取り消し
exten => _278,1,NoOp(CANCEL-MORNINGCALL)
same  => n,Answer
same  => n,Playback(beep)
same  => n,Set(ANSWER_WAV_BASENAME=/var/tmp/morning-call-answer-$CALLERID(num))
same  => n,System(/usr/bin/rm $ANSWER_WAV_BASENAME.wav)
same  => n,System(/usr/local/bin/asterisk-utils/morning-call.pl --action cancel --caller '$CALLERID(num)' --answer-wav $ANSWER_WAV_BASENAME.wav)
same  => n,Playback($ANSWER_WAV_BASENAME)
same  => n,System(/usr/bin/rm $ANSWER_WAV_BASENAME.wav)
same  => n,Wait(1)
same  => n,Playback(beep)
same  => n,Hangup

; 279 きみの朝
exten => 279,1,Answer
same  => n,Wait(1)
same  => n,Playback(/var/lib/asterisk/sounds/asadayo)
same  => n,Hangup
Asterisk を再起動後、SIP電話機から 279 へダイヤルし音源が再生されることを確認してください。場合によっては音源のボリュームを調整する必要もあるかもしれません。

使い方

セット

SIP電話機から「277」に続いて時刻を4桁でダイヤルします。例えば現在時刻が午後9時で明朝7時にモーニングコールをセットしたいときは、「2770700」とダイヤルします。
「モーニングコールを 明日の 7時ちょうどにセットしました。」と音声が流れ、電話が切られます。この電話機に翌朝7時にモーニングコールが掛かってきます。

キャンセル

SIP電話機から「278」にダイヤルします。
「モーニングコールをキャンセルしました。」と音声が流れ、電話が切られます。

参考

tel2ma 日本国内の電話番号から、その番号の属する市外局番と MA(単位料金区域) を得るツール

2025/11/27 10:46 Perl
日本国内の電話番号から、その番号の属する市外局番と MA(単位料金区域) を得るツールです。外部と通信することなくスタンドアロンで動きます。

JavaScript版 (tel2ma.js)

使い方

Web版 を用意しました。

ソース

Perl版 (tel2ma.pl)

使い方

tel2ma.pl <電話番号>
<電話番号> は 0 から始まる10~11桁で指定します。ハイフンが入っていても構いません。MA判定に影響がない桁は x などのアルファベットに置き換えても構いません。
判定ができたら、市外局番-市内局番-加入者番号 の順にハイフン処理がされた電話番号と MA および域内の主な市町村が出力されます。
$ tel2ma.pl 0312345678
03-1234-5678 東京MA 東京都23区,狛江市

$ tel2ma.pl 03-1234-xxxx
03-1234-xxxx 東京MA 東京都23区,狛江市

$ tel2ma.pl 090-xxxx-yyyy
090-xxxx-yyyy 携帯電話

$ tel2ma.pl 04-7100-xxxx
04-7100-xxxx 柏MA 千葉県野田市,柏市,流山市,我孫子市

$ tel2ma.pl 042917zzzz
04-2917-zzzz 所沢MA 埼玉県所沢市,狭山市,入間市

ソース

ご使用に際して

  • このプログラムの出力結果の正当性は保障いたしません。
  • MA域内として出力される市町村は、主要部(市町村事務所所在地*)がそのMA域内にある市町村のみを出力しています。実際には他の市町村も属している可能性があります。(*:町村役場がその町村以外の自治体にある場合を除く)
  • Apache License 2.0 でライセンスします。

参考にしたもの

Ubuntu 24.04 LTS で xorriso を使用して BD に書き込む

2025/10/26 18:28 Linux
Ubuntu 24.04 LTS で BD (ブルーレイ・ディスク)に対して書き込むときに、オーソドックスな Brasero や K3b を使うと私の環境ではなぜか失敗してしまいます (DVD だと大丈夫なんですけどね)。
そこであまり使用例が出てこないのですが、xorriso を使ってみたらうまく行ったのでレポートします。

使用機材:USB2.0 外付けBDドライブ Buffalo BRXL-PC6VU2/N
以下 /dev/sr0 として認識されているものとします。

メディア情報の確認

xorriso -dev '/dev/sr0' -toc
で確認できます。
ブランク BD メディア(25GB)を入れたときの例:
$xorriso -dev '/dev/sr0' -toc                                                                  
xorriso 1.5.6 : RockRidge filesystem manipulator, libburnia project.                                               
                                                                                                                   
Drive current: -dev '/dev/sr0'                                                                                     
Media current: BD-R sequential recording                                                                           
Media status : is blank                                                                                            
Media summary: 0 sessions, 0 data blocks, 0 data, 23.3g free                                                       
Drive current: -dev '/dev/sr0'                                                                                     
Drive access : exclusive:unrestricted                    
Drive type   : vendor 'MATSHITA' product 'BD-MLT UJ260AF' revision '1.00'                                          
Drive id     : 'WP**  ******'                            
Media current: BD-R sequential recording                 
Media product: CMCMAG/BA5/0 , CMC Magnetics Corporation                                                            
Media status : is blank     
Media blocks : 0 readable , 12219392 writable , 12219392 overall                                                   
Media summary: 0 sessions, 0 data blocks, 0 data, 23.3g free

書き込み

xorriso -dev '/dev/sr0' -map <書き込み元のパス> <書き込み先のディレクトリ> -volid <ボリューム・ラベル>
を実行します。
<書き込み先のディレクトリ> は通常 / にしておけばよいでしょうが、指定するとそのディレクトリが作成されて、その中に書き込まれます。
$xorriso -dev '/dev/sr0' -map /var/0476-ドラマ・突然の明日/2025/09/ALL / -volid "ドラマ・突然の明日"                                                                            
xorriso 1.5.6 : RockRidge filesystem manipulator, libburnia project.                                               

Drive current: -dev '/dev/sr0'                           
Media current: BD-R sequential recording                 
Media status : is blank     
Media summary: 0 sessions, 0 data blocks, 0 data, 23.3g free                                                       
xorriso : UPDATE :      13 files added in 1 seconds                                                                
Added to ISO image: directory '/'='/var/0476-ドラマ・突然の明日/2025/09/ALL'
xorriso : WARNING : -volid text problematic as automatic mount point name                                          
xorriso : WARNING : -volid text does not comply to ISO 9660 / ECMA 119 rules                                       
xorriso : UPDATE : Thank you for being patient. Working since 0 seconds.                                           
xorriso : UPDATE : Thank you for being patient. Working since 1 seconds.                                           
xorriso : UPDATE : Thank you for being patient. Working since 2 seconds.                                           
xorriso : UPDATE : Writing:        544s    0.0%   fifo  99%  buf   0%    0.2xB                                     
xorriso : UPDATE : Writing:        544s    0.0%   fifo 100%  buf   0%    0.0xB                                     
xorriso : UPDATE : Writing:        544s    0.0%   fifo 100%  buf   0%    0.0xB
                                    (中略)
xorriso : UPDATE : Writing:    6755969s   99.8%   fifo   0%  buf  62%    2.4xB                                     
xorriso : UPDATE : Writing:    6761024s   99.9%   fifo   0%  buf  37%    2.3xB                                     
xorriso : UPDATE : Writing:    6766409s  100.0%   fifo   0%  buf  37%    2.5xB                                     
xorriso : UPDATE : Writing:    6768570s  100.0%   fifo   0%  buf  25%    1.0xB                                     
xorriso : UPDATE : Closing track/session. Working since 1247 seconds                                               
ISO image produced: 6768420 sectors                      
Written to medium : 6768576 sectors at LBA 0             
Writing to '/dev/sr0' completed successfully.

参考文献

こじまみつひろ さん 玩式草子─ソフトウェアとたわむれる日々 第91回 xorrisoとUEFIブート再び[その1]

foltia-dl.pl  ――foltia ANIME LOCKER 録画データ ダウンローダ

2025/08/28 14:03 LinuxPerlfoltia
自動録画予約ソフトウェア foltia ANIME LOCKER 向けに、同ソフトが動作している Web サイトから録画・録音データをダウンロードするツールを開発しました。mp4 フォーマットのときにはメタデータ(番組名・放送局名・放送時間)も付加して保存します。
foltia ANIME LOCKER は samba サーバ機能も持っていて、そこから録画・録音ファイルを取り出すことも出来るのですが、先に示したようなメタデータは保存されません。また、ファイル名も取り扱いがしやすい形式のものが欲しかった(日付の前に年も欲しい、番組名に含まれる半角記号は全角に直したい)のも本ツール開発の動機です。

ソースファイル

動作要件

  • (当然ながら)foltia ANIME LOCKER が動作しているサーバにHTTPアクセスが可能なこと。
  • (本ツールを動かすマシンに)perl がインストールされていること。
  • (本ツールを動かすマシンに)ffmpeg がインストールされていること。.mp4 ファイルへメタデータを付加するために使用します。

実行方法の例

当ツール foltia-dl.pl を実行権をつけて、パスの通っている場所 (/usr/local/bin/ など) に配置して、
(例1) $ foltia-dl.pl | bash

(例2) $ foltia-dl.pl --grep 'きょうの(料理|健康)' | bash

(例3) $ foltia-dl.pl --tsv

(例4) $ foltia-dl.pl --tsv --grep '御宿かわせみ' > kawasemi.txt
のように実行してください。
標準出力に、シェルで実行可能なコマンドを組み合わせた文字列が出力されます(例1・2)。
TSVモードのとき(例3・4)には、保存先ファイル名・HTTPリクエスト用のパス・番組名・放送局名・放送日時・放送長さが出力されます。

詳細な使い方

  foltia-dl.pl [--tsv] [--grep <title_regexp_string>]
--tsv または -t任意録画録音情報のタブ区切り出力モードになります。指定しないときが通常モードで、シェルで実行可能な文字列を出力します。
--grep <正規表現文字列>任意番組名が<正規表現文字列>に合致した場合のみ出力します。

ソース中の要変更箇所

53行目(あたり)で $FOLTIA_HOST に代入している、foltia ANIME LOCKER が動作している ホスト名またはIPアドレス は、お使いの環境に合わせて書き換えてください。

foltia ANIME LOCKER用 予約重複 チェックツール

2025/08/27 22:34 PerlLinuxfoltia
自動録画予約ソフトウェア foltia ANIME LOCKER を利用していますが、予約重複でチューナー不足になっているのを見逃して録画に失敗してしまい、残念な思いをすることがあります。
そこで、予約一覧から予約時刻が重複している番組を抽出するツールを作成しました。
Perl で書いてあります。cron で実行すると重複予約があるときだけメールで知らせてくれるように出来ます。

ソース
#!/usr/bin/env perl

use strict;
use warnings;

use HTTP::Tiny;


our $FOLTIA_HOST = 'http://localhost:80';

get_reservation_table('/reservation/');
exit;



sub get_reservation_table {
    my ($path) = @_;
    my $resp   = HTTP::Tiny->new->get($FOLTIA_HOST. $path);
    
    if ($resp->{success}) {
        my $body = $resp->{content};
        while ($body =~ m|<tr.+?</tr>|sg) {
            my $rec = $&;
            $rec =~ s/<br>|\n|\r//g;
            my ($id)      = $rec =~ m|id="(-\d+)"|;
            next unless $id;
            
            my ($station) = $rec =~ m|<td class="station">(.+?)</td>|;
            my ($date)    = $rec =~ m|<td class="date">(.+?)</td>|;
            my ($title)   = $rec =~ m|<td>(.+?)</td>|;
            die "放送局・日時・番組名が取得できませんでした. rec=$rec" unless $station && $date && $title;
    
            print "$id $date $station $title\n" if check_overwrap($id);;
        }
        
        get_reservation_table($1) if $body =~ m|<a rel=next href="(.+?)" >|;
        
    } else {
        die "予約一覧が取得できませんでした. get=$FOLTIA_HOST$path";
    }

}



sub check_overwrap {
    my ($id) = @_;
    
    my $api_url = "${FOLTIA_HOST}/reservation/reservation_overwrap_chk_api.php?p=$id";

    my $resp = HTTP::Tiny->new->get($api_url);
    
    if ($resp->{success}) {
        my $body = $resp->{content};
        if(  my ($overwrap) = $body =~ /"overwrap":"(.*?)"/  ) {
            return $overwrap;
            
        } else {
            die "overwrap 文字列が取得できませんでした. api_url=$api_url";
        }
        
    } else {
        die "overwrap が取得できませんでした. api_url=$api_url";
    }

}

Excel で切手組み合わせ問題を整数計画問題として解く

2025/09/06 12:17 整数計画問題
当サイトでは任意の額面を手持ちの切手を組み合わせて最小の枚数で用意する 切手組み合わせ計算ツール を公開しています。
その内部では整数計画問題ソルバである GLPK (Gnu Linear Programming Kit) を使って最適解を求めていますが、
同様のことを Microsoft Excel と付属ソルバを使って求めてみようと思います。

準備

  1. Excel のオプション -> アドイン -> 管理 -> Excel アドイン -> ソルバーアドイン があるのを確認 -> 設定ボタンをクリック
    excel-option.png
  2. ソルバーアドイン にチェック -> OK ボタンをクリック
    excel-add-in.png

入力フォーマットや数式の入力

  1. 例えば次のようなフォーマットを用意します。
    excel-form.png

    Excel ファイルは こちら
    xlsx_icon.png
    kitte.xlsx
    です。
  2. C2 セルに 組み合わせたい金額を入力します
  3. B5 セルから B24 セルには切手の単価を入力します。とりあえず現在発売中の切手の金額を入力します。
  4. D5 セルから D24 セルに手持ちの枚数を入力します。
  5. F5 セルから F24 セルに後ほど結果が代入されます。なんでもいいのですが、とりあえず 0 で埋めておきます。
  6. C26 セルは組み合わせ試行中の合計金額を表します。数式 =SUMPRODUCT(B5:B24,F5:F24) を入力します。この数式は (単価×枚数) の総和を意味します。
  7. C27 セルは組み合わせ試行中の合計枚数を表します。数式 =SUM(F5:F24) を入力します。これがこの問題の最小化させたい目的関数となります。

ソルバーの設定

  1. メニューの データ タブ -> 分析 -> ソルバー をクリック
    excel-menu-solver.png

    excel-solver-setting.png
  2. 目的セルを C27 に設定します。このセルは合計枚数を示すものです。
  3. 目標値は 最小値 を選択します。合計枚数を最小にする解を得たいからです。
  4. 変数セルは F5:F24 にします。ソルバーによってこの範囲に各切手の枚数が代入されていきます。
  5. 制約条件の対象 に3つ条件を追加します。
    • (1) C26 = C2
      これによって合計金額が指定の金額と等しくなるように制約します。
      excel-subject-to-total.png
    • (2) F5:F24 <= D5:D24
      これによって各切手の使用枚数が各々の在庫数以下であることを制約します。
      excel-subject-to-stock.png
    • (3) F5:F24 = 整数
      これによって切手の使用枚数が整数しか取り得ないことを制約します。
      整数に制約したいときには真ん中のセレクトボックスで int を選択します。
      excel-subject-to-integer.png
  6. 制約のない変数を非負数にする にチェックします。切手の使用枚数はマイナスにはならないからです。
  7. 解決方法の選択 では シンプレックスLP を選択します。ここで解決したい問題が線形を示す問題だからです。
  8. 最後に 解決 ボタンをクリックします。

結果を読む

  1. 「整数解が見つかりました」と出たら成功です。
    excel-solver-found.png
    • ソルバーの解の保持 を選択して OK ボタンをクリックします。
    • F5:F24 セル範囲に代入されている枚数が答えです。
      excel-solved.png
  2. 「実行可能解が見つかりませんでした」と出たら、手持ちの切手では合計金額ちょうどの組み合わせが作れなかったということです。
    excel-solver-not-found.png
    • 計算前の値に戻す を選択して OK ボタンをクリックして戻り、在庫枚数などの条件を見直しましょう。

参考

  1. Wikipedia日本語版「整数計画問題」: https://ja.wikipedia.org/wiki/%E6%95%B4%E6%95%B0%E8%A8%88%E7%94%BB%E5%95%8F%E9%A1%8C
  2. Wikipedia日本語版「切手問題」:https://ja.wikipedia.org/wiki/%E5%88%87%E6%89%8B%E5%95%8F%E9%A1%8C

Linux desktop (MATE) でランチャから起動された端末(Terminal)のタイトルを変更する方法

2025/02/07 22:23 Linux
Linux Desktop (MATE) において ワンクリックでアプリケーションを起動させたいとき、カスタム・アプリケーションのランチャをパネルに追加します。
そのソフトが CUI のソフトのときは キーの型を[端末内で機能する]とするのですが、それを起動するときタスクバーに表示されるタイトルが単に[端末]となってしまい、何が実行されているのか分かりづらいです。
Windows の bat ファイルでは title コマンドを使って 実行されているウインドウのタイトルを簡単に変更できるのですが、同様のことを Linux で実現する方法を探しました。

アイコン右クリック > [プロパティ] > [コマンド] に次のように指定します。
bash -c "echo -ne '\033]0;'\"TITLEタイトル\"'\a'; sleep 10 ; exit"

TITLEタイトル がタイトルになります。sleep コマンド以降は適宜実行したいコマンドに置き換えてください。

set_terminal_title.png
実行されている様子

らじる★らじる 録音予約ツール

2025/10/06 00:55 LinuxPerl
らじる★らじる でインターネット配信されるラジオ番組を、指定した時刻に予約録音するツールを制作しました。

ソースファイル

動作要件

  • Linux など
  • perl 次のモジュールが使用可能なこと
    • HTTP::Tiny
    • HTML::Entities
    • XML::XPath
    • XML::XPath::XMLParser
  • ffmpeg が単独で正常に動作していること(パスの通っている場所に配置してください)
  • at (ジョブの遅延実行とバッチ処理) がインストールされていること。

実行方法の例

各 .pl ファイルに実行権をつけて、パスの通っている場所 (/usr/local/bin/ など) に配置して、
$ rec-nhk-radio.pl [ -c | --check | --verbose ] [--offset-time <開始オフセット(秒)>] [--end-margin  <後方余白(秒)>] <放送局ID> [<録音開始日>] <録音開始時刻> [<録音長(分)> <タイトル>]
のように実行してください。
-c または --check任意atコマンドを発行せずに、コマンドの内容を表示します。
--verbose任意冗長表示モード
--offset-time <開始オフセット(秒)>任意録音開始時刻の00秒から実際に録音を開始するまでの秒数を指定します。デフォルトは35秒です。らじる★らじる は電波での放送から50秒ほど遅れているようです。
--end-margin <後方余白(秒)>任意指定の録音長さの後に余分に録音する秒数を指定します。デフォルトは30秒です。
<放送局ID>必須放送局ID 例: tokyo-r1, r2, tokyo-fm
<録音開始日>省略可録音開始する日付を YYYY-MM-DD 形式で指定します。 例: 2024-09-02
<録音開始時刻>必須録音開始する時刻を24時間制で hhmm または hh:mm 形式で指定します。 例: 305, 0305, 3:05, 03:05
<録音長(分)>省略可録音の長さを分単位で指定します。 例: 61
<タイトル>省略可タイトルを指定します。
<録音開始日> を省略した場合には、現在以降直近の <録音開始時刻> から録音が開始されます。
<録音長(分)> と <タイトル> を省略した場合には、番組表からそれらの情報を取得し設定されます。

環境変数 RADIKO_SAVE_TO に保存先のディレクトリを指定します。
~/.bashrc などに
export RADIKO_SAVE_TO=/var/radiko/save/to
のように追記すればよいでしょう。

放送局ID

指定できるのは、r2 (第2放送), sapporo-r1, sendai-r1, tokyo-r1, nagoya-r1, osaka-r1, hiroshima-r1, matsuyama-r1, fukuoka-r1 (ここまで第1放送),
sapporo-fm, sendai-fm, tokyo-fm, nagoya-fm, osaka-fm, hiroshima-fm, matsuyama-fm, fukuoka-fm (ここまでFM放送) です。

2025-10-05

らじる★らじる の URL 変更(2025-09-26)に伴い、録音部を radish から新たに自作した dl-radiru2.pl に切り替えました。
URL変更以降、録音が途切れがちになる傾向がありましたが、ffmpeg に -seg_max_retry オプションを設定(=5)することにより解消されています。

2025-08-03

もともと radiko 専用としていましたが、radish での radiko 対応が残念ながら終えられてしまったので、本ツールも らじる★らじる 専用として改修しました。

2024-09-11対策済み: at の落とし穴 (?) セット時のカレントディレクトリがなくなってしまったときの問題

このツールでタイマー録音をセットしたのに、録音に失敗するケースがありました。
rec-radiko.pl を実行した時点のカレントディレクトリを削除して(あるいは名前変更して)しまうとダメなようでした。
at -c <job番号> で確認してみると
cd /home/*****/aaaaa/bbbbb || {
         echo 'Execution directory inaccessible' >&2
         exit 1
}
のような記述があって、at を読んだときのディレクトリが存在しなくなると失敗させるようになっていました。