Python3 dd-tool(2) for Raspberry Pi 3(Orange Pi 3)

前回作成したdd-toolは書き込み可能なカード(ディスク)を制限するためまた条件を付けやすいこともあり/dev/disk/by-uuidに登場したカードを対象にしています。
/dev/disk/by-uuidには正しくフォーマットされたカードがデバイスとして挙がってきます。
このdd-tool.pyを作成するにあたりパーティションを削除したり未フォーマットのカードを読み込ませると/dev/disk/by-uuidにはデバイス情報が挙がってきません。
実際カードの中に何らかの関係でフォーマット情報などが失われたカードがどのくらい存在するのかわかりませんが今後の実験目的も含めてそんなカードにも対応できるよう少し追加してみました。

デバイス情報

fdiskでパーティションを削除をします(/dev/sda)

lsblkするとOSからは認識しています。(/dev/sda)
/dev/disk/by-uuidには挙がっていません。当然マウントもできません。
sudo blkidからは見えますが基本の条件を変更することは表示形式も違うため簡単に登録、リスト出力が難しくなります。
lsblkから見えてby-uuidからは見えない/dev/sdXを抽出すればいいのですがヘタレな当サイトには簡単にできませんでした。lsblkとby-uuidを一旦ファイルに出力して差し分けを取ってみました。

$ lsblk -f | grep sd | grep -v - | awk '{print substr($0, 1, 3)}' | sort
$ ls -l /dev/disk/by-uuid | grep -oP 'sd.{0,2}' | awk '{print substr($0, 1, 3)}' | awk '!a[$0]++' | sort
$ diff /tmp/device1 /tmp/device2 | awk '{print substr($0, 3, 3)}' | grep sd

lsblkからデバイス名を3文字取り出します。
/dev/disk/by-uuidも同様に3文字取り出します。パーティションを切っていると同じデバイス名ができるので重複した名称はawkで削除
diffで差分をとってファイルに出力、pythonから読み込みます。

カードをUSB端子に接続、lsblkから見えているけどリストに表示されない場合はSEARCHボタンをクリックするとフォーマット実行メッセージボックスが表示されます。
デバイス名は必ず確認すること。
デバイス名はボタンをクリックする度にコマンドを実行、ファイルに書き出します。
該当デバイスに間違いが無ければ実行します。


フォーマットが完了するとリロードしてリストに反映されます。
lsblkで確認するとオートマウントされています。

Tkinter(Entry)

ボタンは少し格好良く配置してみました。(Terget Device)はDEVICEボタンで選択
Tkinterの基本書式は以下のサイトを参考にしています。(いつもお世話になっています)
https://python.keicode.com/advanced/tkinter.php

イメージファイルの入力、デバイスの表示にEntry(テキストボックス)を使っています。

frame2を設定
# Entry box イメージファイル入力
# Button frame2 ボタンを移動(ボタンの動作は変わりません。名称変更)
入力したファイルはflash_selectionでget
terget deviceはlabel3 = ttk.Label(frame2, text=dev)で表示

参考(raspberry pi) dd-tool-sample.py

149     # Frame
154     frame2 = ttk.Frame(
155         root,
156         relief='sunken',
157         borderwidth=2)
158     frame2.grid()

192     # Entry box
193     img = StringVar()
194     img_entry = ttk.Entry(
195         frame2,
196         textvariable=img,
197         width=20 )
198     img_entry.grid(row=0,column=1)

207     # Button frame2
208     button = ttk.Button(frame2, text='IMG FILE', command=button3_click)
209     button.grid(row=0, column=0, columnspan=1)
210     button = ttk.Button(frame2, text='DEVICE', command=select_selection)
211     button.grid(row=1, column=0, columnspan=1)

 56 def flash_selection():
 57     global img,dev
 58     # img get
 59     img = img.get()

 46         # terget device
 47         label3 = ttk.Label(frame2, text=dev)
 48         label3.grid(row=1,column=1)


当サイトのRaspberryPi3,OrangePi3で実行確認していますがほか環境、長期運用は未確認ですのでもし試す場合は確実に書き込むデバイスに間違いないか確認してください。
無責任、無保証です。

Python3 dd-tool for Raspberry Pi 3(Orange Pi 3)

