Informations :
Dates
- Publish : : Wednesday 16 august 2023
- Modification : Tuesday 23 september 2025
- 1351 views
Share :
NdM 20230816 : Ébauche d'article pour se mettre en appétit..
NdM 20230817 : Ajout de mon script avec prise à distance de la Webradio.
Ma WebRadio : https://flows.zw3b.fr (la page Icecast avec tous les flux disponible).
L'interface site Web : https://radio.zw3b.fr
IceCast2
On va configurer rapidement le serveur IceCast2.
Script avec 100 lignes
001root@media:~ # vim /etc/icecast/icecast.xml002 003<icecast>004<!-- Location and admin are two arbitrary strings that are e.g. visible005on the server info page of the icecast web interface006(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 more018specific on how much to burst. Most people won't need to019change 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.039It affects mainly the urls generated by Icecast for playlists and yp040listings. -→041<hostname>flows.zw3b.fr</hostname>042 043<!-- Set the mountpoint for a shoutcast source to use, the default if not044specified is /stream but you can change it here if an alternative is045wanted or an extension is required046<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>060061<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 both066be 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>070071<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 reached084the logfile will be moved to [error|access|playlist].log.DATESTAMP,085otherwise it will be moved to [error|access|playlist].log.old.086Default is non-archive mode (i.e. overwrite)087-→088<!-- <logarchive>1</logarchive> -→089</logging>090091<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"
Envoie d'un flux vidéo VLC sur Icecast
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. - non disponible actuellement
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.
Script avec 3 lignes
001#!/bin/bash002 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'
Infos sur le Wiki videolan.org : VLC command-line help et sur les docs d'Ubuntu VLC.
Cela permet de créer un flux constant en (vrai) streaming. Ce n'est pas un WebCam avec des images toutes les minutes.
Liquid SOAP (de Savonet)
#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.liq002 003#!/usr/bin/liquidsoap004 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 source050special = request.queue(id="special")051# Smooth_add the special source052s = 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,066host = "mdia.zw3b.fr", port = 8000, password = "mot_de_passe_des_sources",067name = "HouseDancerSession - JusDance", description = "By Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Soundtracks Electro, Deep House, Groove, SoulFull, Funky", url = "http://www.housedancer.net/",068mount="listen.ogg",s)069 070output.icecast(071%mp3(bitrate=128),072host = "mdia.zw3b.fr", port = 8000, password = "mot_de_passe_des_sources",073name = "HouseDancerSession - JusDance", description = "By Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Soundtracks Electro, Deep House, Groove, SoulFull, Funky", url = "http://www.housedancer.net/",074mount="listen",s)075076#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-release002PRETTY_NAME="Debian GNU/Linux 9 (stretch)"003NAME="Debian GNU/Linux"004VERSION_ID="9"005VERSION="9 (stretch)"006VERSION_CODENAME=stretch007ID=debian008HOME_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 --version002Liquidsoap 1.1.1003Copyright (c) 2003-2013 Savonet team004Liquidsoap 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 460 lignes
001#!/usr/bin/liquidsoap002 003##############--------- functions -------------------------------------------------------------004# This function turns a fallible005# source into an infallible source006# by playing a static single when007# the original song is not available008def my_safe(s) =009# We assume that festival is installed and010# functional in liquidsoap011security = 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 original014# source has priority over the security015# single. We set track_sensitive to false016# to return immediately to the original source017# when it becomes available again.018fallback(track_sensitive=false,[s,security])019end020# This function is called when021# a new metadata block is passed in022# the stream.023def apply_metadata(m) =024title = m["title"]025artist = m["artist"]026print("Now playing:#{title} by#{artist}")027end028 029# Our custom request function030def get_request() =031# Get the URI032uri = list.hd(get_process_lines("cat /tmp/request"))033# Create a request034request.create(uri)035end036 037# This function updates the title metadata with038# the content of "/tmp/metadata"039def update_title(m) =040# The title metadata041title = m["title"]042# Our addition043content = list.hd(get_process_lines("cat /home/streaming/metadata.title"))044#content = list.hd(get_process_lines("[ZW3B.FR]"))045# If title is empty046if title == "" then047[("title", content)]048# Otherwise049else050[("title","#{title} on#{content}")]051end052end053 054#------------------------------------------------------------------------------------------055# This function updates the title metadata with056# the content of "/tmp/metadata"057def update_user_0(m) =058# The title metadata059title = m["title"]060# Our addition061content = list.hd(get_process_lines("cat /home/streaming/metadata.title"))062usr = list.hd(get_process_lines("cat /home/streaming/metadata.live.user"))063# usr = m["user"]064 065# If title is empty066if title == "" and usr == "" then067[("title", "#{content}")]068# elif title == "" and usr == "" then069# [("title", "Live DJ#{usr} on#{content}")]070# Otherwise071else072if usr == "" then073[("title","#{title} on#{content}")]074else075[("title","Live DJ#{usr}#{title} on#{content}")]076end077end078end079 080def update_user_1(m) =081# The title metadata082title = m["title"]083# Our addition084content = 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"]087usr = "D Jay 1 !"088# If title is empty089if title == "" and usr == "" then090[("title", "#{content}")]091# elif title == "" and usr == "" then092# [("title", "Live DJ#{usr} on#{content}")]093# Otherwise094else095if usr == "" then096[("title","#{title} on#{content}")]097else098[("title","Live DJ#{usr}#{title} on#{content}")]099end100end101end102 103def update_user_2(m) =104# The title metadata105title = m["title"]106# Our addition107content = 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"]110usr = "D Jay 2 Guest..."111# If title is empty112if title == "" and usr == "" then113[("title", "#{content}")]114# elif title == "" and usr == "" then115# [("title", "Live DJ#{usr} on#{content}")]116# Otherwise117else118if usr == "" then119[("title","#{title} on#{content}")]120else121[("title","Live#{usr}#{title} on#{content}")]122end123end124end125 126def update_user_3(m) =127# The title metadata128title = m["title"]129# Our addition130content = 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"]133usr = "D Jay 3"134# If title is empty135if title == "" and usr == "" then136[("title", "#{content}")]137# elif title == "" and usr == "" then138# [("title", "Live DJ#{usr} on#{content}")]139# Otherwise140else141if usr == "" then142[("title","#{title} on#{content}")]143else144[("title","Live DJ#{usr}#{title} on#{content}")]145end146end147end148 149def update_user_4(m) =150# The title metadata151title = m["title"]152# Our addition153content = 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"]156usr = "D Jay 4"157# If title is empty158if title == "" and usr == "" then159[("title", "#{content}")]160# elif title == "" and usr == "" then161# [("title", "Live DJ#{usr} on#{content}")]162# Otherwise163else164if usr == "" then165[("title","#{title} on#{content}")]166else167[("title","Live DJ#{usr}#{title} on#{content}")]168end169end170end171 172#------------------------------------------------------------------------------------------173 174# This function takes a metadata,175# check if it is of type "file"176# and add the replay_gain metadata in177# this case178def add_replaygain(m) =179# Get the type180type = m["type"]181# The replaygain script is located there182script = "#{configure.libdir}/extract-replaygain"183# The filename is contained in this value184filename = m["filename"]185 186# If type = "song", proceed:187if type == "song" then188info = list.hd(get_process_lines("#{script}#{filename}"))189[("replay_gain",info)]190# Otherwise add nothing191else192[]193end194end195 196# Notre crossfade personnalise197# only crossfade betwee tracks198def my_crossfade(s) =199# Notre fonction de transition200def f(_,_, old_m, new_m, old, new) =201# If none of old and new have "type" metadata202# with value "jingles", we crossfade the source:203if old_m["type"] != "jingle" and new_m["type"] != "jingle" then204add([fade.initial(new), fade.final(old)])205else206sequence([old,new])207end208end209# Now, we apply smart_cross with this function:210smart_cross(f,s)211end212 213# Define a transition that fades out the214# old source, adds a single, and then215# plays the new source216def to_live(jingle, old, new) =217# Fade out old source218old = fade.final(old)219# Supperpose the jingle220s = add([jingle,old])221# Compose this in sequence with222# the new source223sequence([s,new])224end225 226# A transition when switching back to files:227def to_file(old, new) =228# We skip the file229# currently in new230# in order to being with231# a fresh file232source.skip(new)233sequence([old,new])234end235 236# Our custom authentication237# Note: the ICY protocol238# does not have any username and for239# icecast, it is "source" most of the time240# thus, we discard it241 242def harbor_auth(port,_,password) =243# Alice connects on port 9000 between 20h and 21h244# 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")247or248# Bob connection on port 7000 between 18h and 20h249# with password "foo"250#(port == 7000 and 00h-23h and password == "live-admin-m2p")251252(port == 10001 and password == "mot_de_passe_DJ1")253or254(port == 10002 and password == "mot_de_passe_DJ2")255or256(port == 10003 and password == "mot_de_passe_DJ3")257or258(port == 10004 and password == "mot_de_passe_DJ4")259 260end261 262##############--------------------------------------------------------------------------------263# CONFIG264 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 dentree274set("harbor.icy",false)275#set("harbor.bind_addr","127.0.0.1") # ip-du-serveur-de-diff276set("harbor.bind_addr","0.0.0.0")277#set("harbor.port",8005) # port-pas-de-ton-icecast278 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 source332special = request.queue(id="special")333# Smooth_add the special source334radio = smooth_add(normal=radio, special=special)335 336# security337radio = 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 boolean376b = 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 live405 406full = fallback(track_sensitive=false, transitions=[to_live_0, to_file], [live_0, radio])407 408#------------------409# Test de tous les live410 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# flux418 419full = mksafe(full)420 421# And the clock jingle422#radio = add([radio, switch([({0m0s},clock)])])423 424#----------------------------------------------------------------------------------------------425# LiquidFlow : http://flows.liquidsoap.fm/426# Une WolrdMap avec tous les flux LiquidSoap427# Ne fonctionne plus (à commenter)428 429full = register_flow(430radio="ZW3B.Radio : HouseDancerSession & JusDance",431website="https://radio.zw3b.fr/",432description="By LAB3W : Laboratoire Web et reseaux - Sounds : Orel1, Delastef & Fukiflex - John Sill & Blaise",433genre="Electro, Deep House, Groove, SoulFull, Funky, Rap",434# user="zw3b",435# password="mon_super_passwd_du_site",436streams=[("mp3/64k","https://flows.zw3b.fr/radio"),("ogg/112k","https://flows.zw3b.fr/radio.ogg")],437full)438 439#----------------------------------------------------------------------------------------------440# encodage de sortie441 442output.icecast(443%mp3(bitrate=64),444id = "ZW3B-RADIO",445host = "127.0.0.1", port = 8000, password = "mot_de_passe_des_sources",446name = "ZW3B.Radio : HouseDancerSession & JusDance", url = "https://radio.zw3b.fr/",447description = "By LAB3W : Laboratoire Web et reseaux - Sounds : Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Electro, Deep House, Groove, SoulFull, Funky, Rap",448mount = "radio", full)449 450#---------------------------------------------------------------------------------------------451 452output.icecast(453%vorbis(samplerate=44100),454id = "ZW3B-RADIO",455# fallible = true456host = "127.0.0.1", port = 8000, password = "mot_de_passe_des_sources",457name = "ZW3B.Radio : HouseDancerSession & JusDance", url = "https://radio.zw3b.fr/",458description = "By LAB3W : Laboratoire Web et reseaux - Sounds : Orel1, Delastef & Fukiflex - John Sill & Blaise", genre = "Electro, Deep House, Groove, SoulFull, Funky, Rap",459mount = "radio.ogg", full)460
Pour infos :
Script avec 2 lignes
001root@media:~ # cat /home/streaming/metadata.title002The Web Radio - ZW3B.Radio
Il y a 5 utilisateurs DJ qui peuvent interagir 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
Quelques commandes :
Script avec 38 lignes
001# Démarrer le serveur pulseaudio :002pulseaudio --start --verbose003 004# Checking Dbus005service dbus status006 007echo $(dbus-launch)008 009# Dans le .bash_aliases d'un utilisateur010export $(dbus-launch)011 012# Liste des caméras013v4l2-ctl --list-devices014 015# Details d'une caméra016v4l2-ctl -d /dev/video0 -D -l017 018# Commandes et paquets qui peuvent servir019apt install vorbis-tools020apt install libtheora-dev libtheora-ocaml libtheora-bin021apt install v4l2loopback-utils022apt install vlc-plugin-pipewire023apt install dbus-x11024apt install alsa-utils025apt install pulsemixer026 027apt-get --purge --reinstall install pulseaudio028 029apt build-dep vlc030 031# Debug032apt install gdb033gdb moc core034 035# Pour MOC036apt build-dep moc037apt install moc-ffmpeg-plugin pipewire-alsa pipewire-jack moc038
Liens :
- Icecast is free server software for streaming multimedia.
- Liquidsoap - Audio & Video Streaming Language
- Git Hub : Savonet - Liquidsoap - Audio & Video Streaming Language
Doc Ubuntu-fr.org
-
Sur le Blog de Guillaume Seznec : LiquidSoap pour installer une des dernières version Liquidsoap.


