RSS

(root)/misc-scripts : /mediatomb-sirius.py (revision 75)

Line Revision Contents
1 39
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3 57
"""mediatomb-sirius.py (c) 2007 ... 2009 Matthew Ernisse <mernisse@ub3rgeek.net>
4 39
All Rights Reserved.
5
6 57
$Id: mediatomb-sirius.py,v 1.9 2008/12/22 02:45:38 mernisse Exp $
7 39
8
Transcode Sirius Internet Radio streams, originally written to allow Mediatomb
9
to playback Sirius Radio.
10
11
Requires:
12
	vlc (http://www.videolan.org/vlc/) - could probably be modified to work
13
	with ffmpeg or mencoder, but vlc has pretty decent URL handling and it
14
	is universally available.
15
16
	Sipie (http://sipie.sourceforge.net/) - Python backend for Sirius
17
	streams.
18
19
Configuration:
20
	Once you have Sipie up and working this should function automatically,
21
	it loads your Sipie config from $HOME/.sipie/
22
23
License:
24
	If you find this useful, I'd love to hear from you.
25
26
Redistribution and use in source and binary forms, 
27
with or without modification, are permitted provided 
28
that the following conditions are met:
29
 
30
    * Redistributions of source code must retain the 
31
      above copyright notice, this list of conditions 
32
      and the following disclaimer.
33
    * Redistributions in binary form must reproduce 
34
      the above copyright notice, this list of conditions 
35
      and the following disclaimer in the documentation 
36
      and/or other materials provided with the distribution.
37
38
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
39
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
40
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
41
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
42
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
43
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
44
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
45
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
46
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 
47
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
48
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49
50
"""
51
import os
52 46
import re
53 47
import signal
54
import subprocess
55 39
import sys
56
import Sipie
57 46
import urllib2
58 39
59
from sys import exit
60
61 47
PLAYFD = None
62
FIFOFD = None
63
64 39
def findPlayer(exe):
65
	""" Returns the Path to the requested executable by searching the
66
67
	user's PATH environment variable.
68
69
	Arguments:
70
		exe - string, file to search for
71
	Returns:
72
		None or string
73
74
	"""
75
	for e in os.environ['PATH'].split(':'):
76
		if os.path.exists(e + "/" + exe):
77
			return e + "/" + exe
78
	return None
79
80 44
def Usage():
81
	print """Usage: %s [list][create][playlist fifo] 
82
83
Viewing or creating stream list:
84
	list - Prints the available streams to stdout
85
	create - creates playlist files in the current directory 
86
87
Playing:
88
	The arguments= list in the Mediatomb config should just be
89
	"%%in %%out".  This will pass the playlist file as the first
90
	argument and the FIFO as the second argument.  For testing 
91
	you can manually pass those arguments yourself.
92
""" % sys.argv[0]
93
	exit(2)
94
95 47
def sig_cleanup(sig, stack):
96
	global FIFOFD, PLAYFD
97
	os.kill(PLAYFD.pid, 15)
98
	exit(0)
99
100 57
def playVLC(player, url, fifo):
101
	global FIFOFD, PLAYFD
102
103
	# vlc is shameful, in that it opens the fifo prior to
104
	# actually starting the stream, so mediatomb thinks the
105
	# transcoder died and then kills the process. 
106
	# NOTE NOTE NOTE NOTE NOTE
107
	# The PS3 is BIG ENDIAN, because it's based on the PPC arch,
108
	# so make sure we output BIG ENDIAN lpcm, not LITTLE ENDIAN,
109
	# unless you love static A LOT
110
	args = '"%s" -I dummy --http-user-agent="NSPlayer" ' % (url)
111
	args += '--sout "#transcode{acodec=s16be,channels=2,samplerate=44100}'
112
	args += ':std{access=file,mux=wav,dst=-}"'
113
114
	# catch the kill signal from sipie so we can kill off VLC
115
	# otherwise it could very well just sit there forever like
116
	# a pain in the arse.
117
	signal.signal(signal.SIGTERM, sig_cleanup)
118
	signal.signal(signal.SIGHUP, sig_cleanup)
119
120
	FIFOFD = open(fifo, 'w')
121
	PLAYFD = subprocess.Popen("%s %s" % (player, args), shell=True,
122
		 stdout=subprocess.PIPE)
123
124
	for line in PLAYFD.stdout:
125
		try:
126
			FIFOFD.write(line)
127
		except:
128
			FIFOFD.close()
129
			exit(0)
130
	exit(0)
131
132
def playMplayer(player, url, fifo):
133
	args = ['mplayer', '-nocache', '-user-agent', 'NSPlayer', \
134
		'-ao', 'null', '-dumpaudio', '-dumpfile', '%s' % (fifo), url]
135
136
	os.execvp(player, args)
137
	exit(0)
138
139 39
def main():
140
	""" This uses Sipie to transcode the asx streams from Sirius Internet
141
142
	Radio to mp3, useful for streaming to a media renderer.
143
144
	Arguments:
145 45
		argv[1] - Sirius stream name, or (list|create).  If list it 
146
		will output a list of streams available.  If create it will
147
		populate the current directory with .sirius files for each
148
		stream available.
149 39
150
		argv[2] - Output File / FIFO. 
151
152
	Returns:
153
		Nothing.
154
155
	Exit Values:
156
		0 - success
157
		1 - failure
158
		2 - usage error
159
160
	"""
161 45
	if not os.path.exists(os.environ['HOME'] + '/.sipie/'):
162
		print """ERROR: You must configure Sipie prior to running %s
163
You can do this by running sipie.py from the distribution's directory and
164
answering the questions.  Please also ensure you complete the CAPCHA.""" % (
165
			sys.argv[0] )
166
		exit(1)
167
168 44
	if len(sys.argv) == 1:
169
		Usage()
170 39
171
	if len(sys.argv[1:]) < 2:
172 45
		config = Sipie.Config(os.environ['HOME'] + '/.sipie/')
173
		sipie = Sipie.Factory(config.items())
174
175 44
		if sys.argv[1] == "list":
176
			print "Available Streams:"
177
			for stream in sipie.getStreams():
178
				print "	%s" % (stream)
179
			exit(0)
180 45
181 44
		elif sys.argv[1] == "create":
182
			print "Creating playlists"
183
			for stream in sipie.getStreams():
184
				fd = open("%s.sirius" % (stream), 'w')
185
				fd.close()
186
			exit(0)
187 45
188 44
		else:
189
			Usage()
190 39
191
	stream = os.path.basename(sys.argv[1].split(".")[0])
192
	fifo = sys.argv[2].strip()
193
194
	config = Sipie.Config(os.environ['HOME'] + '/.sipie/')
195
	sipie = Sipie.Factory(config.items())
196
197
	if not stream in sipie.getStreams():
198
		print "%s not found in getStreams()" % (stream)
199
		exit(1)
200 46
201 39
	sipie.setStream(stream)
202 46
203 57
	player = findPlayer('mplayer')
204
	player = None
205
	if not player:
206
		player = findPlayer('vlc')
207
		if not player:
208
			print "Cannot find mplayer or vlc in your PATH"
209
			exit(1)
210
		else:
211
			playVLC(player, sipie.asxURL, fifo)
212
	else:
213
		playMplayer(player, sipie.asxURL, fifo)
214
215 39
216
if __name__ == "__main__":
217
	main()	

Loggerhead 1.17 is a web-based interface for Bazaar branches