|
a |
|
b/samplescripts/Analog-SenderReceiverMyinput |
|
|
1 |
#!/usr/bin/env python
|
|
|
2 |
|
|
|
3 |
from __future__ import print_function
|
|
|
4 |
|
|
|
5 |
# An example script for sending an audio input out to songcast, with
|
|
|
6 |
# appropriate interface to be controlled by upmpdcli
|
|
|
7 |
#
|
|
|
8 |
# This must be named something like the following, and made executable:
|
|
|
9 |
#
|
|
|
10 |
# /usr/share/upmpdcli/src_scripts/Analog-SenderReceiverReplaceable
|
|
|
11 |
#
|
|
|
12 |
# - You can use another directory for scripts by setting the upmpdcli
|
|
|
13 |
# configuration variable "ohsrc_scripts_dir"
|
|
|
14 |
#
|
|
|
15 |
# - 'Analog' may be replaced by 'Digital' or 'Hdmi' if you so fancy.
|
|
|
16 |
# - 'SenderReceiver' is the mandatory beginning of the part after the dash.
|
|
|
17 |
# - 'Replaceable' can be whatever you want.
|
|
|
18 |
|
|
|
19 |
# Capture device. Use arecord -L to list possible values.
|
|
|
20 |
# The following are values I use to test on my system and entirely
|
|
|
21 |
# dependant on my config, there is no reason they should work for you
|
|
|
22 |
#device = '''default:CARD=U0x46d0x825'''
|
|
|
23 |
#device = '''default:CARD=PCH'''
|
|
|
24 |
device = '''default:CARD=Device'''
|
|
|
25 |
|
|
|
26 |
import time
|
|
|
27 |
import subprocess
|
|
|
28 |
import os
|
|
|
29 |
import sys
|
|
|
30 |
import uuid
|
|
|
31 |
import getopt
|
|
|
32 |
import signal
|
|
|
33 |
import socket
|
|
|
34 |
|
|
|
35 |
def usage(f):
|
|
|
36 |
print("Usage: %s [-h] [-f friendlyname]" % sys.argv[0], file=f)
|
|
|
37 |
sys.exit(1)
|
|
|
38 |
|
|
|
39 |
# Songcast Sender program. This reads from stdin and sends to
|
|
|
40 |
# Songcast. It comes with the sc2mpd package (see the upmpdcli web
|
|
|
41 |
# site)
|
|
|
42 |
uxsender = "mpd2sc"
|
|
|
43 |
|
|
|
44 |
# Upmpdcli friendly-name, actual value comes as a parameter. Used to
|
|
|
45 |
# compute a Uuid in conjunction with the node name and script name
|
|
|
46 |
upmpdcli_fname = "UpMpd"
|
|
|
47 |
|
|
|
48 |
args = sys.argv[1:]
|
|
|
49 |
opts, args = getopt.getopt(args, "hup:f:")
|
|
|
50 |
for opt, arg in opts:
|
|
|
51 |
if opt in ['-h']:
|
|
|
52 |
usage(sys.stdout)
|
|
|
53 |
elif opt in ['-f']:
|
|
|
54 |
upmpdcli_fname = arg
|
|
|
55 |
else:
|
|
|
56 |
print("unknown option %s\n"%opt, file=sys.stderr)
|
|
|
57 |
usage(sys.stderr)
|
|
|
58 |
|
|
|
59 |
# UDN and name for the Sender UPnP device. We use a hash of the
|
|
|
60 |
# friendly name and host name
|
|
|
61 |
sender_udn = uuid.uuid5(uuid.NAMESPACE_DNS,
|
|
|
62 |
socket.gethostname() + upmpdcli_fname + sys.argv[0]).urn
|
|
|
63 |
sender_name = "%s UxSender" % upmpdcli_fname
|
|
|
64 |
|
|
|
65 |
recordproc = None
|
|
|
66 |
senderproc = None
|
|
|
67 |
|
|
|
68 |
def cleanup(xval):
|
|
|
69 |
# Clean up
|
|
|
70 |
try:
|
|
|
71 |
recordproc.terminate()
|
|
|
72 |
except:
|
|
|
73 |
pass
|
|
|
74 |
try:
|
|
|
75 |
senderproc.terminate()
|
|
|
76 |
except:
|
|
|
77 |
pass
|
|
|
78 |
sys.exit(xval)
|
|
|
79 |
|
|
|
80 |
def sighandler(signum, frame):
|
|
|
81 |
cleanup(1)
|
|
|
82 |
|
|
|
83 |
signal.signal(signal.SIGINT, sighandler)
|
|
|
84 |
signal.signal(signal.SIGTERM, sighandler)
|
|
|
85 |
|
|
|
86 |
# -f S16_LE -c 2 -r 44100
|
|
|
87 |
try:
|
|
|
88 |
recordproc = subprocess.Popen(('arecord', '-D', device,
|
|
|
89 |
'-f', 'cd', '-t', 'raw', '-'),
|
|
|
90 |
stdout=subprocess.PIPE)
|
|
|
91 |
except Exception as err:
|
|
|
92 |
print("Can't start arecord: %s" % (err), file=sys.stderr)
|
|
|
93 |
cleanup(1)
|
|
|
94 |
|
|
|
95 |
# Start the Sender
|
|
|
96 |
try:
|
|
|
97 |
senderproc = subprocess.Popen([uxsender, "-f", "stdin",
|
|
|
98 |
"-A", "44100:16:2:1",
|
|
|
99 |
"-u", sender_udn, "-n", sender_name],
|
|
|
100 |
stdin=recordproc.stdout,
|
|
|
101 |
stdout=subprocess.PIPE,
|
|
|
102 |
bufsize = -1)
|
|
|
103 |
except Exception as err:
|
|
|
104 |
print("Can't start %s: %s"%(uxsender, err), file=sys.stderr)
|
|
|
105 |
cleanup(1)
|
|
|
106 |
|
|
|
107 |
# Get the Uri and Metadata values from the sender. These get written to stdout
|
|
|
108 |
urimeta = senderproc.stdout.readline()
|
|
|
109 |
|
|
|
110 |
|
|
|
111 |
# Tell the world we're set. upmpdcli expects this format exactly
|
|
|
112 |
print("Ok %d %s" % (0, urimeta))
|
|
|
113 |
sys.stdout.flush()
|
|
|
114 |
|
|
|
115 |
# Wait process.
|
|
|
116 |
while True:
|
|
|
117 |
if recordproc.poll() is not None or senderproc.poll() is not None:
|
|
|
118 |
break
|
|
|
119 |
time.sleep(0.5)
|
|
|
120 |
|
|
|
121 |
time.sleep(1)
|
|
|
122 |
cleanup(0)
|
|
|
123 |
|