現在の当サイトのメイン環境はRaspberryPi3そしてファイルサーバーにOrangePi3を使って運用しています。それぞれOSのカード以外にSSDやHDDを接続しています。
各OSのイメージ作成にはddコマンドを使ってカードを作成しています。
ddコマンドはOSイメージ作成以外にもいろいろな使い方ができる強力なツールなのですが、使い方を誤ると悲惨な結果を招くことがあります。
間違いを犯す要因として接続ポートによってデバイス名が変わってしまうことが挙げられます。また注意していてもhistoryを多用しているとうっかり過去に使ったデバイス名で実行してしまうということもありえます。

他OSでは便利なツールもあるようですがOSカード作成専用にddコマンドを利用してほぼ間違えようのないツールを作成してみたいと思います。
Raspbian,Armbian(debian buster)用のツールです。

このツールを試すときはdf,lsblkなどのコマンドで充分確認の上実行するようにします。(無責任、無保証です)

概要

ddコマンドの基本書式は次のとおり

# dd if=os.img of=/dev/sdX bs=1M status=progress


ListBOXには接続してあるデバイスのuuidを表示します。
Img File欄には目的のイメージファイルをフルパスで入力します。

使い方は簡単でListBOXから書き込みをするSDカードを選択してSELECTボタンを押すとTerget Device欄に/dev/sdXを表示します。
Terget Deviceは/dev/sdXとして認識できるデバイスを対象にしています。
Img File欄にos imgの場所をコピー貼付けしてFLASHボタンを押すとddを実行します。

画像ではいろいろuuidが表示されていますがこのツールの肝はusbポートに接続してあるssd(hdd)やデータ用のSDカードなど取り外しデバイスのuuidを登録することによってListBOXには載らないようにしています。
uuidは一意(ユニーク)な値になっているので再フォーマットなどパーティション変更に伴う変更をしない限り重複、変化することはありません。
dd,uuidの最低限の基本を理解、設定してあれば極めて安全に且つ簡単にOSイメージのカードを作成することができます。
システム関連の設定は一切変更を加えていなのでコマンドラインその他の操作は一切変わりません。

除外デバイス

プログラム(dd-tool.py)の最初の方に除外デバイスを記述しています。

# device(除外デバイス)
command = ("ls -l /dev/disk/by-uuid | grep -v mmc | awk '{print $9}' | \
grep -v a12e7061-82ca-425e-a377-bbc9f46430e6 | \
grep -v b4f5e826-c78f-4b69-90d0-3753e6b69091 | \
grep -v cb6158bb-02fb-4b75-8736-4ca2bc6a8e5f | \
grep -v 633D-1EF9")

上記は当サイトのRPI3(SSD)の例です。4個のパーティション(うち1個はdosパーティション)があります。

接続したデバイスは/dev/disk/by-uuidに挙がってきます。内蔵スロットのカードはmmcblk0として認識しますがやはりgrep -v mmcでListに載らないようにしています。内蔵スロットからusbポートに差替えた場合はListに挙がってきます。Listに載せたくない場合はやはり除外デバイスとしてリストに記載します。

デフォルト(内蔵スロットカード)はListに何も表示されません。


除外デバイスを設定してraspbianを書き込んだカードを挿してプログラムを起動、またはRELOADボタン(再起動)を押すとリストに現れます。
どちらかを選択(同じ)してSELECTするとメッセージボックスが出現します。
messageboxはlsblk | grep /dev/sdXとsudo blkid | grep /dev/sdXしています。
ターミナルから確認するといいでしょう。

フォーマット

ddはイメージそのまま書き込んでいくのでフォーマットなしでもいいはずなのですが過去の経緯からフォーマットしたほうが安心感があります。初期の頃はOSのせいか安物のカードリーダーのせいかフォーマットしたほうが成功する率が高かったように思います。

パーティションエディタはpartedを実行しています。
実行はやはりデバイスを選択してFORMATボタンをクリックします。
messageboxが出るのでOKで開始
マウントしてあれば自動でアンマウントして実行
パーティションはforで廻してrm
mklabel msdos
mkpart primary fat32 1MiB 100%
FAT32専用フォーマット
xterm -e sudo mkfs.vfat -v -F 32 /dev/sdX1
完了メッセージが出るのでOKでプログラム再起動
uuidが変わります。

