Switch to unified view

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.