Name : BETA-TESTERS
Project name : ZW3B-API-BETA-TESTERS
Authorized. - 200 - Client API Name and Origin Wildcard OK
Comment faire un flux #streaming accroché à #Icecast par #VLC - Streaming audio vidéo avec #LiquidSOAP Savonet.
NdM 20230816 : Ébauche d'article pour se mettre en appétit..
NdM 20230817 : Ajout de mon script avec prise à distance de la Webradio.
On va configurer rapidement le serveur IceCast2.
Script avec 100 lignes
001root@media:~ # vim /etc/icecast/icecast.xml 002 003<icecast> 004 <!-- Location and admin are two arbitrary strings that are e.g. visible 005 on the server info page of the icecast web interface 006 (server_version.xsl). --> 007 <location>FR</location> 008 <admin>orj(at)lab3w(dot)fr</admin> 009 010 <limits> 011 <clients>100</clients> 012 <sources>10</sources> 013 <queue-size>524288</queue-size> 014 <client-timeout>30</client-timeout> 015 <header-timeout>15</header-timeout> 016 <source-timeout>10</source-timeout> 017 <!-- Same as burst-on-connect, but this allows for being more 018 specific on how much to burst. Most people won't need to 019 change from the default 64k. Applies to all mountpoints. --> 020 <burst-size>65535</burst-size> 021 <!-- 022 <max-bandwidth>100M</max-bandwidth> 023 --> 024 </limits> 025 026 <authentication> 027 <!-- Sources log in with username 'source' --> 028 <source-password>mot_de_passe_des_sources</source-password> 029 <!-- Relays log in username 'relay' --> 030 <relay-password>mot_de_passe_des_relay</relay-password> 031 032 <!-- Admin logs in with the username given below --> 033 <admin-user>admin</admin-user> 034 <admin-password>mot_de_passe_admin</admin-password> 035 </authentication> 036 037 038 <!-- This is the hostname other people will use to connect to your server. 039 It affects mainly the urls generated by Icecast for playlists and yp 040 listings. --> 041 <hostname>flows.zw3b.fr</hostname> 042 043 <!-- Set the mountpoint for a shoutcast source to use, the default if not 044 specified is /stream but you can change it here if an alternative is 045 wanted or an extension is required 046 <shoutcast-mount>/live.nsv</shoutcast-mount> 047 --> 048 049 <!-- port to use when talking to YP etc --> 050 <!--<port>8000</port> --> 051 052 <!-- You may have multiple <listener> elements --> 053 <listen-socket> 054 <port>8000</port> 055 <!-- <bind-address>127.0.0.1</bind-address> --> 056 <!-- use <shoutcast-mount> in here to implicitly define port n+1 --> 057 </listen-socket> 058 059 <fileserve>1</fileserve> 060 061 <paths> 062 <!-- basedir is only used if chroot is enabled --> 063 <basedir>/usr/share/icecast2</basedir> 064 065 <!-- Note that if <chroot> is turned on below, these paths must both 066 be relative to the new root, not the original root --> 067 <logdir>/var/log/icecast2</logdir> 068 <webroot>/usr/share/icecast2/web</webroot> 069 <adminroot>/usr/share/icecast2/admin</adminroot> 070 071 <alias source="/" dest="/index.html"/> 072 073 <x-forwarded-for>127.0.0.1</x-forwarded-for> 074 </paths> 075 076 <logging> 077 <accesslog>access.log</accesslog> 078 <errorlog>error.log</errorlog> 079 <!-- <accesslog_ip>0<accesslog_ip> --> 080 <!-- <playlistlog>playlist.log</playlistlog> --> 081 <loglevel>3</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error --> 082 <logsize>10000</logsize> <!-- Max size of a logfile --> 083 <!-- If logarchive is enabled (1), then when logsize is reached 084 the logfile will be moved to [error|access|playlist].log.DATESTAMP, 085 otherwise it will be moved to [error|access|playlist].log.old. 086 Default is non-archive mode (i.e. overwrite) 087 --> 088 <!-- <logarchive>1</logarchive> --> 089 </logging> 090 091 <security> 092 <chroot>0</chroot> 093 <!-- 094 <changeowner> 095 <user>nobody</user> 096 <group>nogroup</group> 097 </changeowner> 098 --> 099 </security> 100</icecast>
On peut lancer le serveur icecast (depuis l'utilisateur "icecast" :
Script avec 1 ligne
001su - "icecast2" -c "/usr/bin/icecast2 -b -c /etc/icecast2/icecast.xml"
Exemple d'une requête VLC pour créer un /point
de montage Icecast sur un serveur distant :
flows.zw3b.fr:8000/cam0
-> le rendu de la caméra.
La requête ci-dessous récupére le périphérique /dev/video0
de l'ordinateur.
Et envoie le flux vidéo sur une autre machine (au Canada en l'occurrence, sur un container de ma serveur hébergé chez OVH) la machine "10.101.150.80
sur le port "8000
" qui bien sûr passe par un VPN perso IPSec .
Script avec 3 lignes
001#!/bin/bash 002 003su - orj -c 'cvlc v4l2:// :v4l2-dev=/dev/video0 :v4l2-width=320 :v4l2-height=240 --video-title="LAB3W.WebCam" --live-caching=2000 --sout "#transcode{vcodec=theo,vb=150,scale=1,acodec=vorb,ab=64,channels=2,samplerate=22050}:std{access=shout,mux=ogg,dst=source:mot_de_passe_des_sources@10.101.150.80:8000/cam0}" --ttl 12 :no-sout-rtp-sap :no-sout-standard-sap :sout-all :sout-keep'
Cela permet de créer un flux constant en (vrai) streaming. Ce n'est pas un WebCam avec des images toutes les minutes.
#Liquidsoap est un outil puissant pour créer des générateurs de flux audio et vidéo complexes, ciblant généralement les radios Internet #webradio et les #webtv . Il se compose d'un langage de script simple, qui a une notion de première classe de source (essentiellement un flux) et fournit des constructeurs de source élémentaires et des compositions de source à partir desquels vous pouvez créer le générateur de flux que vous souhaitez. Cette conception rend le savon liquide flexible et facilement extensible.
Je vous pose un exemple de scripting liq
liquidsoap 1.1.1
(la version LiquidSoap 2.2.0 est disponible mais ce script ne fonctionne pas avec, il faut l'adapter).
Script avec 87 lignes
001root@media:/home/streaming # vim radio.liq 002 003#!/usr/bin/liquidsoap 004 005set("log.file",false) 006set("log.stdout",true) 007set("log.level",3) 008#set("harbor.icy",true) 009 010%include "library.liq" 011 012set("server.telnet",true) 013 014 015liste_hds = mksafe(playlist("/home/alibaba/music/house.techo.electro/house-dancer-session-mp3/")) 016src_hds = normalize(liste_hds) 017jingle_hds = single("say: House Dancer Session!") 018jingle_hds = amplify(1.0,jingle_hds) 019 020liste_jd = mksafe(playlist("/home/alibaba/music/house.techo.electro/jus-dance/")) 021src_jd = normalize(liste_jd) 022jingle_jd = single("say: Jus Dance!") 023jingle_jd = amplify(1.0,jingle_jd) 024 025 026 027src_hds = rotate(weights=[1,2], [jingle_hds,src_hds]) 028src_jd = rotate(weights=[1,2], [jingle_jd,src_jd]) 029 030src = rotate(weights=[1,1], [src_hds,src_jd]) 031 032s = fallback([request.queue(), src]) 033 034 035 036jingle = single("say: WELCOME !!!!") 037jingle = amplify(1.0,jingle) 038 039 040 041s = rotate(weights=[1,2], [jingle,s]) 042 043s = map_metadata(add_replaygain,s) 044s = amplify(override="replay_gain",1.,s) 045s = my_crossfade(s) 046s = map_metadata(update_title,s) 047s = on_metadata(apply_metadata,s) 048 049# A special source 050special = request.queue(id="special") 051# Smooth_add the special source 052s = smooth_add(normal=s,special=special) 053 054 055s = my_safe(s) 056 057 058jingle1 = single("say:Et now KSS AT HOME") 059to_live1 = to_live(jingle1) 060 061 062s = skip_blank(max_blank=3.,s) 063 064output.icecast( 065 %vorbis, 066 host = "mdia.zw3b.fr", port = 8000, password = "mot_de_passe_des_sources", 067 name = "HouseDancerSession - JusDance", description = "By Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Soundtracks Electro, Deep House, Groove, SoulFull, Funky", url = "http://www.housedancer.net/", 068 mount="listen.ogg",s) 069 070output.icecast( 071 %mp3(bitrate=128), 072 host = "mdia.zw3b.fr", port = 8000, password = "mot_de_passe_des_sources", 073 name = "HouseDancerSession - JusDance", description = "By Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Soundtracks Electro, Deep House, Groove, SoulFull, Funky", url = "http://www.housedancer.net/", 074 mount="listen",s) 075 076#output.icecast( 077# %ogg(%flac), 078# host = "mdia.zw3b.fr", port = 8000, password = "mot_de_passe_des_sources", 079# name = "HouseDancerSession", description = "By Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Soundtracks Electro, Deep House, Groove, SoulFull, Funky", url = "http://www.housedancer.net/", 080# mount="listen-flac.ogg",s) 081 082#output.icecast( 083# %aacplus(bitrate=32), 084# host = "mdia.zw3b.fr", port = 8000, password = "mot_de_passe_des_sources", 085# name = "HouseDancerSession - JusDance", description = "By Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Soundtracks Electro, Deep House, Groove, SoulFull, Funky", url = "http://www.housedancer.net/", 086# mount="listen.aac",s) 087
Il faut faire attention, l'ordre dans le fichiers est "extrêmement" important.
Pour lancer le streaming encoder en 2 formats (%vorbis
et %mp3
et d'autres -- il faut installer les codecs des "dépots multimedia de débian" par exemple pour le codec "flac
" etc.).
Par exemple :
Script avec 1 ligne
001su - "streaming" -c "liquidsoap radio.liq"
J'écris la suite prochainement..
Histoire que vous essayez, ce n'est pas forcement simple.
Je vous laisse lire la documentation Liquidsoap.
Je vous expliquerais et détaillerais les fonctions et ajouterais la mise en place de possible connection de "DJs" sur le flux "constant" de la Web Radio.
J'ai fais des test de streaming vidéo avec inscrutation "image dans image", logo, ticker, text etc.. cela doit mieux fonctionner avec la version 2.2.0 qu'avec la version 1.1.1.
je vous laisse découvrir 🙂
Romain, bonne soirée.
Pour la suite (le jeudi 17 août 2023), je vous ajoute, ci-dessous mon script qui fait tourner les flux sur https://radio.zw3b.fr
L'operationg System :
Script avec 10 lignes
001root@media:~ # cat /etc/os-release 002PRETTY_NAME="Debian GNU/Linux 9 (stretch)" 003NAME="Debian GNU/Linux" 004VERSION_ID="9" 005VERSION="9 (stretch)" 006VERSION_CODENAME=stretch 007ID=debian 008HOME_URL="https://www.debian.org/" 009SUPPORT_URL="https://www.debian.org/support" 010BUG_REPORT_URL="https://bugs.debian.org/"
La version de liquidsoap :
Script avec 5 lignes
001root@media:~ # liquidsoap --version 002Liquidsoap 1.1.1 003Copyright (c) 2003-2013 Savonet team 004Liquidsoap is open-source software, released under GNU General Public License. 005See <http://liquidsoap.fm> for more information.
Et le script radio-live.liq
Script avec 458 lignes
001#!/usr/bin/liquidsoap 002 003##############--------- functions ------------------------------------------------------------- 004# This function turns a fallible 005# source into an infallible source 006# by playing a static single when 007# the original song is not available 008def my_safe(s) = 009 # We assume that festival is installed and 010 # functional in liquidsoap 011 security = single("say:Hello, this is radio FOO! We are currently having some technical difficulties but we'll be back soon so stay tuned!") 012 013 # We return a fallback where the original 014 # source has priority over the security 015 # single. We set track_sensitive to false 016 # to return immediately to the original source 017 # when it becomes available again. 018 fallback(track_sensitive=false,[s,security]) 019end 020# This function is called when 021# a new metadata block is passed in 022# the stream. 023def apply_metadata(m) = 024 title = m["title"] 025 artist = m["artist"] 026 print("Now playing:#{title} by#{artist}") 027end 028 029# Our custom request function 030def get_request() = 031 # Get the URI 032 uri = list.hd(get_process_lines("cat /tmp/request")) 033 # Create a request 034 request.create(uri) 035end 036 037# This function updates the title metadata with 038# the content of "/tmp/metadata" 039def update_title(m) = 040 # The title metadata 041 title = m["title"] 042 # Our addition 043 content = list.hd(get_process_lines("cat /home/streaming/metadata.title")) 044 #content = list.hd(get_process_lines("[ZW3B.FR]")) 045 # If title is empty 046 if title == "" then 047 [("title", content)] 048 # Otherwise 049 else 050 [("title","#{title} on#{content}")] 051 end 052end 053 054#------------------------------------------------------------------------------------------ 055# This function updates the title metadata with 056# the content of "/tmp/metadata" 057def update_user_0(m) = 058 # The title metadata 059 title = m["title"] 060 # Our addition 061 content = list.hd(get_process_lines("cat /home/streaming/metadata.title")) 062 usr = list.hd(get_process_lines("cat /home/streaming/metadata.live.user")) 063# usr = m["user"] 064 065 # If title is empty 066 if title == "" and usr == "" then 067 [("title", "#{content}")] 068# elif title == "" and usr == "" then 069# [("title", "Live DJ#{usr} on#{content}")] 070 # Otherwise 071 else 072 if usr == "" then 073 [("title","#{title} on#{content}")] 074 else 075 [("title","Live DJ#{usr}#{title} on#{content}")] 076 end 077 end 078end 079 080def update_user_1(m) = 081 # The title metadata 082 title = m["title"] 083 # Our addition 084 content = list.hd(get_process_lines("cat /home/streaming/metadata.title")) 085# usr = list.hd(get_process_lines("cat /home/streaming/metadata.live.user")) 086# usr = m["user"] 087 usr = "D Jay 1 !" 088 # If title is empty 089 if title == "" and usr == "" then 090 [("title", "#{content}")] 091# elif title == "" and usr == "" then 092# [("title", "Live DJ#{usr} on#{content}")] 093 # Otherwise 094 else 095 if usr == "" then 096 [("title","#{title} on#{content}")] 097 else 098 [("title","Live DJ#{usr}#{title} on#{content}")] 099 end 100 end 101end 102 103def update_user_2(m) = 104 # The title metadata 105 title = m["title"] 106 # Our addition 107 content = list.hd(get_process_lines("cat /home/streaming/metadata.title")) 108# usr = list.hd(get_process_lines("cat /home/streaming/metadata.live.user")) 109# usr = m["user"] 110 usr = "D Jay 2 Guest..." 111 # If title is empty 112 if title == "" and usr == "" then 113 [("title", "#{content}")] 114# elif title == "" and usr == "" then 115# [("title", "Live DJ#{usr} on#{content}")] 116 # Otherwise 117 else 118 if usr == "" then 119 [("title","#{title} on#{content}")] 120 else 121 [("title","Live#{usr}#{title} on#{content}")] 122 end 123 end 124end 125 126def update_user_3(m) = 127 # The title metadata 128 title = m["title"] 129 # Our addition 130 content = list.hd(get_process_lines("cat /home/streaming/metadata.title")) 131# usr = list.hd(get_process_lines("cat /home/streaming/metadata.live.user")) 132# usr = m["user"] 133 usr = "D Jay 3" 134 # If title is empty 135 if title == "" and usr == "" then 136 [("title", "#{content}")] 137# elif title == "" and usr == "" then 138# [("title", "Live DJ#{usr} on#{content}")] 139 # Otherwise 140 else 141 if usr == "" then 142 [("title","#{title} on#{content}")] 143 else 144 [("title","Live DJ#{usr}#{title} on#{content}")] 145 end 146 end 147end 148 149def update_user_4(m) = 150 # The title metadata 151 title = m["title"] 152 # Our addition 153 content = list.hd(get_process_lines("cat /home/streaming/metadata.title")) 154# usr = list.hd(get_process_lines("cat /home/streaming/metadata.live.user")) 155# usr = m["user"] 156 usr = "D Jay 4" 157 # If title is empty 158 if title == "" and usr == "" then 159 [("title", "#{content}")] 160# elif title == "" and usr == "" then 161# [("title", "Live DJ#{usr} on#{content}")] 162 # Otherwise 163 else 164 if usr == "" then 165 [("title","#{title} on#{content}")] 166 else 167 [("title","Live DJ#{usr}#{title} on#{content}")] 168 end 169 end 170end 171 172#------------------------------------------------------------------------------------------ 173 174# This function takes a metadata, 175# check if it is of type "file" 176# and add the replay_gain metadata in 177# this case 178def add_replaygain(m) = 179 # Get the type 180 type = m["type"] 181 # The replaygain script is located there 182 script = "#{configure.libdir}/extract-replaygain" 183 # The filename is contained in this value 184 filename = m["filename"] 185 186 # If type = "song", proceed: 187 if type == "song" then 188 info = list.hd(get_process_lines("#{script}#{filename}")) 189 [("replay_gain",info)] 190 # Otherwise add nothing 191 else 192 [] 193 end 194end 195 196# Notre crossfade personnalise 197# only crossfade betwee tracks 198def my_crossfade(s) = 199 # Notre fonction de transition 200 def f(_,_, old_m, new_m, old, new) = 201 # If none of old and new have "type" metadata 202 # with value "jingles", we crossfade the source: 203 if old_m["type"] != "jingle" and new_m["type"] != "jingle" then 204 add([fade.initial(new), fade.final(old)]) 205 else 206 sequence([old,new]) 207 end 208 end 209 # Now, we apply smart_cross with this function: 210 smart_cross(f,s) 211end 212 213# Define a transition that fades out the 214# old source, adds a single, and then 215# plays the new source 216def to_live(jingle, old, new) = 217 # Fade out old source 218 old = fade.final(old) 219 # Supperpose the jingle 220 s = add([jingle,old]) 221 # Compose this in sequence with 222 # the new source 223 sequence([s,new]) 224end 225 226# A transition when switching back to files: 227def to_file(old, new) = 228 # We skip the file 229 # currently in new 230 # in order to being with 231 # a fresh file 232 source.skip(new) 233 sequence([old,new]) 234end 235 236# Our custom authentication 237# Note: the ICY protocol 238# does not have any username and for 239# icecast, it is "source" most of the time 240# thus, we discard it 241 242def harbor_auth(port,_,password) = 243 # Alice connects on port 9000 between 20h and 21h 244 # with password "rabbit" 245 #(port == 9000 and 20h-22h and password == "live-guest-mot_de_passe") 246 (port == 10000 and password == "mot_de_passe_DJ0") 247 or 248 # Bob connection on port 7000 between 18h and 20h 249 # with password "foo" 250 #(port == 7000 and 00h-23h and password == "live-admin-m2p") 251 252 (port == 10001 and password == "mot_de_passe_DJ1") 253 or 254 (port == 10002 and password == "mot_de_passe_DJ2") 255 or 256 (port == 10003 and password == "mot_de_passe_DJ3") 257 or 258 (port == 10004 and password == "mot_de_passe_DJ4") 259 260end 261 262##############-------------------------------------------------------------------------------- 263# CONFIG 264 265#set("log.file.path","/home/streaming/logs/liquisoap.log") 266set("log.file",false) 267set("log.stdout",true) 268#set("log.stdout", false) 269set("log.level",4) 270#set("harbor.icy",true) 271set("server.telnet",true) 272 273# Stream dentree 274set("harbor.icy",false) 275#set("harbor.bind_addr","127.0.0.1") # ip-du-serveur-de-diff 276set("harbor.bind_addr","0.0.0.0") 277#set("harbor.port",8005) # port-pas-de-ton-icecast 278 279set("harbor.username","guest") 280set("harbor.password","mot_de_passe_des_sources") 281 282#--------------------------------------------------------------------------------------------- 283 284#radio = fallback(track_sensitive=false, [live,radio]) 285 286#live_0 = input.harbor("live") 287 288#live_0_dj = "Kss*" 289live_0_jingle = single("say: D Jay KSS !") 290to_live_0 = to_live(live_0_jingle) 291 292live_1_jingle = single("say:D Jay 1 !") 293to_live_1 = to_live(live_1_jingle) 294 295live_2_jingle = single("say:D Jay 2 Live !") 296to_live_2 = to_live(live_2_jingle) 297 298live_3_jingle = single("say:D Jay 3 !") 299to_live_3 = to_live(live_3_jingle) 300 301live_4_jingle = single("say:D Jay 4 !") 302to_live_4 = to_live(live_4_jingle) 303 304#--------------------------------------------------------------------------------------------- 305 306s2 = sine() 307 308security = single("say:Hello, this is radio FOO! We are currently having some technical difficulties but we'll be back soon so stay tuned!") 309#jingles = mksafe(playlist("/home/alibaba/music/jingles/")) 310 311playlist_house = mksafe(playlist("/home/alibaba/music/house.techo.electro/house-dancer-session-mp3/")) 312 313jingle_house = amplify(1.0, single("say: The Web Radio!")) 314 315#--------------------------------------------------------------------------------------------- 316 317radio_house = rotate(weights=[1,2], [jingle_house, playlist_house]) 318 319radio = fallback(track_sensitive=true, 320 [radio, security]) 321 322radio = map_metadata(add_replaygain, radio) 323radio = amplify(override="replay_gain",1., radio) 324radio = my_crossfade(radio) 325#radio = smart_cross(id="cross", active=true, conservative=false, duration=5., inhibit=3., minimum=3., width=1., radio) 326radio = map_metadata(update_title, radio) 327radio = on_metadata(apply_metadata, radio) 328 329radio = normalize(radio) 330 331# A special source 332special = request.queue(id="special") 333# Smooth_add the special source 334radio = smooth_add(normal=radio, special=special) 335 336# security 337radio = my_safe(radio) 338 339#radio = skip_blank(threshold=-28.,length=3.,radio) 340#radio = skip_blank(radio, length=10., threshold=-40.) 341radio = skip_blank(id="blanc", threshold=-35., max_blank=5., min_noise=0., track_sensitive=true, radio) 342 343#--------------------------------------------------------------------------------------------- 344timed_promotions = switch ( 345#track_sensitive = true, 346[ 347# ({ 00h59m55s }, amplify(5., override="replay_gain", single("say: une heure!")) ), 348# ({ 01h59m55s }, amplify(5., override="replay_gain", single("say: deux heure!")) ), 349# ({ 02h59m55s }, amplify(5., override="replay_gain", single("say: trois heure!")) ), 350 ({ 03h59m55s }, amplify(5., override="replay_gain", single("say: quatre heure! sur the web radio !")) ), 351# ({ 04h59m55s }, amplify(5., override="replay_gain", single("say: cinq heure!")) ), 352# ({ 05h59m55s }, amplify(5., override="replay_gain", single("say: six heure!")) ), 353# ({ 06h59m55s }, amplify(5., override="replay_gain", single("say: sept heure!")) ), 354 ({ 07h59m55s }, amplify(5., override="replay_gain", single("say: huigt heure! sur the web radio !")) ), 355# ({ 08h59m55s }, amplify(5., override="replay_gain", single("say: neuf heure!")) ), 356# ({ 09h59m55s }, amplify(5., override="replay_gain", single("say: dix heure!")) ), 357# ({ 10h59m55s }, amplify(5., override="replay_gain", single("say: onze heure!")) ), 358 ({ 11h59m55s }, amplify(5., override="replay_gain", single("say: midi! sur the web radio !")) ), 359# ({ 12h59m55s }, amplify(5., override="replay_gain", single("say: treize heure!")) ), 360# ({ 13h59m55s }, amplify(5., override="replay_gain", single("say: quatorze heure!")) ), 361# ({ 14h59m55s }, amplify(5., override="replay_gain", single("say: quinze heure!")) ), 362 ({ 15h59m55s }, amplify(5., override="replay_gain", single("say: catre heure! sur the web radio !")) ), 363# ({ 16h59m55s }, amplify(5., override="replay_gain", single("say: dix sept heure!")) ), 364# ({ 17h59m55s }, amplify(5., override="replay_gain", single("say: dix huigt heure!")) ), 365# ({ 18h59m55s }, amplify(5., override="replay_gain", single("say: dix neuf heure!")) ), 366 ({ 19h59m55s }, amplify(5., override="replay_gain", single("say: vingt heure! sur the web radio !")) ), 367# ({ 20h59m55s }, amplify(5., override="replay_gain", single("say: vingt et une heure!")) ), 368# ({ 21h59m55s }, amplify(5., override="replay_gain", single("say: vingt deux heure!")) ), 369# ({ 22h59m55s }, amplify(5., override="replay_gain", single("say: vingt trois heure!")) ), 370 ({ 23h59m55s }, amplify(5., override="replay_gain", single("say: minuit! sur the web radio !")) ) 371]) 372 373radio = add([radio, timed_promotions]) 374 375# Create an interactive boolean 376b = interactive.bool("button", true) 377 378radio = switch(track_sensitive=false,[(b, radio), ({true}, s2)]) 379 380#--------------------------------------------------------------------------------------------- 381# Authentication for live : 382 383live_auth_0 = harbor_auth(10000) 384live_0 = input.harbor(port=10000,auth=live_auth_0,"live") 385live_0 = map_metadata(update_user_0, live_0) 386 387live_auth_1 = harbor_auth(10001) 388live_1 = input.harbor(port=10001,auth=live_auth_1,"live") 389live_1 = map_metadata(update_user_1, live_1) 390 391live_auth_2 = harbor_auth(10002) 392live_2 = input.harbor(port=10002,auth=live_auth_2,"live") 393live_2 = map_metadata(update_user_2, live_2) 394 395live_auth_3 = harbor_auth(10003) 396live_3 = input.harbor(port=10003,auth=live_auth_3,"live") 397live_3 = map_metadata(update_user_3, live_3) 398 399live_auth_4 = harbor_auth(10004) 400live_4 = input.harbor(port=10004,auth=live_auth_4,"live") 401live_4 = map_metadata(update_user_4, live_4) 402 403#-------------------------------------------- 404# transitions live 405 406full = fallback(track_sensitive=false, transitions=[to_live_0, to_file], [live_0, radio]) 407 408#------------------ 409# Test de tous les live 410 411full = fallback(track_sensitive=false, transitions=[to_live_1, to_file], [live_1, full]) 412full = fallback(track_sensitive=false, transitions=[to_live_2, to_file], [live_2, full]) 413full = fallback(track_sensitive=false, transitions=[to_live_3, to_file], [live_3, full]) 414full = fallback(track_sensitive=false, transitions=[to_live_4, to_file], [live_4, full]) 415 416#--------------------------------------------------------------------------------------------- 417# flux 418 419full = mksafe(full) 420 421# And the clock jingle 422#radio = add([radio, switch([({0m0s},clock)])]) 423 424#---------------------------------------------------------------------------------------------- 425# LiquidFlow : http://flows.liquidsoap.fm/ 426 427full = register_flow( 428 radio="ZW3B.Radio : HouseDancerSession & JusDance", 429 website="http://radio.zw3b.fr/", 430 description="By LAB3W : Laboratoire Web et reseaux - Sounds : Orel1, Delastef & Fukiflex - John Sill & Blaise", 431 genre="Electro, Deep House, Groove, SoulFull, Funky, Rap", 432# user="zw3b", 433# password="mon_super_passwd_du_site", 434 streams=[("mp3/64k","http://flows.zw3b.net/radio"),("ogg/112k","http://flows.zw3b.net/radio.ogg")], 435 full) 436 437#---------------------------------------------------------------------------------------------- 438# encodage de sortie 439 440output.icecast( 441 %mp3(bitrate=64), 442 id = "ZW3B-RADIO", 443 host = "127.0.0.1", port = 8000, password = "mot_de_passe_des_sources", 444 name = "ZW3B.Radio : HouseDancerSession & JusDance", url = "http://radio.zw3b.fr/", 445 description = "By LAB3W : Laboratoire Web et reseaux - Sounds : Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Electro, Deep House, Groove, SoulFull, Funky, Rap", 446 mount = "radio", full) 447 448#--------------------------------------------------------------------------------------------- 449 450output.icecast( 451 %vorbis(samplerate=44100), 452 id = "ZW3B-RADIO", 453# fallible = true 454 host = "127.0.0.1", port = 8000, password = "mot_de_passe_des_sources", 455 name = "ZW3B.Radio : HouseDancerSession & JusDance", url = "http://radio.zw3b.fr/", 456 description = "By LAB3W : Laboratoire Web et reseaux - Sounds : Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Electro, Deep House, Groove, SoulFull, Funky, Rap", 457 mount = "radio.ogg", full) 458
Il y a 5 utilisateurs DJ qui peuvent intéragir sur la webradio à n'importe quel moment - En gros, le bordel. On peut définir des plages horaires.
Pour vous connectez il suffit de lancer une "table de mixage" type le logiciel Mixxx : Diffuser en live de la musique disponible sur Microsoft, Linux et Apple.
Bon mix !
Romain