書き込み

テストとしてraspbian busterを焼いてみます。ダウンロードして展開しておきます。
Img File欄にフルパスでimgファイルの場所を指定します。Tkinterは右クリック貼り付けできないのでフルパスをフォーカスできるファイラーかpcmanfmでは右クリック-パスをコピーするでテキストエディタに貼り付けてそこからコピーするのがいいでしょう。

Img Fileとdeviceを選択してFLASHボタンをクリックするとxtermに渡すddコマンドの書式が出来上がります。
dd-tool.pyはこの書式を作成しているだけなのでImg File欄に/dev/sdXを記載するとディスクコピーになります。


Yesをクリックするとxtermが起動してddコマンドを実行します。
status=progressで進捗を表示します。


書き込み終了
xtermは終了します。
ターミナルやエディタは使いやすいものに変更するといいでしょう。


プログラム再起動してuuidが変わります。
pcmanfmに古い情報が残っていたらカードを抜き差しで更新

参考 dd-tool.py
# indentに誤りがあったので差替えました。

87             format_exe() (正)
87                 format_exe() (誤)

Orange Pi 3

OrangePi3もRaspberryPiと基本同じですがOrangePi3のオートマウントにはudiskieをインストールしています。フォーマットの際loop中オートマウントが有効になってしまうのでkillallしています。
書き込み後はカードリーダーごと抜き差しで更新します。

def format_exe():
    global dev
    subprocess.run("killall udiskie", shell=True)
    ---
    ---
    subprocess.run("udiskie -F -N &", shell=True)
    messagebox.showinfo('dd tool', "フォーマット完了 FAT32 " + dev)


RaspberryPiはポートを変更しない限りあまりデバイス名は変わらないのですがOrangePi3は再起動やカードの有無でかなり変わってきます。
ダウンロードしたイメージはファイルサーバーのOrangePi3に保存、作成もOrangePi3で実行することが多くなります。
このツールはかなり重宝しています。

SimulRadio – 音量設定(3) – (mpc volume)

CSRA関連にはmms://で配信しているラジオ局をリストに登録しています。これまでは見て聴かぬ振りをしていたのですがほぼ希望通りの動作をすることができたのでmms://も簡単に音量設定をしてみました。

mms://で登録しているラジオ局は10数局と数も少ないし決まったパターンも無いことから簡単なpythonファイル(mms.py)にして読み込んでいます。
simul-vol.pyとsimul.pyのplay_selectionを変更しています。

simul-vol.py

simul-vol.pyではJCBA – ListenRadio – NHKの順に検索しています。どれにも該当しないものをmms.pyで検索します。

        # other
        if not (proc):
            command = ("mpc playlist | grep -oP 'nhk.{0,5}' | grep -v {")
            proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
            proc = proc.strip()
            # NHK
            if proc == 'nhkradio':
                subprocess.run("mpc volume +4", shell=True)
            # mms
            else:
                subprocess.run("/home/pi/bin/mms.py", shell=True)

mms.pyでは直接urlを検索してmpc volumeの値を設定します。

command = ("mpc playlist")
proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
proc = proc.strip()
if proc == 'mms://hdv2.nkansai.tv/radiokaros':
    subprocess.run("mpc volume +5", shell=True)

simul.py

simul.pyのplay_selectionではsleepの値を調整するため検索順を少し変更して更に詰めてみました。
当サイトの環境では以下の設定値で問題なく設定した音量を変更することができました。
simul.pyを変更したらプログラムの再起動が必要です。
# ListenRadio time.sleep(0.2)
# JCBA time.sleep(4)
# NHK mms time.sleep(2.5)

# selection
def play_selection():
    for i in lb.curselection():
        a = (lb.get(i))
        subprocess.run("mpc add " + (a), shell=True)
        command = ("mpc playlist | grep -oP 'www.youtube.{0,4}' | grep -v {")
        proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
        proc = proc.strip()
        if proc == 'www.youtube.com':
            command = ((("mpv ") + (a)) + (" &"))
        else:
            command = ("mpc play")
        subprocess.run(command, shell=True)
        # simul-vol.py
        command = ("mpc playlist | grep -oP 'JCB.{0,3}' | grep -v {")
        proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
        if not (proc):
            command = ("mpc playlist | grep -oP 'smartstream.{0,6}'")
            proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
            proc = proc.strip()
            # ListenRadio
            if proc == 'smartstream.ne.jp':
                time.sleep(0.2)
            # NHK mms
            else:
                time.sleep(2.5)
        # JCBA
        else:
            time.sleep(4)
        subprocess.run(("~/bin/simul-vol.py"), shell=True)

