
私はこの.shを持っています:
#!/bin/bash
cd /home/pi/Desktop/PiFmRds/src
for f in $(ls -1 /home/pi/Desktop/Music/Acapella/*.mp3|sort -R); do sox -t mp3 "$f" -t wav -r 44100 - | sudo ./pi_fm_rds -freq 102.1 -audio - -ps WZSFM -rt "ZSFM"; done
デフォルトでは、ディレクトリ内のすべてのファイルをランダムな順序で再生し、すぐにmp3からwavに変換してからpfmにパイプします。 PifmはFMラジオで放送できるプログラムです。問題は、forloopを使用しているため、pfmコマンドを実行して各個々のファイルをブロードキャストするため、各ファイル間のラジオにわずかな静的信号があるため、ファイル内のpfmコマンド間のラジオにいくつかの静的信号があることです。その後、停止して次のファイル処理を開始します。 forloopにコマンドの最初の部分だけを実行して、実際に放送されているpfm部分ではなくランダムな曲を選択させる方法はありますか?これにより、pfmコマンドは常にブロードキャストされ、forループはコマンドが混在するファイル部分にのみ適用されます。
さらに私はこれを試しました:
#!/bin/bash
cd /home/pi/Desktop/PiFmRds/src
for f in $(ls -1 /home/pi/Desktop/Music/Acapella/*.mp3|sort -R); do sox -t mp3 "$f" -t wav -r 44100 - ; done | sudo ./pi_fm_rds -freq 102.1 -audio - -ps WZSFM -rt "ZSFM"
ただし、ファイルを再生した後は停止します。
編集:問題を次のようにまとめました。ファイル間に静的がある理由は、pifmコマンドが各ファイルをブロードキャストするためですが、forloopの各繰り返しごとに停止して再実行するため、繰り返し間に静的だけがあるためです。各ファイルを個別に繰り返しながら(必要に応じて、それ以外の場合はより多くの問題が発生します)、常に放送するようにするにはどうすればよいですか?
答え1
まず読んで理解してください。lsが解析されないのはなぜですか(そして何をすべきですか?)ls
- あなたがやろうとしているように、それを使用しないでください妥当な理由があります。
プレイリストをランダムに指定する必要がない場合は、「単にfind
その-exec
オプションを使用してください。代わりにfind
その-print0
オプションを使用して出力をsort -z -R
(またはshuf -z
)にパイプしてから、スクリプトを実行してxargs -0r
ファイルを変換して再生してください。
まず、次のスクリプトを作成します。
#!/bin/bash
pifm='/home/pi/Desktop/PiFmRds/src/pi_fm_rds'
for f in "$@"; do
sox -t mp3 "$f" -t wav -r 44100 -
done | sudo "$pifm" -freq 102.1 -audio - -ps WZSFM -rt "ZSFM"
.ls
pi_fm_rds
ところで、改行やインデントを追加してスクリプトを読みやすくする必要があります。\
行の末尾にバックスラッシュ()を追加すると、次の行が現在の行の連続であることをbashに通知できます。または、次のスクリプトに示すように、|
パイプ文字()で終わる行は\
。
まだ実行していない場合は、sudo
ユーザーがパスワードなしでrootとして実行できるように構成する必要があります。/home/pi/Desktop/PiFmRds/src/pi_fm_rds
たとえば、/usr/local/bin/randomise-playlist.shとして保存して実行可能にしますchmod +x /usr/local/bin/randomise-playlist.sh
。
次に、変換して再生するファイル名のリストを渡して、次のように実行します。
find /home/pi/Desktop/Music/Acapella/ -type f -name '*.mp3' -print0 |
sort -z -R |
xargs -0 -r /usr/local/bin/randomise-playlist.sh
shuf -z
または代わりに-shufを使用してくださいsort -z -R
。 shufの目的は、入力ラインをランダムに指定することです。
これはパイプライン全体でファイル名の区切り文字としてNULを使用するため、有効な文字(スペース、タブ、改行、およびシェルメタ&
文字も含む)を含む;
ファイル名を使用します。
ところで、一部の人々は常に連続した行を終了し、次の行の先頭に\
パイプ|
文字(または||
その他など)を入れるのが好きです。&&
どちらの方法も同じように機能するため、より読みやすい方法を選択してください。ただし、常にいくつかのスペース(通常は2つのスペースを使用します。4つのスペースも推奨されます。場合によっては、後続の行の同じ列で始まるようにパラメータを並べ替えたい場合)または表記号で連続した行をインデントすることをお勧めします。前の行の連続であることを示します。
find /home/pi/Desktop/Music/Acapella/ -type f -name '*.mp3' -print0 \
| sort -z -R \
| xargs -0 -r /usr/local/bin/randomise-playlist.sh
上記のすべての項目にはGNUバージョンfind
および/またはが必要です。 Raspberry Piで実行されているため、GNUは標準である必要があります。xargs
sort
shuf
coreutils
findutils
必要に応じて、コマンドfind ... | xargs
全体を独自のスクリプトに入れることができます。実行するたびに入力するのに少し時間がかかります。
答え2
forループを使用して各クリップを個別に再生するのではなく、soxコマンドの機能を使用してクリップを単一の再生ストリームに結合します。
また、ファイル名に特殊文字(スペースを含む)が含まれていると、リストを生成するための指定された方法が中断されます。さらに、ファイル数が多い場合は、コマンドラインの長さ制限に達する可能性があります。元のコマンドには両方の問題があるため、この問題を完全に解決するわけではありません。ただし、考えられる解決策は、ファイル名を任意の順序で(おそらくシンボリックリンクなど)新しい番号付きファイル名にマッピングし、それを単一の名前でsoxに提供し、-t mp3 "*.mp3"
soxをグローバルに拡張できるようにすることです。
以下の変更がお客様の要件を満たしている必要があります。
ループでsoxを実行する代わりに、ファイルのリストをsoxに直接提供してください。
この
-t mp3
オプションを削除し、soxが自動的にファイル形式を検出するようにします。すべての.mp3ファイルが、同じサンプリングレートとチャンネル数を使用して単一のリンクされた出力ストリームに結合できることを確認してください。
sox $(ls -1 /home/pi/Desktop/Music/Acapella/*.mp3|sort -R) -t wav -r 44100 - | sudo ./pi_fm_rds -freq 102.1 -audio- -ps WZSFM -rt "ZSFM"
上記のいずれかの操作が失敗した場合は、ファイルをマージする前にファイルを前処理する必要があります。
オーディオファイルにはデフォルトでヘッダーがあり、直接追加できないため、2回目の試みは失敗しました。 pi_fm_rds コマンドのドキュメントを確認しないと、そのヘッダーが必要かどうかはわかりません。予期しない場合、これはファイル間の静的ソースである可能性があります。この場合のもう1つのアプローチは、ヘッダーなしで生のオーディオをエクスポートし、forループ内の各ファイルに対して個別に呼び出すようにsoxに指示することです。