├── LGPL3.txt
├── README.md
├── WTFPL.txt
├── automation
├── getlogin.py
├── getnext.py
├── getpromo.py
└── login.py
├── icecast
└── icecast.xml
└── liquidsoap
└── radio.liq
/LGPL3.txt:
--------------------------------------------------------------------------------
1 |
2 | GNU LESSER GENERAL PUBLIC LICENSE
3 | Version 3, 29 June 2007
4 |
5 | Copyright (C) 2007 Free Software Foundation, Inc.
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 |
10 | This version of the GNU Lesser General Public License incorporates
11 | the terms and conditions of version 3 of the GNU General Public
12 | License, supplemented by the additional permissions listed below.
13 |
14 | 0. Additional Definitions.
15 |
16 | As used herein, "this License" refers to version 3 of the GNU Lesser
17 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
18 | General Public License.
19 |
20 | "The Library" refers to a covered work governed by this License,
21 | other than an Application or a Combined Work as defined below.
22 |
23 | An "Application" is any work that makes use of an interface provided
24 | by the Library, but which is not otherwise based on the Library.
25 | Defining a subclass of a class defined by the Library is deemed a mode
26 | of using an interface provided by the Library.
27 |
28 | A "Combined Work" is a work produced by combining or linking an
29 | Application with the Library. The particular version of the Library
30 | with which the Combined Work was made is also called the "Linked
31 | Version".
32 |
33 | The "Minimal Corresponding Source" for a Combined Work means the
34 | Corresponding Source for the Combined Work, excluding any source code
35 | for portions of the Combined Work that, considered in isolation, are
36 | based on the Application, and not on the Linked Version.
37 |
38 | The "Corresponding Application Code" for a Combined Work means the
39 | object code and/or source code for the Application, including any data
40 | and utility programs needed for reproducing the Combined Work from the
41 | Application, but excluding the System Libraries of the Combined Work.
42 |
43 | 1. Exception to Section 3 of the GNU GPL.
44 |
45 | You may convey a covered work under sections 3 and 4 of this License
46 | without being bound by section 3 of the GNU GPL.
47 |
48 | 2. Conveying Modified Versions.
49 |
50 | If you modify a copy of the Library, and, in your modifications, a
51 | facility refers to a function or data to be supplied by an Application
52 | that uses the facility (other than as an argument passed when the
53 | facility is invoked), then you may convey a copy of the modified
54 | version:
55 |
56 | a) under this License, provided that you make a good faith effort to
57 | ensure that, in the event an Application does not supply the
58 | function or data, the facility still operates, and performs
59 | whatever part of its purpose remains meaningful, or
60 |
61 | b) under the GNU GPL, with none of the additional permissions of
62 | this License applicable to that copy.
63 |
64 | 3. Object Code Incorporating Material from Library Header Files.
65 |
66 | The object code form of an Application may incorporate material from
67 | a header file that is part of the Library. You may convey such object
68 | code under terms of your choice, provided that, if the incorporated
69 | material is not limited to numerical parameters, data structure
70 | layouts and accessors, or small macros, inline functions and templates
71 | (ten or fewer lines in length), you do both of the following:
72 |
73 | a) Give prominent notice with each copy of the object code that the
74 | Library is used in it and that the Library and its use are
75 | covered by this License.
76 |
77 | b) Accompany the object code with a copy of the GNU GPL and this license
78 | document.
79 |
80 | 4. Combined Works.
81 |
82 | You may convey a Combined Work under terms of your choice that,
83 | taken together, effectively do not restrict modification of the
84 | portions of the Library contained in the Combined Work and reverse
85 | engineering for debugging such modifications, if you also do each of
86 | the following:
87 |
88 | a) Give prominent notice with each copy of the Combined Work that
89 | the Library is used in it and that the Library and its use are
90 | covered by this License.
91 |
92 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
93 | document.
94 |
95 | c) For a Combined Work that displays copyright notices during
96 | execution, include the copyright notice for the Library among
97 | these notices, as well as a reference directing the user to the
98 | copies of the GNU GPL and this license document.
99 |
100 | d) Do one of the following:
101 |
102 | 0) Convey the Minimal Corresponding Source under the terms of this
103 | License, and the Corresponding Application Code in a form
104 | suitable for, and under terms that permit, the user to
105 | recombine or relink the Application with a modified version of
106 | the Linked Version to produce a modified Combined Work, in the
107 | manner specified by section 6 of the GNU GPL for conveying
108 | Corresponding Source.
109 |
110 | 1) Use a suitable shared library mechanism for linking with the
111 | Library. A suitable mechanism is one that (a) uses at run time
112 | a copy of the Library already present on the user's computer
113 | system, and (b) will operate properly with a modified version
114 | of the Library that is interface-compatible with the Linked
115 | Version.
116 |
117 | e) Provide Installation Information, but only if you would otherwise
118 | be required to provide such information under section 6 of the
119 | GNU GPL, and only to the extent that such information is
120 | necessary to install and execute a modified version of the
121 | Combined Work produced by recombining or relinking the
122 | Application with a modified version of the Linked Version. (If
123 | you use option 4d0, the Installation Information must accompany
124 | the Minimal Corresponding Source and Corresponding Application
125 | Code. If you use option 4d1, you must provide the Installation
126 | Information in the manner specified by section 6 of the GNU GPL
127 | for conveying Corresponding Source.)
128 |
129 | 5. Combined Libraries.
130 |
131 | You may place library facilities that are a work based on the
132 | Library side by side in a single library together with other library
133 | facilities that are not Applications and are not covered by this
134 | License, and convey such a combined library under terms of your
135 | choice, if you do both of the following:
136 |
137 | a) Accompany the combined library with a copy of the same work based
138 | on the Library, uncombined with any other library facilities,
139 | conveyed under the terms of this License.
140 |
141 | b) Give prominent notice with the combined library that part of it
142 | is a work based on the Library, and explaining where to find the
143 | accompanying uncombined form of the same work.
144 |
145 | 6. Revised Versions of the GNU Lesser General Public License.
146 |
147 | The Free Software Foundation may publish revised and/or new versions
148 | of the GNU Lesser General Public License from time to time. Such new
149 | versions will be similar in spirit to the present version, but may
150 | differ in detail to address new problems or concerns.
151 |
152 | Each version is given a distinguishing version number. If the
153 | Library as you received it specifies that a certain numbered version
154 | of the GNU Lesser General Public License "or any later version"
155 | applies to it, you have the option of following the terms and
156 | conditions either of that published version or of any later version
157 | published by the Free Software Foundation. If the Library as you
158 | received it does not specify a version number of the GNU Lesser
159 | General Public License, you may choose any version of the GNU Lesser
160 | General Public License ever published by the Free Software Foundation.
161 |
162 | If the Library as you received it specifies that a proxy can decide
163 | whether future versions of the GNU Lesser General Public License shall
164 | apply, that proxy's public statement of acceptance of any version is
165 | permanent authorization for you to choose that version for the
166 | Library.
167 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Radio Scripts
2 | =============
3 |
4 | These are some old radio scripts that I used (that still work) to run an
5 | Internet radio station using LiquidSoap, Icecast, and Python. You can use them
6 | to create your own Internet radio station. Multiple DJs are supported, which
7 | each DJ specifying their own individual password. The playlist is controlled
8 | by an external Python script.
9 |
10 | Some forms of these scripts have been running for ~6 years now. <3 LiquidSoap.
--------------------------------------------------------------------------------
/WTFPL.txt:
--------------------------------------------------------------------------------
1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2 | Version 2, December 2004
3 |
4 | Copyright (C) 2004 Sam Hocevar
5 |
6 | Everyone is permitted to copy and distribute verbatim or modified
7 | copies of this license document, and changing it is allowed as long
8 | as the name is changed.
9 |
10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12 |
13 | 0. You just DO WHAT THE FUCK YOU WANT TO.
--------------------------------------------------------------------------------
/automation/getlogin.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright (c) 2005-2011 sk89q
4 | #
5 |
6 | import sys
7 | from optparse import OptionParser
8 | import MySQLdb
9 | import time
10 |
11 | def main():
12 | parser = OptionParser("%prog harbor")
13 | (options, args) = parser.parse_args()
14 |
15 | if len(args) < 1:
16 | parser.error("Not enough arguments")
17 |
18 | harbor, = args
19 |
20 | conn = MySQLdb.connect(host="localhost",
21 | user="root",
22 | passwd="",
23 | db="radio")
24 |
25 | # Look for a record
26 | cursor = conn.cursor()
27 | cursor.execute("""SELECT idname
28 | FROM dj_logins
29 | WHERE harbor = %s
30 | ORDER BY id DESC
31 | LIMIT 1""", (harbor))
32 | row = cursor.fetchone()
33 | cursor.close()
34 |
35 | # No login
36 | if row == None:
37 | print "Unknown"
38 | sys.exit(0)
39 |
40 | print row[0]
41 | sys.exit(0)
42 |
43 | if __name__ == "__main__":
44 | main();
--------------------------------------------------------------------------------
/automation/getnext.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright (c) 2005-2011 sk89q
4 | #
5 |
6 | import os
7 | import os.path
8 | import re
9 | import random
10 | import sys
11 |
12 | src_dir = '/home/radio/music/main/'
13 |
14 | # NOTE! This song selection algorithm MAY VIOLATE COPYRIGHT / LICENSING LAWS
15 | # WITHIN YOUR COUNTRY!
16 |
17 | pool = []
18 | r = re.compile("\\.(?:mp3|ogg)$", re.I);
19 | for root, dirs, files in os.walk(src_dir):
20 | for file in files:
21 | if r.search(file):
22 | pool.append(os.path.join(root, file))
23 | if '.__ignore__' in dirs:
24 | dirs.remove('.__ignore__')
25 | print random.choice(pool)
--------------------------------------------------------------------------------
/automation/getpromo.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright (c) 2005-2011 sk89q
4 | #
5 |
6 | import glob
7 | import random
8 |
9 | files = glob.glob("/home/radio/intros/DU_promo.mp3")
10 | print random.choice(files)
--------------------------------------------------------------------------------
/automation/login.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | #
3 | # Copyright (c) 2005-2011 sk89q
4 | #
5 |
6 | import sys
7 | from optparse import OptionParser
8 | import MySQLdb
9 | import time
10 |
11 | def main():
12 | parser = OptionParser("%prog harbor login")
13 | (options, args) = parser.parse_args()
14 |
15 | if len(args) < 2:
16 | parser.error("Not enough arguments")
17 |
18 | harbor, login = args
19 | login = login.split("|", 1)
20 | if len(login) < 2:
21 | parser.error("Invalid login argument")
22 | username, password = login
23 |
24 | conn = MySQLdb.connect(host="localhost",
25 | user="root",
26 | passwd="",
27 | db="radio")
28 |
29 | # Look for a record
30 | cursor = conn.cursor()
31 | cursor.execute("""QUERY WENT HERE""", (username, password))
32 | row = cursor.fetchone()
33 | cursor.close()
34 |
35 | # No login
36 | if row == None:
37 | print "Failed to authenticate"
38 | sys.exit(1)
39 |
40 | print "Authenticated as %s (%s)" % (row[1], row[0])
41 |
42 | # Log login
43 | cursor = conn.cursor()
44 | cursor.execute("""INSERT INTO dj_logins
45 | (mid, idname, harbor, time)
46 | VALUES
47 | (%s, %s, %s, %s)""",
48 | (row[0], row[2], harbor, time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())))
49 | cursor.close()
50 |
51 | sys.exit(0)
52 |
53 | if __name__ == "__main__":
54 | main();
--------------------------------------------------------------------------------
/icecast/icecast.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 100
4 | 7
5 | 5
6 | 524288
7 | 30
8 | 15
9 | 10
10 | 1
11 | 65535
12 |
13 |
14 |
15 | CHANGEME
16 | CHANGEME
17 | CHANGEME
18 | CHANGEME!
19 |
20 |
21 |
31 |
32 | CHANGEME
33 |
34 |
35 |
36 | 8000
37 |
38 |
39 |
40 | 8001
41 |
42 | 1
43 |
44 |
45 | 1
46 |
47 |
48 | /main.aac
49 |
50 |
51 | /main-low.aac
52 |
53 |
54 | /main.mp3
55 |
56 |
57 |
58 |
59 | /home/radio/icecast
60 |
62 | /home/radio/icecast/logs
63 | /home/radio/icecast/web
64 | /home/radio/icecast/admin
65 |
66 |
67 |
68 |
69 |
70 | access.log
71 | error.log
72 |
73 | 2
74 | 10000
75 | 1
76 |
77 |
78 |
79 |
80 |
81 | radio
82 | radio
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/liquidsoap/radio.liq:
--------------------------------------------------------------------------------
1 | #!/usr/local/bin/liquidsoap
2 | #
3 | # Copyright (c) 2008-2011 sk89q
4 | # Available under GNU Lesser General Public License v3 or WTFPL
5 | #
6 |
7 | base_dir = "/home/radio/liquidsoap/"
8 | automation_dir = "/home/radio/automation/"
9 | source_pass = "CHANGEME"
10 | telnet_port = 10000
11 |
12 | # ----------------------------------------
13 | # Configuration
14 | # ----------------------------------------
15 |
16 | set("decoding.buffer_length", 20.)
17 | set("frame.channels", 2)
18 | set("frame.samplerate", 44100)
19 | set("harbor.icy", false)
20 | set("harbor.bind_addr", "0.0.0.0")
21 | set("harbor.port", 8004)
22 | set("init.daemon.pidfile.path", base_dir^"