ON AIR

NHK mms://については基本urlを表示しますが# ON AIRの項に直接urlを記述することで表示できます。

# ON AIR
def button7_click():
---
        # NHK mms
        if not (proc):
            command = ("mpc playlist")
            proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
            proc = proc.strip()
            if proc == 'https://nhkradiohkfm-i.akamaihd.net/hls/live/512076/1-fm/1-fm-01.m3u8':
                proc = 'NHK FM 仙台'
            if proc == 'mms://hdv2.nkansai.tv/radiokaros':
                proc = 'ラジオカロスサッポロ/札幌市'


ラジオカロスサッポロはListenRadioを休止してCSRAのサーバーに変更されています。

"ラジオカロスサッポロ/札幌市"     "mms://hdv2.nkansai.tv/radiokaros"

リストに登録したラジオ局は全て音量の設定ができるようになりました。ラジオ局側の対応が結構適当なのでほどほどがいいと思います。
接続、再生開始はネットワーク環境、回線状態、マシンパワーなどによると思います。

参考

当サイトの現在のpythonプログラムです。(無保証)
pythonプログラムは~/bin/以下に置いて$ chmod 755 xxx.pyしています。
mms.py ボリューム設定値は変更
simul.py
simul-vol.py

Raspberry Piでは Font “Helvetica” にすると見やすくなるかもしれません。

SimulRadio – 音量設定(2) - (mpc volume)

前回までラジオ局別にボリュームリストを作成、音量を揃えてだいぶ使いやすくなったのですが再生を開始してからボリュームボタンを押す必要がありました。

やはり使ってみると再度ボタンを押すことは手間なので(欲が出ます)オートボリュームぽい仕様にしてみました。

simul.py

simul-vol.pyを設置、正常に機能している環境で設定します。
mpc volumeはmpc playの状態で有効になるのでsleepを設定してsimul-vol.pyを実行するようにします。

# simul-vol.py以降を追記します。
再生開始は当サイトのOrangePi3環境ではListenRadioはplayとほぼ同時にJCBAは5秒ほど待つ必要があります。
+1秒を加えてtime.sleepを設定します。
(環境によって変更)

~/bin/simul.py

# selection
def play_selection():
    for i in lb.curselection():
        a = (lb.get(i))
        subprocess.run("mpc add " + (a), shell=True)
        command = ("mpc playlist | grep -oP 'www.youtube.{0,4}' | grep -v {")
        proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
        proc = proc.strip()
        if proc == 'www.youtube.com':
            command = ((("mpv ") + (a)) + (" &"))
        else:
            command = ("mpc play")
        subprocess.run(command, shell=True)
        # simul-vol.py
        command = ("mpc playlist | grep -oP 'JCB.{0,3}' | grep -v {")
        proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
        if not (proc):
            command = ("mpc playlist | grep -oP 'nhk.{0,5}' | grep -v {")
            proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
            proc = proc.strip()
            # NHK
            if proc == 'nhkradio':
                time.sleep(3)
            # ListenRadio
            else:
                time.sleep(1)
        # JCBA
        else:
            time.sleep(6)
        subprocess.run(("~/bin/simul-vol.py"), shell=True)

simul.pyプログラムON AIRボタンクリック時simul-vol.pyをチェックするようにしました。(1行追記します)

# ON AIR
def button7_click():
    subprocess.run(("~/bin/simul-vol.py"), shell=True)
    command = ("mpc playlist | grep -oP 'JCB.{0,3}' | grep -v {")

ボリューム値が適用されていなければ適用してON AIR表示します。


playボタンを押すと接続、再生開始して約1秒後にボリュームリストに記載した設定値を適用します。
ボリュームリストの値はラジオ局の番組、時間帯などによってかなり違う場合があります。
また起動時の初回はOSに保存されているmpc volume値が使われます。

これで当サイトとしてはほぼ満足の行く仕様に仕上がりました。

