|
a/samplescripts/Analog-Input |
|
b/samplescripts/Analog-Input |
1 |
#!/usr/bin/env python
|
1 |
#!/usr/bin/env python
|
2 |
|
2 |
|
3 |
from __future__ import print_function
|
3 |
from __future__ import print_function
|
4 |
|
4 |
|
5 |
# An example script for sending an audio input out to songcast, with
|
5 |
# Reference script for reading an audio input and sending to Songcast,
|
6 |
# appropriate interface to be controlled by upmpdcli
|
6 |
# with an appropriate interface to be controlled by upmpdcli.
|
7 |
#
|
7 |
#
|
8 |
# This must be named something like the following, and made executable:
|
8 |
# The script can also be executed from the command line for
|
9 |
#
|
9 |
# testing. No need for parameters, but you should set the device name
|
10 |
# /usr/share/upmpdcli/src_scripts/Analog-SenderReceiverReplaceable
|
10 |
# at least (and maybe the mixer scripts), see further down.
|
11 |
#
|
|
|
12 |
# - You can use another directory for scripts by setting the upmpdcli
|
|
|
13 |
# configuration variable "ohsrc_scripts_dir"
|
|
|
14 |
#
|
11 |
#
|
15 |
# - 'Analog' may be replaced by 'Digital' or 'Hdmi' if you so fancy.
|
12 |
# The general idea is that upmpdcli will create an Openhome Source for
|
16 |
# - 'SenderReceiver' is the mandatory beginning of the part after the dash.
|
13 |
# each script it finds inside a designated directory.
|
17 |
# - 'Replaceable' can be whatever you want.
|
|
|
18 |
#
|
14 |
#
|
19 |
# The Source will appear with type Analog and name SenderReceiverReplaceable
|
15 |
# By default, the directory is '/usr/share/upmpdcli/src_scripts', but
|
20 |
# in an OpenHome Source select dialog (e.g from upplay).
|
16 |
# it can be changed by setting the "ohsrc_scripts_dir" configuration
|
|
|
17 |
# variable inside /etc/upmpdcli.conf
|
21 |
#
|
18 |
#
|
22 |
# The 'SenderReceiver' string part is a hack for upplay to guess that
|
19 |
# Entries inside the directory will typically be created as symbolic
|
23 |
# the Receiver for this upmpdcli instance is active.
|
20 |
# links to this file, which is installed as /usr/share/upmpdcli/Analog-Input
|
24 |
#
|
21 |
#
|
25 |
# Capture device. Use arecord -L to list possible values.
|
22 |
# The links must be named like SourceType-SourceName, where SourceType
|
26 |
# The following are values I use to test on my system and entirely
|
23 |
# MUST BE one of 'Analog', 'Digital', or 'Hdmi', (which are all the
|
27 |
# dependant on my config, there is no reason they should work for you
|
24 |
# same, and for display purpose only), and you can choose 'SourceName'
|
28 |
#device = '''default:CARD=U0x46d0x825'''
|
25 |
# as you wish, but it should contain no space characters.
|
29 |
#device = '''default:CARD=PCH'''
|
26 |
#
|
30 |
device = '''default:CARD=Device'''
|
27 |
# The Source will appear with type Analog, Digital or Hdmi and name
|
|
|
28 |
# SourceName in an OpenHome Source select dialog (e.g from upplay).
|
|
|
29 |
#
|
|
|
30 |
# If a file named device-SourceName exists in the same directory as
|
|
|
31 |
# the link, we read the device name from it (the contents should be
|
|
|
32 |
# a single line with the device name). Else, the device name is
|
|
|
33 |
# 'default', which has little chance to work
|
|
|
34 |
#
|
|
|
35 |
# If a file named prescript-SourceName exists in the same directory,
|
|
|
36 |
# it must be executable, and we try to execute it before
|
|
|
37 |
# activating. We renounce if it fails. This is meant for mixer
|
|
|
38 |
# commands to set up the device.
|
|
|
39 |
#
|
|
|
40 |
# If a file named postcript-SourceName exists in the same directory,
|
|
|
41 |
# it must be executable, and we try to execute it before terminating
|
|
|
42 |
# This is meant for mixer commands to reset the device.
|
|
|
43 |
#
|
31 |
|
44 |
|
32 |
import time
|
45 |
import time
|
33 |
import subprocess
|
46 |
import subprocess
|
34 |
import os
|
47 |
import os
|
35 |
import sys
|
48 |
import sys
|
36 |
import uuid
|
49 |
import uuid
|
37 |
import getopt
|
50 |
import getopt
|
38 |
import signal
|
51 |
import signal
|
39 |
import socket
|
52 |
import socket
|
40 |
|
53 |
|
41 |
def usage(f):
|
54 |
############# Defaults
|
42 |
print("Usage: %s [-h] [-f friendlyname]" % sys.argv[0], file=f)
|
55 |
|
43 |
sys.exit(1)
|
56 |
# Capture device. Use arecord -L to list possible values.
|
|
|
57 |
# Set this in device-mySourceName
|
|
|
58 |
device = '''default'''
|
44 |
|
59 |
|
45 |
# Songcast Sender program. This reads from stdin and sends to
|
60 |
# Songcast Sender program. This reads from stdin and sends to
|
46 |
# Songcast. It comes with the sc2mpd package (see the upmpdcli web
|
61 |
# Songcast. It comes with the sc2mpd package (see the upmpdcli web
|
47 |
# site)
|
62 |
# site)
|
48 |
uxsender = "mpd2sc"
|
63 |
uxsender = "mpd2sc"
|
49 |
|
64 |
|
50 |
# Upmpdcli friendly-name, actual value comes as a parameter. Used to
|
65 |
# Upmpdcli friendly-name, the actual value comes from a parameter when
|
|
|
66 |
# executed from upmpdcli (as normal). Used to compute a Uuid in
|
51 |
# compute a Uuid in conjunction with the node name and script name
|
67 |
# conjunction with the node name and script name
|
52 |
upmpdcli_fname = "UpMpd"
|
68 |
upmpdcli_fname = "UpMpd"
|
|
|
69 |
|
|
|
70 |
def usage(f):
|
|
|
71 |
print("Usage: %s [-h] [-f friendlyname]" % sys.argv[0], file=f)
|
|
|
72 |
sys.exit(1)
|
53 |
|
73 |
|
54 |
args = sys.argv[1:]
|
74 |
args = sys.argv[1:]
|
55 |
opts, args = getopt.getopt(args, "hup:f:")
|
75 |
opts, args = getopt.getopt(args, "hup:f:")
|
56 |
for opt, arg in opts:
|
76 |
for opt, arg in opts:
|
57 |
if opt in ['-h']:
|
77 |
if opt in ['-h']:
|
|
... |
|
... |
59 |
elif opt in ['-f']:
|
79 |
elif opt in ['-f']:
|
60 |
upmpdcli_fname = arg
|
80 |
upmpdcli_fname = arg
|
61 |
else:
|
81 |
else:
|
62 |
print("unknown option %s\n"%opt, file=sys.stderr)
|
82 |
print("unknown option %s\n"%opt, file=sys.stderr)
|
63 |
usage(sys.stderr)
|
83 |
usage(sys.stderr)
|
|
|
84 |
|
|
|
85 |
|
|
|
86 |
# Script name should be something like type-name. We use the name part
|
|
|
87 |
# to look for data or aux scripts
|
|
|
88 |
scriptdir = os.path.dirname(sys.argv[0])
|
|
|
89 |
scriptname = os.path.basename(sys.argv[0])
|
|
|
90 |
lst = scriptname.split("-")
|
|
|
91 |
|
|
|
92 |
prescript = None
|
|
|
93 |
postscript = None
|
|
|
94 |
if len(lst) == 2:
|
|
|
95 |
srcname = lst[1]
|
|
|
96 |
path = os.path.join(scriptdir, 'device-' + srcname)
|
|
|
97 |
if os.path.exists(path):
|
|
|
98 |
device = open(path).read().strip()
|
|
|
99 |
path = os.path.join(scriptdir, 'prescript-' + srcname)
|
|
|
100 |
if os.path.exists(path):
|
|
|
101 |
prescript = path
|
|
|
102 |
path = os.path.join(scriptdir, 'postscript-' + srcname)
|
|
|
103 |
if os.path.exists(path):
|
|
|
104 |
postscript = path
|
|
|
105 |
|
|
|
106 |
print("device [%s] prescript [%s] postscript [%s] " %
|
|
|
107 |
(device, prescript, postscript), file=sys.stderr)
|
64 |
|
108 |
|
65 |
# UDN and name for the Sender UPnP device. We use a hash of the
|
109 |
# UDN and name for the Sender UPnP device. We use a hash of the
|
66 |
# friendly name and host name
|
110 |
# friendly name and host name
|
67 |
sender_udn = uuid.uuid5(uuid.NAMESPACE_DNS,
|
111 |
sender_udn = uuid.uuid5(uuid.NAMESPACE_DNS,
|
68 |
socket.gethostname() + upmpdcli_fname + sys.argv[0]).urn
|
112 |
socket.gethostname() + upmpdcli_fname + sys.argv[0]).urn
|
|
... |
|
... |
79 |
pass
|
123 |
pass
|
80 |
try:
|
124 |
try:
|
81 |
senderproc.terminate()
|
125 |
senderproc.terminate()
|
82 |
except:
|
126 |
except:
|
83 |
pass
|
127 |
pass
|
|
|
128 |
# Execute post-script if it is set
|
|
|
129 |
if postscript:
|
|
|
130 |
try:
|
|
|
131 |
subprocess.check_call(postscript)
|
|
|
132 |
except:
|
|
|
133 |
pass
|
|
|
134 |
|
84 |
sys.exit(xval)
|
135 |
sys.exit(xval)
|
85 |
|
136 |
|
86 |
def sighandler(signum, frame):
|
137 |
def sighandler(signum, frame):
|
87 |
cleanup(1)
|
138 |
cleanup(1)
|
88 |
|
139 |
|
89 |
signal.signal(signal.SIGINT, sighandler)
|
140 |
signal.signal(signal.SIGINT, sighandler)
|
90 |
signal.signal(signal.SIGTERM, sighandler)
|
141 |
signal.signal(signal.SIGTERM, sighandler)
|
|
|
142 |
|
|
|
143 |
|
|
|
144 |
# Execute pre-script if it is set
|
|
|
145 |
if prescript:
|
|
|
146 |
subprocess.check_call(prescript)
|
91 |
|
147 |
|
92 |
# -f S16_LE -c 2 -r 44100
|
148 |
# -f S16_LE -c 2 -r 44100
|
93 |
try:
|
149 |
try:
|
94 |
recordproc = subprocess.Popen(('arecord', '-D', device,
|
150 |
recordproc = subprocess.Popen(('arecord', '-D', device,
|
95 |
'-f', 'cd', '-t', 'raw', '-'),
|
151 |
'-f', 'cd', '-t', 'raw', '-'),
|
|
... |
|
... |
111 |
cleanup(1)
|
167 |
cleanup(1)
|
112 |
|
168 |
|
113 |
# Get the Uri and Metadata values from the sender. These get written to stdout
|
169 |
# Get the Uri and Metadata values from the sender. These get written to stdout
|
114 |
urimeta = senderproc.stdout.readline()
|
170 |
urimeta = senderproc.stdout.readline()
|
115 |
|
171 |
|
116 |
|
|
|
117 |
# Tell the world we're set. upmpdcli expects this format exactly
|
172 |
# Tell the world we're set. upmpdcli expects this format exactly
|
118 |
print("Ok %d %s" % (0, urimeta))
|
173 |
print("Ok %d %s" % (0, urimeta))
|
119 |
sys.stdout.flush()
|
174 |
sys.stdout.flush()
|
120 |
|
175 |
|
121 |
# Wait process.
|
176 |
# Wait process.
|