Do nagrywania audycji radiowych ze strumienia audio używam dwóch skryptów ( nie ja jestem ich autorem, nie umiem programować) uruchamianych na koncie shell:
- skrypt w Pythonie:
#!/usr/bin/env python3
# argumenty: url= time= prefix= albo u= t= p=
import socket
import os
import fcntl
import io
import sys
import time
import re
# czy Python3? (Python2 ma inna biblioteke urllib):
mpv = sys.version_info.major
if mpv == 3:
from urllib import request as urq
else:
print("Uzyj Python-a 3!")
sys.exit(-1)
url = "http://stream4.nadaje.com:9240/prw"
ts = "1m"
pfx = "tmp"
def patn2s(a):
m = {'s': 1, 'm': 60, 'h': 3600}
i = re.finditer('[0-9]+[hms]', a)
t = 0
for e in i:
u = a[e.end()-1]
v = int(a[e.start():e.end()-1])
t = t + v*m[u]
return t
for a in sys.argv[1:]:
if a[:4] == 'url=':
url = a[4:]
if a[:5] == 'time=':
ts = a[5:]
if a[:7] == 'prefix=':
pfx = a[7:]
if a[:2] == 'u=':
url = a[2:]
if a[:2] == 't=':
ts = a[2:]
if a[:2] == 'p=':
pfx = a[2:]
dtv = patn2s(ts)
print('url="%s"' % (url))
print('time="%s"=%u' % (ts, dtv))
print('prefix="%s"' % (pfx))
t_end = time.time()+dtv
while time.time() < t_end:
ofn = pfx+time.strftime("%Y-%m-%d_%H-%M-%S.mp3")
print('output="%s"' % (ofn))
sys.stdout.flush()
try:
pr = urq.urlopen(url, timeout=1)
except:
time.sleep(0.5)
continue
ofd = io.open(ofn, "wb")
tl = 0
while time.time() < t_end:
try:
d = pr.read1(16000)
except:
d = ''
break
ofd.write(d)
time.sleep(0.2)
tl += len(d)
print('total length %u, last block %u' % (tl, len(d)))
sys.stdout.flush()
ofd.close()
pr.close()
- skrypt w Bashu:
#!/bin/bash
# jako argument podaje sie prw, albo prx (nazwy w case)
# - sluza do wyboru zestawu parametrow do nagrywania
# skrypt w Pythonie ma nazwe "$HOME/scripts/gsn.py"
# to sa wspolne elementy katalogow dla logow i MP3
logp="$HOME/JW/log"
ddpr="$HOME/JW"
# czas startu dla nazwy logu (bedzie tylko jeden log)
dts="$(date '+%Y-%m-%d_%H-%M-%S')"
# tu podaje sie parametry dla kazdej wersji nagrywania:
# lfr to prefiks logow (jeszcze bez czasu i .log/.err);
# dpr - prefiks nazw MP3; dt - czas nagrywania; i url
case "$1" in
prw) lfr="$logp/RW_"; dpr="$ddpr/RW_"; dt=2h
url="http://stream4.nadaje.com:9240/prw";;
3po3) lfr="$logp/3po3_"; dpr="$ddpr/3po3_"; dt=30m
url="http://stream4.nadaje.com:9240/prw";;
sdw) lfr="$logp/SDW_"; dpr="$ddpr/SDW_"; dt=2h
url="http://stream4.nadaje.com:9230/rwkultura";;
sds) lfr="$logp/SDS_"; dpr="$ddpr/SDS_"; dt=4h
url="http://stream4.nadaje.com:9240/prw";;
new) lfr="$logp/NEW_"; dpr="$ddpr/NEW_"; dt=2h
url="http://stream4.nadaje.com:9240/prw";;
add) lfr="$logp/ADD_"; dpr="$ddpr/ADD_"; dt=3h
url="http://stream4.nadaje.com:9240/prw";;
max357aac) lfr="$logp/MAX357AAC_"; dpr="$ddpr/MAX357AAC_"; dt=5m
url="https://stream.rcs.revma.com/ye5kghkgcm0uv";;
max357mp3) lfr="$logp/MAX357MP3_"; dpr="$ddpr/MAX357MP3_"; dt=5m
url="https://stream.rcs.revma.com/an1ugyygzk8uv";;
*) exit;; esac; # tu sie konczy, jak nieznana nazwa
# uwaga: $dts dodaje sie do nazwy logu, ale nie do
# prefiksu nazw MP3 - to ma zrobic skrypt w Pythonie
# na wszelki wypadek tworzenie katalogow:
p="${dpr%/*}"; [ -d "$p" ] || mkdir -p "$p" || exit
p="${lfr%/*}"; [ -d "$p" ] || mkdir -p "$p" || exit
[ "$2" ] && dt="$2"
# i wykonanie wedlug wybranego zestawu parametrow:
exec "$HOME/scripts/gsn.py" "url=$url" "prefix=$dpr" \
"t=$dt" > "$lfr$dts.log" 2> "$lfr$dts.err" < /dev/null
Uruchamiam je w cron’ie w przykładowy sposób:
00 18 * * 1-5 /home/rostov/scripts/gsn.sh prw
gdzie prw
jest parametrem określonym w skrypcie bash dla jednej ze stacji radiowych, zawierającym adres strumienia, prefiks pliku wynikowego, oraz czas trwania nagrania.
Wszystko działa elegancko, ale problem jest z dwoma ostatnimi stacjami:
https://stream.rcs.revma.com/ye5kghkgcm0uv
https://stream.rcs.revma.com/an1ugyygzk8uv
Jak widać w powyższym przykładzie, czas nagrywania został testowo ustawiony na 5 minut. Niestety, w pierwszym przykładzie plik wynikowy (aac) ma 1m 9s, a w drugim (mp3) 36s. Pliki takiej długości otrzymuję bez względu na to, jaką długość nagrania ustawię. Czym to może być spowodowane? Czy może tym, że te 2 ostatnie strumienie mają https, czy może na serwerze jest jakaś blokada?