Raspberry Pi

現在のraspbianはやはりデフォルトでpulseaudioが有効になると思います。
~/.config/pulseを作成する必要があるかもしれません。通常は$ pulseaudio –startで作成されます。
確認、モニターするにはpavucontrolをインストール

# apt install pavucontrol


pulseaudioの基本はユーザーとして実行します。
simulradioでは再生タブ(mpd)の音量はボリュームリストによって変化します。
スピーカー、アンプのある環境ではマスターボリュームで出力装置の音量をコントロールしますがmpdの音量は同時に一定の比率で変化します。
再生開始時や終了時はマスターボリュームとmpdの値が同じのほうが使いやすいと思います。

pulseaudioの出力装置の音量をコントロールするには次のコマンドを使います。

$ pactl -- set-sink-volume 0 20%

このコマンドをkillall.shに追記します。(default 20 適宜変更)

#!/bin/sh
mpc pause 1>/dev/null 2>/dev/null
pactl -- set-sink-volume 0 20%
mpc volume 20 1>/dev/null 2>/dev/null
sleep 0.1 
mpc clear 1>/dev/null 2>/dev/null
killall -q mpv
killall -q mplayer
killall -q ffplay

mpc volumeの前に記述することでラジオ局の切り替え時や終了時はデフォルト値でマスターボリュームの値を設定することができます。
mpdの音量を大きくするとマスターボリュームも同時に大きくなります。

SimulRadio – 音量設定(mpc volume)

サイマルラジオはMPDによる接続も安定してずいぶん使い勝手も良くなりました。(数日前musicbirdのサーバーが怪しいときがありましたが…)

残る問題はラジオ局によって音量の違いがかなりあることだと思います。
流石にradikoはほとんど音量が揃っています。(NHKは若干低め)
サイマルラジオ局の音量はradikoと比較すると低めのところが多いようです。

自動化は無理としてもなんとか音量の違いをカバーする方法を考えてみたいと思います。
手順としてはpythonで外部プログラム(simul-vol.py)を作成
ラジオ局固有のボリューム情報を作成(vol)
操作しやすいように適当なメニューにボリュームボタンを配置
ラジオの再生を開始したらボリュームボタンを1回押すという想定をします。

作業にあたってpulseaudioの挙動を確認してみます。

Orange Pi 3


通常radikoの再生音量は20%で利用しています。このときpavucontrolの再生タブ(アプリケーション)と出力装置タブは同じ20%になります。SimulRadioを再生してmpd(mpc)の音量を上げていくと再生タブと出力タブは同じ値で上昇しますがそこから音量を下げていくと再生タブのみ追従します。実際の音量は再生タブの値ですね。再生タブ側はアプリケーションでコントロールする仕様と思います。新たにradikoなどを再生すると出力タブの音量で再生するので気をつけなければいけません。

Raspberry Pi 3

RaspberryPiのalsa環境を確認しようと切り替えたらいつの間にかpulseaudioが動いていますね。物心(pulse heart)付いた頃から常に~/.config/pulseにはclient.confを入れていたためいつどの時点で変更になったのか全く気が付きませんでした。lxsessionのpulseaudioのチェックは外れています。

確認手順としてはpulse server(moode)を停止、~/.config/mpd/mpd.confのaudio_outputをpulseからalsaに変更してmpd再起動、~/.config/pulse/client.confを削除した時点で切り替わりました。
pavucontrolをインストールしていないと通常はalsaと変わらないので気が付かないかもしれません。

mpc volume


音量の制御はmpc volumeコマンドを利用しています。
mpc playの状態でmpc volumeが適用されます。

ボリュームリスト(vol)の作成

サンプルはradikoの音量とほぼ同じかつしかFMを基準に実際に聴取して±の値を決めています。変更なしは+0を記載
最初は大雑把に決めていいと思います。またテスト用のIDだけでもいいです。
ファイルは一つにしていますが分けることも可能です。
/home/pi/radio/vol

JCB001 +3
JCB002 +3
JCB003 +6
JCB004 +0
---
30001 +2
30002 +10
30003 +10

simul-vol.py

default volumeの設定箇所はこのファイルと下のkillall.shの2箇所あります。環境に合わせて変更します。
最初にmpc volumeからボリューム値を取得しています。(vol_level)
値は0〜99を取得していますがここで使っているのはn/a以外を判断しています。
取得した値をなにかに利用する場合は文字列になっているのでint(vol_level)で数値にする必要があります。
プログラムの基本はON AIRの動作と全く一緒でmpc playlistからIDを取得、作成したボリュームリスト(vol)のIDを検索して設定値を取得、その値でmpc volume +nします。
NHKもurlを検索して少しUPしています。
~/bin/simul-vol.py

#!/usr/bin/python3
import subprocess
import re

# default volume
vol = "mpc volume 20"

# mpc volume
command = ("mpc volume | grep -oP 'volume.{4}'")
vol_level = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
vol_level = vol_level[8:]
vol_level = vol_level.strip()
#print(vol_level)
if vol_level != 'n/':
    subprocess.run(vol, shell=True)
    command = ("mpc playlist | grep -oP 'JCB.{0,3}' | grep -v {")
    proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
    if not (proc):
        command = ("mpc playlist | grep -oP 'jp/3.{0,4}' | grep -v {")
        proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
        # other
        if not (proc):
            command = ("mpc playlist | grep -oP 'nhk.{0,5}' | grep -v {")
            proc = (subprocess.Popen(command, stdout=subprocess.PIPE, shell=True).communicate()[0]).decode('utf-8')
            proc = proc.strip()
            # NHK
            if proc == 'nhkradio':
                subprocess.run("mpc volume +4", shell=True)
            else:
                subprocess.run("mpc volume +0", shell=True)

        # ListenRadio
        else:
            proc = proc.strip()
            proc = proc[3:]
            with open("/home/pi/radio/vol", 'r') as f:
                for id in f:
                    if re.search((proc), id):
                        v = id[5:]
                        command = ("mpc volume" + (v))
                        subprocess.run(command, shell=True)
    # JCBA
    else:
        proc = proc.strip()
        with open("/home/pi/radio/vol", 'r') as f:
            for id in f:
                if re.search((proc), id):
                    v = id[6:]
                    command = ("mpc volume" + (v))
                    subprocess.run(command, shell=True)
else:
    quit

killall.sh

ラジオ局の切り替えや終了時は一旦ポーズしてデフォルトボリューム値を設定、mpc clearを実行。clearするとstopも実行します。
simul.py起動時はmpc playしていないのでmpc volume はn/aになっています。起動時はOSに保存されているmpc volumeの値が使われるためここで保存します。(必ずしもここの設定だけが保存されるとは限りません)
またラジオ局の切替時もデフォルトボリューム値を再設定します。
~/bin/killall.sh

#!/bin/sh
mpc pause 1>/dev/null 2>/dev/null
# デフォルトボリューム値を設定
mpc volume 20 1>/dev/null 2>/dev/null
sleep 0.1 
mpc clear 1>/dev/null 2>/dev/null
killall -q mpv 
killall -q mplayer
killall -q ffplay


volumeの値はncmpcppにリアルタイムに表示されます。
ボタンはncmpcpp下のスピーカーアイコンを使っています。
デフォルトボリューム値からncmpcppで音量を変更確認してID volume値を編集保存、ボタンを押すと即座に反映します。

サイマルラジオの音量は番組やCMによってもかなりアバウトに感じます。修正を加えながらリストを育てると使いやすくなると思います。

これまで10%以上開きがあると聴く気にならなかったのですが今は普通に聴くことができます。音質の悪いラジオ局はNGですが。

作成したsimul-vol.pyは実行権限を付けてメニューボタンから実行します。

$ chmod 755 simul-vol.py

参考 無責任 無保証です。ボリュームリスト(vol)は環境によってデフォルトボリュームが違うと思うので勝手に作成してください。
app.py サンプルメニュー
simul-vol.py
simul.py ID Editはボリュームリスト(Vol Edit)に変更しました。
ListboxはOS,fontなどによって見え方が違ってくると思います。
font sizeやwidthなど適当にいじってください。

radikoは放送大学を除いて無料で受信できるラジオ局を全て登録しました。
radikoのホームページにアクセスするとエリアが表示されます。これプロバイダの接続点ですね。放送局をクリックするとurlの末尾にradikoスクリプトに指定するIDが見えます。

だいぶラジオ環境が充実してきました。

Top